summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/C/FCE/BinaryParse.c
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/C/FCE/BinaryParse.c')
-rw-r--r--BaseTools/Source/C/FCE/BinaryParse.c1326
1 files changed, 0 insertions, 1326 deletions
diff --git a/BaseTools/Source/C/FCE/BinaryParse.c b/BaseTools/Source/C/FCE/BinaryParse.c
deleted file mode 100644
index e9f8ee6826..0000000000
--- a/BaseTools/Source/C/FCE/BinaryParse.c
+++ /dev/null
@@ -1,1326 +0,0 @@
-/** @file
-
- The API to parse the binary.
-
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __GNUC__
-#include "windows.h"
-#else
-#include <sys/types.h>
-#include <dirent.h>
-#include <unistd.h>
-#endif
-#include "BinaryParse.h"
-#include "BinaryCreate.h"
-#include "VariableCommon.h"
-#include "FirmwareVolumeBufferLib.h"
-
-extern G_EFI_FD_INFO gEfiFdInfo;
-extern EFI_HANDLE mParsedGuidedSectionTools;
-extern CHAR8 mInputFdName[MAX_FILENAME_LEN];
-
-//
-// The Guid to sign the position of Vfr and Uni array in FV
-//
-EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID;
-EFI_GUID gUniStrArrayAttractGuid = EFI_UNI_STR_ATTRACT_GUID;
-EFI_GUID gEfiSystemNvDataFvGuid = EFI_SYSTEM_NVDATA_FV_GUID;
-EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
-
-/**
- Converts a three byte length value into a UINT32.
-
- @param ThreeByteLength Pointer to the first of the 3 byte length.
-
- @retval Length Size of the section
-
-**/
-static
-UINT32
-Get3ByteLength (
- IN UINT8 *ThreeByteLength
- )
-{
- UINT32 Length;
-
- Length = 0;
-
- if (ThreeByteLength == NULL) {
- return 0;
- }
-
- Length = *((UINT32 *) ThreeByteLength);
- Length = Length & 0x00FFFFFF;
-
- return Length;
-}
-
-/**
- Generate the unique template filename.
-**/
-CHAR8 *
-GenTempFile (
- VOID
- )
-{
- CHAR8 *TemString;
- TemString = NULL;
-#ifndef __GNUC__
- TemString = CloneString (tmpnam (NULL));
-#else
- CHAR8 tmp[] = "/tmp/fileXXXXXX";
- UINTN Fdtmp;
- Fdtmp = mkstemp(tmp);
- TemString = CloneString(tmp);
- close(Fdtmp);
-#endif
- return TemString;
-}
-
-/**
- Check whether exist the same Ifr FFS. If not existed, return TRUE.
-
- @param[in] FfsImage The pointer to the binary.
- @param[in] FileSize The size of binary.
-
- @return The string after convert.
-**/
-static
-BOOLEAN
-NotExistSameFfsIfr (
- IN VOID *FfsImage
-)
-{
- UINT32 Index;
-
- Index = 0;
-
- while (gEfiFdInfo.FfsArray[Index] != NULL) {
- if (memcmp (gEfiFdInfo.FfsArray[Index], FfsImage, sizeof (EFI_GUID)) == 0) {
- return FALSE;
- }
- Index++;
- }
- return TRUE;
-}
-
-/**
- This function returns the next larger size that meets the alignment
- requirement specified.
-
- @param ActualSize The size.
- @param Alignment The desired alignment.
-
- @retval The Occupied length
-
-**/
-static
-UINT32
-GetOccupiedSize (
- IN UINT32 ActualSize,
- IN UINT32 Alignment
- )
-{
- UINT32 OccupiedSize;
-
- OccupiedSize = ActualSize;
- while ((OccupiedSize & (Alignment - 1)) != 0) {
- OccupiedSize++;
- }
-
- return OccupiedSize;
-}
-
-
-/**
- Parses FFS Sections, and remove the FFS headers. Tis function olny handle one efi in this FFS.
-
- @param SectionBuffer The section base address
- @param BufferLength The length of FFS.
- @param EfiBufferHeader The structure dual pointer to the efi informations
-
- @retval EFI_SUCCESS The application exited normally.
- @retval EFI_ABORTED An error occurred.
-
-**/
-EFI_STATUS
-ParseSection (
- IN BOOLEAN IsFfsOrEfi,
- IN OUT UINT8 *SectionBuffer,
- IN UINT32 BufferLength,
- IN OUT EFI_SECTION_STRUCT **EfiBufferHeader
- )
-{
- UINT32 ParsedLength;
- EFI_SECTION_TYPE Type;
- UINT8 *Ptr;
- UINT32 SectionLength;
- UINT8 *CompressedBuffer;
- UINT32 CompressedLength;
- UINT8 *UncompressedBuffer;
- UINT32 UncompressedLength;
- UINT8 CompressionType;
- DECOMPRESS_FUNCTION DecompressFunction;
- GETINFO_FUNCTION GetInfoFunction;
- UINT32 ScratchSize;
- UINT8 *ScratchBuffer;
- EFI_STATUS Status;
- UINT32 DstSize;
- CHAR8 *ExtractionTool;
- CHAR8 *ToolInputFile;
- CHAR8 *ToolOutputFile;
- CHAR8 *SystemCommandFormatString;
- CHAR8 *SystemCommand;
- UINT8 *ToolOutputBuffer;
- UINT32 ToolOutputLength;
- BOOLEAN HasDepexSection;
-
- Ptr = NULL;
- SectionLength = 0;
- CompressedBuffer = NULL;
- CompressedLength = 0;
- UncompressedBuffer = NULL;
- UncompressedLength = 0;
- CompressionType = 0;
- ScratchSize = 0;
- ScratchBuffer = NULL;
- Status = EFI_SUCCESS;
- DstSize = 0;
- ExtractionTool = NULL;
- ToolInputFile = NULL;
- ToolOutputFile = NULL;
- SystemCommandFormatString = NULL;
- SystemCommand = NULL;
-
- //
- // Jump the FFS header
- //
- if (IsFfsOrEfi) {
- SectionBuffer = SectionBuffer + sizeof (EFI_FFS_FILE_HEADER);
- BufferLength = BufferLength - sizeof (EFI_FFS_FILE_HEADER);
- }
- ParsedLength = 0;
- HasDepexSection = FALSE;
- ExtractionTool = NULL;
- ToolOutputLength = 0;
- ToolOutputBuffer = NULL;
-
- (*EfiBufferHeader)->Length = BufferLength;
-
- while (ParsedLength < BufferLength) {
- Ptr = SectionBuffer + ParsedLength;
-
- SectionLength = Get3ByteLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);
- Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;
-
- //
- // This is sort of an odd check, but is necessary because FFS files are
- // padded to a QWORD boundary, meaning there is potentially a whole section
- // header worth of 0xFF bytes.
- //
- if ((SectionLength == 0xffffff) && (Type == 0xff)) {
- ParsedLength += 4;
- continue;
- }
-
- switch (Type) {
-
- case EFI_SECTION_PE32:
- case EFI_SECTION_TE:
- //
- //Got the correct address
- //
- (*EfiBufferHeader)->BufferBase = (UINTN)(Ptr + sizeof (EFI_COMMON_SECTION_HEADER));
- return EFI_SUCCESS;
-
- case EFI_SECTION_RAW:
- case EFI_SECTION_PIC:
- break;
-
- case EFI_SECTION_USER_INTERFACE:
- HasDepexSection = FALSE;
- break;
-
- case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
- case EFI_SECTION_COMPATIBILITY16:
- case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
- break;
-
- case EFI_SECTION_PEI_DEPEX:
- case EFI_SECTION_DXE_DEPEX:
- case EFI_SECTION_SMM_DEPEX:
- HasDepexSection = TRUE;
- break;
-
- case EFI_SECTION_VERSION:
- break;
- case EFI_SECTION_COMPRESSION:
- UncompressedBuffer = NULL;
- CompressedLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION);
- UncompressedLength = ((EFI_COMPRESSION_SECTION *) Ptr)->UncompressedLength;
- CompressionType = ((EFI_COMPRESSION_SECTION *) Ptr)->CompressionType;
-
- if (CompressionType == EFI_NOT_COMPRESSED) {
- if (CompressedLength != UncompressedLength) {
- Error (
- NULL,
- 0,
- 0,
- "file is not compressed, but the compressed length does not match the uncompressed length",
- NULL
- );
- return EFI_ABORTED;
- }
-
- UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION);
- } else if (CompressionType == EFI_STANDARD_COMPRESSION) {
- GetInfoFunction = EfiGetInfo;
- DecompressFunction = EfiDecompress;
- CompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION);
-
- Status = GetInfoFunction (
- CompressedBuffer,
- CompressedLength,
- &DstSize,
- &ScratchSize
- );
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);
- return EFI_ABORTED;
- }
-
- if (DstSize != UncompressedLength) {
- Error (NULL, 0, 0003, "compression error in the compression section", NULL);
- return EFI_ABORTED;
- }
-
- ScratchBuffer = malloc (ScratchSize);
- if (ScratchBuffer == NULL) {
- return EFI_ABORTED;
- }
- UncompressedBuffer = malloc (UncompressedLength);
- if (UncompressedBuffer == NULL) {
- free (ScratchBuffer);
- return EFI_ABORTED;
- }
- memset (UncompressedBuffer, 0, UncompressedLength);
-
- Status = DecompressFunction (
- CompressedBuffer,
- CompressedLength,
- UncompressedBuffer,
- UncompressedLength,
- ScratchBuffer,
- ScratchSize
- );
- free (ScratchBuffer);
- if (Status != EFI_SUCCESS) {
- Error (NULL, 0, 0003, "decompress failed", NULL);
- free (UncompressedBuffer);
- return EFI_ABORTED;
- }
- } else {
- Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);
- return EFI_ABORTED;
- }
-
- Status = ParseSection (FALSE, UncompressedBuffer, UncompressedLength, EfiBufferHeader);
- if (Status != EFI_SUCCESS) {
- Error (NULL, 0, 0003, "failed to parse section", NULL);
- free (UncompressedBuffer);
- UncompressedBuffer = NULL;
- } else {
- return EFI_SUCCESS;
- }
- //
- // Store the allocate memory address for UncompressedBuffer
- //
- if (UncompressedBuffer != NULL) {
- (*EfiBufferHeader)->UncompressedBuffer[(*EfiBufferHeader)->UnCompressIndex] = (UINTN) UncompressedBuffer;
- (*EfiBufferHeader)->UnCompressIndex = (*EfiBufferHeader)->UnCompressIndex + 1;
- }
- break;
-
- case EFI_SECTION_GUID_DEFINED:
- //
- // Decompress failed, and then check for CRC32 sections which we can handle internally if needed.
- // Maybe this section is no-compressed.
- //
- if (!CompareGuid (
- &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid,
- &gEfiCrc32GuidedSectionExtractionProtocolGuid
- )) {
- //
- // CRC32 guided section
- //
- Status = ParseSection (
- FALSE,
- SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,
- BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,
- EfiBufferHeader
- );
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);
- return EFI_ABORTED;
- } else {
- return EFI_SUCCESS;
- }
- } else {
- ExtractionTool = LookupGuidedSectionToolPath (
- mParsedGuidedSectionTools,
- &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid
- );
-
- if (ExtractionTool != NULL) {
- ToolInputFile = GenTempFile ();
- ToolOutputFile = GenTempFile ();
- //
- // Construction 'system' command string
- //
- SystemCommandFormatString = "%s -d -o \"%s\" \"%s\"";
- SystemCommand = malloc (
- strlen (SystemCommandFormatString) \
- + strlen (ExtractionTool) \
- + strlen (ToolInputFile) \
- + strlen (ToolOutputFile) \
- + 1
- );
- if (SystemCommand == NULL) {
- free (ExtractionTool);
- free (ToolInputFile);
- free (ToolOutputFile);
- return EFI_ABORTED;
- }
- sprintf (
- SystemCommand,
- "%s -d -o \"%s\" \"%s\"",
- ExtractionTool,
- ToolOutputFile,
- ToolInputFile
- );
- free (ExtractionTool);
-
- Status = PutFileImage (
- ToolInputFile,
- (CHAR8*) Ptr + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,
- SectionLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset
- );
-
- if (HasDepexSection) {
- HasDepexSection = FALSE;
- }
-
- system (SystemCommand);
- remove (ToolInputFile);
- free (ToolInputFile);
- ToolInputFile = NULL;
- free (SystemCommand);
- SystemCommand = NULL;
-
- if (EFI_ERROR (Status)) {
- Error ("FCE", 0, 0004, "unable to decoded GUIDED section", NULL);
- free (ToolOutputFile);
- return EFI_ABORTED;
- }
-
- Status = GetFileImage (
- ToolOutputFile,
- (CHAR8 **)&ToolOutputBuffer,
- &ToolOutputLength
- );
- remove (ToolOutputFile);
- free (ToolOutputFile);
- ToolOutputFile = NULL;
- if (EFI_ERROR (Status)) {
- return EFI_ABORTED;
- }
- }
- Status = ParseSection (
- FALSE,
- ToolOutputBuffer,
- ToolOutputLength,
- EfiBufferHeader
- );
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
- return EFI_ABORTED;
- }
- }
- break;
-
- default:
- ;
- }
- ParsedLength += SectionLength;
- //
- // We make then next section begin on a 4-byte boundary
- //
- ParsedLength = GetOccupiedSize (ParsedLength, 4);
- }
-
- return EFI_ABORTED;
-}
-
-static
-BOOLEAN
-GetNextOffset (
- IN UINT8 *Data,
- IN EFI_GUID *Guid,
- IN UINTN Len,
- IN OUT UINTN *Offset
- )
-{
- UINTN NextOffset;
- if (*Offset >= Len || Len - *Offset <= sizeof (EFI_GUID)) {
- return FALSE;
- }
-
- for (NextOffset = *Offset; NextOffset < Len - sizeof (EFI_GUID); NextOffset++) {
- if (CompareGuid(Guid, (EFI_GUID*)(Data + NextOffset)) == 0) {
- *Offset = NextOffset + sizeof(EFI_GUID);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/**
- Get the address by Guid.
-
- Parse the FFS image, and find the GUID address.There may be some Guids matching the
- searched Guid.
-
- @param Fv the Pointer to the image.
- @param Guid The Guid need to find.
- @param Offset The dual Pointer to the offset.
- @param NumOfMatchGuid The number of matching Guid offset.
-
- @retval EFI_SUCCESS The Search was complete successfully
- @return EFI_ABORTED An error occurred
-**/
-EFI_STATUS
-GetAddressByGuid (
- IN VOID *Fv,
- IN EFI_GUID *Guid,
- IN UINTN Len,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMatchGuid
- )
-{
- VOID *LocalFv;
- UINT8 Flag;
-
- EFI_RAW_SECTION* Section;
- UINT8 *RawData;
- VOID* SectionStart;
- UINTN NextOffset;
- UINTN Key;
- UINTN TotalSectionsSize;
- UINTN SecLen;
- UINTN SecHdr;
- EFI_STATUS Status;
-
- if( (Fv == NULL) || (Fv == NULL) || (Guid == NULL) || Len == 0 ){
- return EFI_ABORTED;
- }
-
- LocalFv = Fv;
- Flag = 0;
- Section = NULL;
- Key = 0;
-
- if (NumOfMatchGuid != NULL) {
- *NumOfMatchGuid = 0;
- }
-
- SectionStart = (VOID*)((UINTN)LocalFv + FvBufGetFfsHeaderSize(LocalFv));
- TotalSectionsSize = Len - FvBufGetFfsHeaderSize(LocalFv);
- while (TRUE) {
- Status = FvBufFindNextSection (
- SectionStart,
- TotalSectionsSize,
- &Key,
- (VOID **)&Section
- );
- if (Section == NULL || EFI_ERROR (Status)) {
- break;
- }
-
- if (EFI_SECTION_RAW == Section->Type) {
- if ((*(UINT32 *)Section->Size & 0xffffff) == 0xffffff) {
- SecLen = ((EFI_RAW_SECTION2 *)Section)->ExtendedSize;
- SecHdr = sizeof(EFI_RAW_SECTION2);
- } else {
- SecLen = *(UINT32 *)Section->Size & 0xffffff;
- SecHdr = sizeof(EFI_RAW_SECTION);
- }
- if (SecLen <= SecHdr || SecLen - SecHdr < sizeof(EFI_GUID)) {
- continue;
- }
- RawData = (UINT8 *)Section + SecHdr;
- NextOffset = 0;
- while (GetNextOffset(RawData, Guid, SecLen - SecHdr, &NextOffset)) {
- Flag = 1;
- if ((NumOfMatchGuid != NULL) && (Offset != NULL)) {
- if (*NumOfMatchGuid == 0) {
- *Offset = malloc (sizeof (UINTN) * MAX_MATCH_GUID_NUM);
- if (*Offset == NULL) {
- return EFI_ABORTED;
- }
- memset (*Offset, 0, sizeof (UINTN) * MAX_MATCH_GUID_NUM);
- }
- *(*Offset + *NumOfMatchGuid) = NextOffset + (RawData - (UINT8 *)Fv);
- (*NumOfMatchGuid)++;
- } else {
- return EFI_SUCCESS;
- }
- }
- }
- }
-
- if( Flag == 0 ) {
- return EFI_ABORTED;
- }
- return EFI_SUCCESS;
-}
-
-/**
- Search the VfrBin Base address.
-
- According the known GUID gVfrArrayAttractGuid to get the base address from FFS.
-
- @param Fv the Pointer to the FFS
- @param EfiAddr the Pointer to the EFI in FFS
- @param Length the length of Fv
- @param Offset the Pointer to the Addr (Offset)
- @param NumOfMachingOffset the number of Addr (Offset)
-
- @retval EFI_SUCCESS Get the address successfully.
-**/
-EFI_STATUS
-SearchVfrBinInFFS (
- IN VOID *Fv,
- IN VOID *EfiAddr,
- IN UINTN Length,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMachingOffset
- )
-{
- UINTN Index;
- EFI_STATUS Status;
- UINTN VirOffValue;
-
- Index = 0;
- Status = EFI_SUCCESS;
- VirOffValue = 0;
-
- if ((Fv == NULL) || (Offset == NULL)) {
- return EFI_ABORTED;
- }
- Status = GetAddressByGuid (
- Fv,
- &gVfrArrayAttractGuid,
- Length,
- Offset,
- NumOfMachingOffset
- );
- if (Status != EFI_SUCCESS) {
- return EFI_ABORTED;
- }
-
- while (Index < *NumOfMachingOffset) {
- //
- // Got the virOffset after the GUID
- //
- VirOffValue = *(UINTN *)((UINTN)Fv + *(*Offset + Index));
- //
- //Transfer the offset to the VA address. One modules may own more VfrBin address.
- //
- *(*Offset + Index) = (UINTN) EfiAddr + VirOffValue;
- Index++;
- }
- return EFI_SUCCESS;
-}
-
-/**
- Search the UniBin Base address.
-
- According the known GUID gUniStrArrayAttractGuid to get the base address from FFS.
-
- @param Fv the Pointer to the FFS
- @param EfiAddr the Pointer to the EFI in FFS
- @param Length the length of Fv
- @param Offset the Pointer to the Addr (Offset)
-
- @retval Base address Get the address successfully.
-**/
-EFI_STATUS
-SearchUniBinInFFS (
- IN VOID *Fv,
- IN VOID *EfiAddr,
- IN UINTN Length,
- OUT UINTN **Offset
- )
-{
- UINT8 NumOfMachingOffset;
- EFI_STATUS Status;
- UINTN VirOffValue;
-
- NumOfMachingOffset = 0;
- Status = EFI_SUCCESS;
- VirOffValue = 0;
-
- if ((Fv == NULL) || (Offset == NULL)) {
- return EFI_ABORTED;
- }
- Status = GetAddressByGuid (
- Fv,
- &gUniStrArrayAttractGuid,
- Length,
- Offset,
- &NumOfMachingOffset
- );
- if (Status != EFI_SUCCESS) {
- return EFI_ABORTED;
- }
- //
- //Transfer the offset to the VA address. There is only one UniArray in one modules.
- //
- if (NumOfMachingOffset == 1) {
- VirOffValue = *(UINTN *)((UINTN)Fv + **Offset);
- **Offset = (UINTN) EfiAddr + VirOffValue;
- } else {
- printf ("Error. Find more than 1 UniBin in FFS.\n");
- return EFI_ABORTED;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-SearchNvStoreDatabaseInFd(
- IN VOID *Fv,
- IN UINTN length
- )
-{
- EFI_STATUS Status;
- UINTN Offset;
- PCD_NV_STORE_DEFAULT_BUFFER_HEADER *NvStoreHeader;
- Status = EFI_SUCCESS;
- Offset = 0;
- if (Fv == NULL) {
- printf ("The FV is NULL.");
- return EFI_ABORTED;
- }
- while (Offset < (length - sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER))){
- NvStoreHeader = (PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)((UINT8*)Fv + Offset);
- if (NvStoreHeader->Signature == PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE) {
- gEfiFdInfo.ExistNvStoreDatabase = TRUE;
- gEfiFdInfo.NvStoreDatabase = (UINT8 *) NvStoreHeader;
- break;
- }
- Offset++;
- }
- if (Offset == (length - sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) || gEfiFdInfo.ExistNvStoreDatabase != TRUE) {
- //printf ("Not found the PcdNvStoreDefaultValueBuffer\n");
- return Status;
- }
- return Status;
-}
-
-/**
- Get the address by Guid.
-
- Parse the FD image, and find the GUID address.There may be some Guids matching the
- searched Guid.
-
- @param Fv the Pointer to the image.
- @param Guid The Guid need to find.
- @param Offset The dual Pointer to the offset.
- @param NumOfMatchGuid The number of matching Guid offset.
-
- @retval EFI_SUCCESS The Search was complete successfully
- @return EFI_ABORTED An error occurred
-**/
-EFI_STATUS
-GetVariableAddressByGuid (
- IN VOID *Fv,
- IN EFI_GUID *Guid,
- IN UINTN Len,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMatchGuid
- )
-{
- UINTN NextOffset;
- UINT8 Flag;
-
- if( (Fv == NULL) || (Fv == NULL) || (Guid == NULL) ){
- return EFI_ABORTED;
- }
-
- Flag = 0;
- NextOffset = 0;
-
- if (NumOfMatchGuid != NULL) {
- *NumOfMatchGuid = 0;
- }
- while (GetNextOffset(Fv, Guid, Len, &NextOffset)) {
- Flag = 1;
- if (NumOfMatchGuid != NULL && Offset != NULL) {
- if (*NumOfMatchGuid == 0) {
- *Offset = malloc (sizeof (UINTN) * MAX_MATCH_GUID_NUM);
- if (*Offset == NULL) {
- return EFI_ABORTED;
- }
- memset (*Offset, 0, sizeof (UINTN) * MAX_MATCH_GUID_NUM);
- }
- *(*Offset + *NumOfMatchGuid) = NextOffset;
- (*NumOfMatchGuid)++;
- } else {
- return EFI_SUCCESS;
- }
- }
-
- if( Flag == 0 ) {
- return EFI_ABORTED;
- }
- return EFI_SUCCESS;
-}
-
-/**
- Search the EFI Variable Base address.
-
- According the known GUID gEfiSystemNvDataFvGuid to get the base address from FFS.
-
- @param Fv the Pointer to the FFS
- @param Length the length of Fv
- @param Offset the Pointer to the Addr (Offset)
- @param NumOfMachingOffset the number of IFR array in one FFS
-
- @retval EFI_SUCCESS Get the address successfully.
- @retval EFI_ABORTED An error occured.
-**/
-EFI_STATUS
-SearchEfiVarInFFS (
- IN VOID *Fv,
- IN UINTN Length,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMachingOffset
- )
-{
- EFI_STATUS Status;
- UINT8 Index;
-
- Status = EFI_SUCCESS;
- Index = 0;
-
- if ((Fv == NULL) || (Offset == NULL)) {
- printf ("The FV or offset is NULL.");
- return EFI_ABORTED;
- }
- Status = GetVariableAddressByGuid (
- Fv,
- &gEfiSystemNvDataFvGuid,
- Length,
- Offset,
- NumOfMachingOffset
- );
- if (Status != EFI_SUCCESS) {
- return EFI_ABORTED;
- }
- //
- //Transfer the offset to the VA address.
- //
- while (Index < *NumOfMachingOffset) {
- *(*Offset + Index) = (UINTN) Fv + *(*Offset + Index);
- Index++;
- }
- return EFI_SUCCESS;
-}
-
-/**
- Parse the Ffs header to get the size.
-
- @param InputFile The pointer to the input file
- @param FvSize The pointer to the file size
-
- @return EFI_SUCCESS Get the file size successfully
-**/
-EFI_STATUS
-ReadFfsHeader (
- IN FILE *InputFile,
- OUT UINT32 *FvSize
- )
-{
- EFI_FFS_FILE_HEADER FfsHeader;
- EFI_FV_FILETYPE Type;
-
- //
- // Check input parameters
- //
- if ((InputFile == NULL) || (FvSize == NULL)) {
- return EFI_ABORTED;
- }
- //
- // Read the header
- //
- fread (
- &FfsHeader,
- sizeof (EFI_FFS_FILE_HEADER),
- 1,
- InputFile
- );
- Type = FfsHeader.Type;
-
- if (Type == EFI_FV_FILETYPE_DRIVER) {
- *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff;
- } else if (Type == EFI_FV_FILETYPE_APPLICATION) {
- *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff;
- } else if (Type == EFI_FV_FILETYPE_FREEFORM) {
- *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff;
- } else {
- return EFI_ABORTED;
- }
- return EFI_SUCCESS;
-}
-
-/*
- Read the length of the whole FD
-
- This function determines the size of the FV.
-
- @param InputFile The file that contains the FV image.
- @param FvSize The size of the FV.
-
- @retval EFI_SUCCESS The application exited normally.
- @retval EFI_ABORTED An error occurred.
-
-**/
-static
-EFI_STATUS
-ReadFdHeader (
- IN FILE *InputFile,
- OUT UINT32 *FvSize
- )
-{
- //
- // Check input parameters
- //
- if ((InputFile == NULL) || (FvSize == NULL)) {
- return EFI_ABORTED;
- }
- *FvSize = 0;
- //
- // Get the total size of FD file (Fixed the length)
- //
- fseek(InputFile,0,SEEK_END);
- *FvSize = ftell(InputFile);
- fseek(InputFile,0,SEEK_SET);
-
- if (*FvSize == 0) {
- return EFI_ABORTED;
- }
- return EFI_SUCCESS;
-}
-
-/**
- Read the file to memory.
-
- @param InputFile The file that contains the FV image.
- @param Size The size of the file.
-
- @retval The pointer to the begining position of memory.
-**/
-VOID *
-ReadFileToMemory (
- IN CHAR8 *FileName,
- OUT UINT32 *Size
- )
-{
- FILE *InFile;
- VOID *Address;
- UINT32 BytesRead;
- EFI_STATUS Status;
-
- InFile = NULL;
- Address = NULL;
- BytesRead = 0;
- Status = EFI_SUCCESS;
-
- InFile = fopen (FileName,"rb");
- if (InFile == NULL) {
- return NULL;
- }
- //
- // Determine the size of FV
- //
- Status = ReadFdHeader (InFile, Size);
- if (Status != EFI_SUCCESS) {
- fclose (InFile);
- return NULL;
- }
- //
- // Allocate a buffer for the FV image
- //
- Address = malloc (*Size);
- if (Address == NULL) {
- fclose (InFile);
- return NULL;
- }
- memset (Address, 0, *Size);
- //
- // Seek to the start of the image, then read the entire FV to the buffer
- //
- fseek (InFile, 0, SEEK_SET);
- BytesRead = fread (Address, 1, *Size, InFile);
- fclose (InFile);
- if ((UINTN) BytesRead != *Size) {
- free (Address);
- return NULL;
- }
- return Address;
-}
-
-/**
- Search the EFI variables address in Fd.
-
- Open and read the *.fd to the memory, initialize the global structure.
- Update the EFI variables addr and the begining position of memory.
-
- @retval EFI_SUCCESS Get the address successfully.
-**/
-EFI_STATUS
-GetEfiVariablesAddr (
- BOOLEAN UqiIsSet
- )
-{
- VOID *FdImage;
- UINT32 FdSize;
- EFI_STATUS Status;
- UINTN *EfiVarAddr;
- UINT8 NumOfMachingVar;
- UINT32 Index;
- BOOLEAN GotFlag;
- EFI_FIRMWARE_VOLUME_HEADER *Variable;
- BOOLEAN AuthencitatedMonotonicOrNot;
- BOOLEAN AuthencitatedBasedTimeOrNot;
- BOOLEAN NormalOrNot;
-
- FdImage = NULL;
- FdSize = 0;
- Status = EFI_SUCCESS;
- EfiVarAddr = NULL;
- NumOfMachingVar = 0;
- Index = 0;
- GotFlag = TRUE;
- Variable = NULL;
-
- FdImage = ReadFileToMemory (mInputFdName, &FdSize);
- if (FdImage == NULL) {
- return EFI_ABORTED;
- }
- if (!UqiIsSet) {
- Status = SearchNvStoreDatabaseInFd(FdImage, FdSize);
- if (EFI_ERROR (Status)) {
- return EFI_ABORTED;
- }
- }
- Status = SearchEfiVarInFFS (
- FdImage,
- FdSize,
- &EfiVarAddr,
- &NumOfMachingVar
- );
- if (EFI_ERROR (Status)) {
- return EFI_ABORTED;
- }
- //
- // Check the signature "_FVH"
- //
- Index = 0;
- GotFlag = FALSE;
-
- while (Index < NumOfMachingVar) {
- Variable = (EFI_FIRMWARE_VOLUME_HEADER *)(*(EfiVarAddr + Index) - 0x20);
- if (Variable->Signature == 0x4856465F) {
- AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore ((UINT8 *)Variable + Variable->HeaderLength);
- AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot ((UINT8 *)Variable + Variable->HeaderLength);
- NormalOrNot = CheckNormalVarStoreOrNot ((UINT8 *)Variable + Variable->HeaderLength);
- if (AuthencitatedMonotonicOrNot || AuthencitatedBasedTimeOrNot || NormalOrNot) {
- GotFlag = TRUE;
- gEfiFdInfo.EfiVariableAddr = (UINTN)Variable;
- break;
- }
- }
- Index++;
- }
- free (EfiVarAddr);
- if (!GotFlag) {
- return EFI_ABORTED;
- }
- gEfiFdInfo.Fd = FdImage;
- gEfiFdInfo.FdSize = FdSize;
-
- return EFI_SUCCESS;
-}
-
-/**
- Pick up the FFS which includes IFR section.
-
- Parse all FFS extracted by BfmLib, and save all which includes IFR
- Binary to gEfiFdInfo structure.
-
- @retval EFI_SUCCESS Get the address successfully.
- @retval EFI_BUFFER_TOO_SMALL Memory can't be allocated.
- @retval EFI_ABORTED Read FFS Failed.
-**/
-EFI_STATUS
-FindFileInFolder (
- IN CHAR8 *FolderName,
- OUT BOOLEAN *ExistStorageInBfv,
- OUT BOOLEAN *SizeOptimized
-)
-{
- CHAR8 *FileName;
- CHAR8 *CurFolderName;
- EFI_STATUS Status;
- UINTN MaxFileNameLen;
- UINTN Index;
- CHAR8 FileNameArry[MAX_FILENAME_LEN];
- FILE *FfsFile;
- UINTN FileSize;
- VOID *FfsImage;
- UINTN BytesRead;
-#ifndef __GNUC__
- HANDLE FindHandle;
- WIN32_FIND_DATA FindFileData;
-#else
- struct dirent *pDirent;
- DIR *pDir;
-#endif
-
- FileName = NULL;
- CurFolderName = NULL;
- Status = EFI_SUCCESS;
- MaxFileNameLen = 0;
- Index = 0;
- FileSize = 0;
- BytesRead = 0;
- FfsImage = NULL;
- FfsFile = NULL;
-
- MaxFileNameLen = strlen (FolderName) + MAX_FILENAME_LEN;
- CurFolderName = (CHAR8 *)calloc(
- strlen (FolderName) + strlen (OS_SEP_STR) + strlen ("*.*")+ 1,
- sizeof(CHAR8)
- );
- if (CurFolderName == NULL) {
- return EFI_BUFFER_TOO_SMALL;
- }
- strcpy (CurFolderName, FolderName);
- strcat (CurFolderName, OS_SEP_STR);
- strcat (CurFolderName, "*.*");
- FileName = (CHAR8 *)calloc(
- MaxFileNameLen,
- sizeof(CHAR8)
- );
- if (FileName == NULL) {
- free (CurFolderName);
- return EFI_BUFFER_TOO_SMALL;
- }
-
-#ifndef __GNUC__
- if((FindHandle = FindFirstFile(CurFolderName, &FindFileData)) != INVALID_HANDLE_VALUE){
- do {
- memset (FileName, 0, MaxFileNameLen);
- if ((strcmp (FindFileData.cFileName, ".") == 0)
- || (strcmp (FindFileData.cFileName, "..") == 0)
- ) {
- continue;
- }
- if (strlen(FolderName) + strlen ("\\") + strlen (FindFileData.cFileName) > MAX_FILENAME_LEN - 1) {
- Status = EFI_ABORTED;
- goto Done;
- }
- snprintf (FileNameArry, MAX_FILENAME_LEN, "%s%c%s", FolderName, OS_SEP, FindFileData.cFileName);
- FfsFile = fopen (FileNameArry, "rb");
- if (FfsFile == NULL) {
- Status = EFI_ABORTED;
- goto Done;
- }
- Status = ReadFfsHeader (FfsFile, (UINT32 *)&FileSize);
- if (EFI_ERROR (Status)) {
- fclose (FfsFile);
- Status = EFI_SUCCESS;
- continue;
- }
- //
- // Allocate a buffer for the FFS file
- //
- FfsImage = malloc (FileSize);
- if (FfsImage == NULL) {
- fclose (FfsFile);
- Status = EFI_BUFFER_TOO_SMALL;
- goto Done;
- }
- //
- // Seek to the start of the image, then read the entire FV to the buffer
- //
- fseek (FfsFile, 0, SEEK_SET);
- BytesRead = fread (FfsImage, 1, FileSize, FfsFile);
- fclose (FfsFile);
-
- if ((UINTN) BytesRead != FileSize) {
- free (FfsImage);
- Status = EFI_ABORTED;
- goto Done;
- }
- //
- // Check whether exists the storage ffs in BFV for multi-platform mode
- //
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid,(EFI_GUID *) FfsImage) == 0) {
- *ExistStorageInBfv = TRUE;
- *SizeOptimized = FALSE;
- gEfiFdInfo.StorageFfsInBfv = FfsImage;
- continue;
- }
- //
- // Check whether exists the optimized storage ffs in BFV for multi-platform mode
- //
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid2,(EFI_GUID *) FfsImage) == 0) {
- *ExistStorageInBfv = TRUE;
- *SizeOptimized = TRUE;
- gEfiFdInfo.StorageFfsInBfv = FfsImage;
- continue;
- }
- //
- // Check whether current FFS includes IFR
- //
- Status = GetAddressByGuid (
- FfsImage,
- &gVfrArrayAttractGuid,
- FileSize,
- NULL,
- NULL
- );
- if (EFI_ERROR (Status)) {
- free (FfsImage);
- Status = EFI_SUCCESS;
- } else {
- //
- // Check whether existed same IFR binary. If existed, not insert the new one.
- //
- if (NotExistSameFfsIfr (FfsImage)) {
- gEfiFdInfo.FfsArray[Index] = FfsImage;
- gEfiFdInfo.Length[Index++] = FileSize;
- }
- }
-
- } while (FindNextFile (FindHandle, &FindFileData));
- FindClose(FindHandle);
- } else {
- Status = EFI_ABORTED;
- goto Done;
- }
-
-Done:
- free (CurFolderName);
- free (FileName);
-
-#else
- if((pDir = opendir(FolderName)) != NULL){
- while ((pDirent = readdir(pDir)) != NULL){
- memset (FileName, 0, MaxFileNameLen);
- if ((strcmp (pDirent->d_name, ".") == 0)
- || (strcmp (pDirent->d_name, "..") == 0)
- ) {
- continue;
- }
- sprintf (FileNameArry, "%s%c%s", FolderName, OS_SEP, pDirent->d_name);
- FfsFile = fopen (FileNameArry, "rb");
- Status = ReadFfsHeader (FfsFile, (UINT32 *)&FileSize);
- if (EFI_ERROR (Status)) {
- fclose (FfsFile);
- Status = EFI_SUCCESS;
- continue;
- }
- //
- // Allocate a buffer for the FFS file
- //
- FfsImage = malloc (FileSize);
- if (FfsImage == NULL) {
- fclose (FfsFile);
- Status = EFI_BUFFER_TOO_SMALL;
- goto Done;
- }
- //
- // Seek to the start of the image, then read the entire FV to the buffer
- //
- fseek (FfsFile, 0, SEEK_SET);
- BytesRead = fread (FfsImage, 1, FileSize, FfsFile);
- fclose (FfsFile);
-
- if ((UINTN) BytesRead != FileSize) {
- free (FfsImage);
- Status = EFI_ABORTED;
- goto Done;
- }
- //
- // Check whether exists the storage ffs in BFV for multi-platform mode
- //
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid,(EFI_GUID *) FfsImage) == 0) {
- *ExistStorageInBfv = TRUE;
- *SizeOptimized = FALSE;
- gEfiFdInfo.StorageFfsInBfv = FfsImage;
- continue;
- }
- //
- // Check whether exists the optimized storage ffs in BFV for multi-platform mode
- //
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid2,(EFI_GUID *) FfsImage) == 0) {
- *ExistStorageInBfv = TRUE;
- *SizeOptimized = TRUE;
- gEfiFdInfo.StorageFfsInBfv = FfsImage;
- continue;
- }
- //
- // Check whether current FFS includes IFR
- //
- Status = GetAddressByGuid (
- FfsImage,
- &gVfrArrayAttractGuid,
- FileSize,
- NULL,
- NULL
- );
- if (EFI_ERROR (Status)) {
- free (FfsImage);
- Status = EFI_SUCCESS;
- } else {
- //
- // Check whether existed same IFR binary. If existed, not insert the new one.
- //
- if (NotExistSameFfsIfr (FfsImage)) {
- gEfiFdInfo.FfsArray[Index] = FfsImage;
- gEfiFdInfo.Length[Index++] = FileSize;
- }
- }
-
- }
- closedir(pDir);
- } else {
- Status = EFI_ABORTED;
- goto Done;
- }
-
-Done:
- free (CurFolderName);
- free (FileName);
-#endif
- return Status;
-}
-