Signed-off-by: lzeng14 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12584 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			234 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   FFS file access utilities.
 | |
| 
 | |
| Copyright (c) 2006 - 2011, 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 "DxeMain.h"
 | |
| #include "FwVolDriver.h"
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Get the FFS file state by checking the highest bit set in the header's state field.
 | |
| 
 | |
|   @param  ErasePolarity  Erase polarity attribute of the firmware volume
 | |
|   @param  FfsHeader      Points to the FFS file header
 | |
| 
 | |
|   @return FFS File state
 | |
| 
 | |
| **/
 | |
| 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;
 | |
|   }
 | |
| 
 | |
|   return (EFI_FFS_FILE_STATE) HighestBit;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Check if a block of buffer is erased.
 | |
| 
 | |
|   @param  ErasePolarity  Erase polarity attribute of the firmware volume
 | |
|   @param  InBuffer       The buffer to be checked
 | |
|   @param  BufferSize     Size of the buffer in bytes
 | |
| 
 | |
|   @retval TRUE           The block of buffer is erased
 | |
|   @retval FALSE          The block of buffer is not erased
 | |
| 
 | |
| **/
 | |
| 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;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Verify checksum of the firmware volume header.
 | |
| 
 | |
|   @param  FvHeader       Points to the firmware volume header to be checked
 | |
| 
 | |
|   @retval TRUE           Checksum verification passed
 | |
|   @retval FALSE          Checksum verification failed
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| VerifyFvHeaderChecksum (
 | |
|   IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
 | |
|   )
 | |
| {
 | |
|   UINT16  Checksum;
 | |
| 
 | |
|   Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
 | |
| 
 | |
|   if (Checksum == 0) {
 | |
|     return TRUE;
 | |
|   } else {
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Verify checksum of the FFS file header.
 | |
| 
 | |
|   @param  FfsHeader      Points to the FFS file header to be checked
 | |
| 
 | |
|   @retval TRUE           Checksum verification passed
 | |
|   @retval FALSE          Checksum verification failed
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| VerifyHeaderChecksum (
 | |
|   IN EFI_FFS_FILE_HEADER  *FfsHeader
 | |
|   )
 | |
| {
 | |
|   UINT8 HeaderChecksum;
 | |
| 
 | |
|   if (IS_FFS_FILE2 (FfsHeader)) {
 | |
|     HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2));
 | |
|   } else {
 | |
|     HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
 | |
|   }
 | |
|   HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);
 | |
| 
 | |
|   if (HeaderChecksum == 0) {
 | |
|     return TRUE;
 | |
|   } else {
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Check if it's a valid FFS file header.
 | |
| 
 | |
|   @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
 | |
| 
 | |
|   @retval TRUE           Valid FFS file header
 | |
|   @retval FALSE          Invalid FFS file header
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| IsValidFfsHeader (
 | |
|   IN UINT8                ErasePolarity,
 | |
|   IN EFI_FFS_FILE_HEADER  *FfsHeader,
 | |
|   OUT EFI_FFS_FILE_STATE  *FileState
 | |
|   )
 | |
| {
 | |
|   *FileState = GetFileState (ErasePolarity, FfsHeader);
 | |
| 
 | |
|   switch (*FileState) {
 | |
|   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);
 | |
| 
 | |
|   case EFI_FILE_HEADER_CONSTRUCTION:
 | |
|   case EFI_FILE_HEADER_INVALID:
 | |
|   default:
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   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.
 | |
| 
 | |
|   @param  ErasePolarity  Erase polarity attribute of the firmware volume
 | |
|   @param  FfsHeader      Points to the FFS file to be checked
 | |
| 
 | |
|   @retval TRUE           Valid FFS file
 | |
|   @retval FALSE          Invalid FFS file
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| IsValidFfsFile (
 | |
|   IN UINT8                ErasePolarity,
 | |
|   IN EFI_FFS_FILE_HEADER  *FfsHeader
 | |
|   )
 | |
| {
 | |
|   EFI_FFS_FILE_STATE  FileState;
 | |
|   UINT8               DataCheckSum;
 | |
| 
 | |
|   FileState = GetFileState (ErasePolarity, FfsHeader);
 | |
|   switch (FileState) {
 | |
| 
 | |
|   case EFI_FILE_DELETED:
 | |
|   case EFI_FILE_DATA_VALID:
 | |
|   case EFI_FILE_MARKED_FOR_UPDATE:
 | |
|     DataCheckSum = FFS_FIXED_CHECKSUM;
 | |
|     if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
 | |
|       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));
 | |
|       }
 | |
|     }
 | |
|     if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) {
 | |
|       return TRUE;
 | |
|     }
 | |
| 
 | |
|   default:
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 |