/** @file\r
+These functions assist in parsing and manipulating a Firmware Volume.\r
\r
-Copyright (c) 2004 - 2008, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- FvLib.c\r
-\r
-Abstract:\r
-\r
- These functions assist in parsing and manipulating a Firmware Volume.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
Fv Buffer containing the FV.\r
FvLength Length of the FV\r
- \r
+\r
Returns:\r
- \r
+\r
EFI_SUCCESS Function Completed successfully.\r
EFI_INVALID_PARAMETER A required parameter was NULL.\r
\r
\r
FvHeader Pointer to the FV buffer.\r
FvLength Length of the FV\r
- \r
+\r
Returns:\r
- \r
+\r
EFI_SUCCESS Function Completed successfully.\r
EFI_INVALID_PARAMETER A required parameter was NULL.\r
EFI_ABORTED The library needs to be initialized.\r
}\r
\r
*FvHeader = mFvHeader;\r
+ *FvLength = mFvLength;\r
return EFI_SUCCESS;\r
}\r
\r
Routine Description:\r
\r
This function returns the next file. If the current file is NULL, it returns\r
- the first file in the FV. If the function returns EFI_SUCCESS and the file \r
+ the first file in the FV. If the function returns EFI_SUCCESS and the file\r
pointer is NULL, then there are no more files in the FV.\r
\r
Arguments:\r
\r
CurrentFile Pointer to the current file, must be within the current FV.\r
NextFile Pointer to the next file in the FV.\r
- \r
+\r
Returns:\r
- \r
+\r
EFI_SUCCESS Function completed successfully.\r
EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.\r
EFI_ABORTED The library needs to be initialized.\r
//\r
// Verify file is in this FV.\r
//\r
- if ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength) {\r
+ if ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength) {\r
*NextFile = NULL;\r
return EFI_SUCCESS;\r
}\r
// Verify current file is in range\r
//\r
if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||\r
- ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength)\r
+ ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength)\r
) {\r
return EFI_INVALID_PARAMETER;\r
}\r
//\r
// Get next file, compensate for 8 byte alignment if necessary.\r
//\r
- *NextFile = (EFI_FFS_FILE_HEADER *) (((UINTN) CurrentFile + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3));\r
+ *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetFfsFileLength(CurrentFile) + 0x07) & (~(UINTN) 7)) + (UINT8 *) mFvHeader);\r
\r
//\r
// Verify file is in this FV.\r
//\r
- if (((UINTN) *NextFile + sizeof (EFI_FFS_FILE_HEADER) >= (UINTN) mFvHeader + mFvLength) ||\r
- ((UINTN) *NextFile + GetLength ((*NextFile)->Size) > (UINTN) mFvHeader + mFvLength)\r
+ if (((UINTN) *NextFile + GetFfsHeaderLength(*NextFile) >= (UINTN) mFvHeader + mFvLength) ||\r
+ ((UINTN) *NextFile + GetFfsFileLength (*NextFile) > (UINTN) mFvHeader + mFvLength)\r
) {\r
*NextFile = NULL;\r
return EFI_SUCCESS;\r
Arguments:\r
\r
FileType Type of file to search for.\r
- Instance Instace of the file type to return.\r
+ Instance Instance of the file type to return.\r
File Return pointer. In the case of an error, contents are undefined.\r
\r
Returns:\r
EFI_FILE_SECTION_POINTER InnerSection;\r
EFI_STATUS Status;\r
UINTN SectionSize;\r
+ UINT16 GuidSecAttr;\r
+ UINT16 GuidDataOffset;\r
\r
+ GuidSecAttr = 0;\r
+ GuidDataOffset = 0;\r
CurrentSection = FirstSection;\r
\r
while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {\r
// special processing, go ahead to search the requesting\r
// section inside the GUID-defined section.\r
//\r
+ if (CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED) {\r
+ if (GetLength(CurrentSection.CommonHeader->Size) == 0xffffff) {\r
+ GuidSecAttr = CurrentSection.GuidDefinedSection2->Attributes;\r
+ GuidDataOffset = CurrentSection.GuidDefinedSection2->DataOffset;\r
+ } else {\r
+ GuidSecAttr = CurrentSection.GuidDefinedSection->Attributes;\r
+ GuidDataOffset = CurrentSection.GuidDefinedSection->DataOffset;\r
+ }\r
+ }\r
if (SectionType != EFI_SECTION_GUID_DEFINED &&\r
CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&\r
- !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {\r
+ !(GuidSecAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {\r
InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)\r
- ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset);\r
- SectionSize = CurrentSection.CommonHeader->Size[0] +\r
- (CurrentSection.CommonHeader->Size[1] << 8) + \r
- (CurrentSection.CommonHeader->Size[2] << 16);\r
+ ((UINTN) CurrentSection.CommonHeader + GuidDataOffset);\r
+ SectionSize = GetSectionFileLength(CurrentSection.CommonHeader);\r
Status = SearchSectionByType (\r
InnerSection,\r
(UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),\r
//\r
// Find next section (including compensating for alignment issues.\r
//\r
- CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetSectionFileLength(CurrentSection.CommonHeader) + 0x03) & (~(UINTN) 3));\r
}\r
\r
return EFI_NOT_FOUND;\r
\r
Routine Description:\r
\r
- Find a section in a file by type and instance. An instance of 1 is the first \r
+ Find a section in a file by type and instance. An instance of 1 is the first\r
instance. The function will return NULL if a matching section cannot be found.\r
GUID-defined sections, if special processing is not needed, are handled in a\r
depth-first manner.\r
\r
File The file to search.\r
SectionType Type of file to search for.\r
- Instance Instace of the section to return.\r
+ Instance Instance of the section to return.\r
Section Return pointer. In the case of an error, contents are undefined.\r
\r
Returns:\r
//\r
// Get the first section\r
//\r
- CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));\r
- \r
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + GetFfsHeaderLength(File));\r
+\r
//\r
// Depth-first manner to find section file.\r
//\r
Status = SearchSectionByType (\r
CurrentSection,\r
- (UINT8 *) ((UINTN) File + GetLength (File->Size)),\r
+ (UINT8 *) ((UINTN) File + GetFfsFileLength (File)),\r
SectionType,\r
&SectionCount,\r
Instance,\r
{\r
BOOLEAN ErasePolarity;\r
EFI_STATUS Status;\r
- EFI_FFS_FILE_HEADER BlankHeader;\r
+ EFI_FFS_FILE_HEADER2 BlankHeader;\r
UINT8 Checksum;\r
UINT32 FileLength;\r
UINT8 SavedChecksum;\r
UINT8 SavedState;\r
UINT8 FileGuidString[80];\r
+ UINT32 FfsHeaderSize;\r
+\r
//\r
// Verify library has been initialized.\r
//\r
if (EFI_ERROR (Status)) {\r
return EFI_ABORTED;\r
}\r
+\r
+ FfsHeaderSize = GetFfsHeaderLength(FfsHeader);\r
//\r
// Check if we have free space\r
//\r
if (ErasePolarity) {\r
- memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER));\r
+ memset (&BlankHeader, -1, FfsHeaderSize);\r
} else {\r
- memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
+ memset (&BlankHeader, 0, FfsHeaderSize);\r
}\r
\r
- if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) {\r
+ if (memcmp (&BlankHeader, FfsHeader, FfsHeaderSize) == 0) {\r
return EFI_NOT_FOUND;\r
}\r
//\r
FfsHeader->State = 0;\r
SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;\r
FfsHeader->IntegrityCheck.Checksum.File = 0;\r
- Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));\r
+ Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FfsHeaderSize);\r
FfsHeader->State = SavedState;\r
FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;\r
if (Checksum != 0) {\r
//\r
// Verify file data checksum\r
//\r
- FileLength = GetLength (FfsHeader->Size);\r
- Checksum = CalculateSum8 ((UINT8 *) (FfsHeader + 1), FileLength - sizeof (EFI_FFS_FILE_HEADER));\r
+ FileLength = GetFfsFileLength (FfsHeader);\r
+ Checksum = CalculateSum8 ((UINT8 *) ((UINT8 *)FfsHeader + FfsHeaderSize), FileLength - FfsHeaderSize);\r
Checksum = Checksum + FfsHeader->IntegrityCheck.Checksum.File;\r
if (Checksum != 0) {\r
Error (NULL, 0, 0006, "invalid FFS file checksum", "Ffs file with Guid %s", FileGuidString);\r
return EFI_SUCCESS;\r
}\r
\r
+UINT32\r
+GetFfsHeaderLength(\r
+ IN EFI_FFS_FILE_HEADER *FfsHeader\r
+ )\r
+{\r
+ if (FfsHeader == NULL) {\r
+ return 0;\r
+ }\r
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {\r
+ return sizeof(EFI_FFS_FILE_HEADER2);\r
+ }\r
+ return sizeof(EFI_FFS_FILE_HEADER);\r
+}\r
+\r
+UINT32\r
+GetSectionHeaderLength(\r
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader\r
+ )\r
+{\r
+ if (SectionHeader == NULL) {\r
+ return 0;\r
+ }\r
+ if (GetLength(SectionHeader->Size) == 0xffffff) {\r
+ return sizeof(EFI_COMMON_SECTION_HEADER2);\r
+ }\r
+ return sizeof(EFI_COMMON_SECTION_HEADER);\r
+}\r
+\r
+UINT32\r
+GetFfsFileLength (\r
+ EFI_FFS_FILE_HEADER *FfsHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get FFS file length including FFS header.\r
+\r
+Arguments:\r
+\r
+ FfsHeader Pointer to EFI_FFS_FILE_HEADER.\r
+\r
+Returns:\r
+\r
+ UINT32 Length of FFS file header.\r
+\r
+--*/\r
+{\r
+ if (FfsHeader == NULL) {\r
+ return 0;\r
+ }\r
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {\r
+ return (UINT32) ((EFI_FFS_FILE_HEADER2 *)FfsHeader)->ExtendedSize;\r
+ } else {\r
+ return GetLength(FfsHeader->Size);\r
+ }\r
+}\r
+\r
+UINT32\r
+GetSectionFileLength (\r
+ EFI_COMMON_SECTION_HEADER *SectionHeader\r
+ )\r
+{\r
+ UINT32 Length;\r
+ if (SectionHeader == NULL) {\r
+ return 0;\r
+ }\r
+ Length = GetLength(SectionHeader->Size);\r
+ if (Length == 0xffffff) {\r
+ Length = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;\r
+ }\r
+ return Length;\r
+}\r
+\r
UINT32\r
GetLength (\r
UINT8 *ThreeByteLength\r
EFI_SUCCESS The function completed successfully.\r
EFI_INVALID_PARAMETER One of the input parameters was invalid.\r
EFI_ABORTED Operation aborted.\r
- \r
+\r
--*/\r
{\r
EFI_STATUS Status;\r
It in no way validate the FFS file.\r
\r
Arguments:\r
- \r
+\r
ErasePolarity The erase polarity for the file state bits.\r
FfsHeader Pointer to a FFS file.\r
\r