+++ /dev/null
-/** @file\r
-\r
- Library to process EFI image.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BinFileManager.h"\r
-\r
-#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \\r
- ( \\r
- (BOOLEAN) ( \\r
- (FvbAttributes & EFI_FVB2_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \\r
- ) \\r
- )\r
-\r
-#ifndef __GNUC__\r
-#define DECODE_STR "%s -d -o \"%s\" \"%s\" > NUL"\r
-#define ENCODE_STR "%s -e \"%s\" -o \"%s\" > NUL"\r
-#define GENSEC_COMPRESSION "GenSec -s %s -c %s \"%s\" -o \"%s\" > NUL"\r
-#define GENSEC_GUID "GenSec -s %s -r PROCESSING_REQUIRED -g %s \"%s\" -o \"%s\" > NUL"\r
-#define GENSEC_STR "GenSec -s %s \"%s\" -o \"%s\" > NUL"\r
-#define GENSEC_ALIGN "GenSec --sectionalign 16 \"%s\" -o \"%s\" > NUL"\r
-#define GENFV_STR "GenFv -i \"%s\" -o \"%s\" > NUL"\r
-#define GENFV_FVGUID "GenFv -i \"%s\" -o \"%s\" --FvNameGuid %s > NUL"\r
-#define GENFV_FFS "GenFv -f \"%s\" -g %s -o \"%s\" > NUL"\r
-#define GENFFS_STR "GenFfs -t %s -i \"%s\" -g %s -o \"%s\" > NUL"\r
-#define GENFFS_FIX "GenFfs -t %s -i \"%s\" -g %s -x -o \"%s\" > NUL"\r
-#else\r
-#define DECODE_STR "%s -d -o \"%s\" \"%s\" > /dev/null"\r
-#define ENCODE_STR "%s -e \"%s\" -o \"%s\" > /dev/null"\r
-#define GENSEC_COMPRESSION "GenSec -s %s -c %s \"%s\" -o \"%s\" > /dev/null"\r
-#define GENSEC_GUID "GenSec -s %s -r PROCESSING_REQUIRED -g %s \"%s\" -o \"%s\" > /dev/null"\r
-#define GENSEC_STR "GenSec -s %s \"%s\" -o \"%s\" > /dev/null"\r
-#define GENSEC_ALIGN "GenSec --sectionalign 16 \"%s\" -o \"%s\" > /dev/null"\r
-#define GENFV_STR "GenFv -i \"%s\" -o \"%s\" > /dev/null"\r
-#define GENFV_FVGUID "GenFv -i \"%s\" -o \"%s\" --FvNameGuid %s > /dev/null"\r
-#define GENFV_FFS "GenFv -f \"%s\" -g %s -o \"%s\" > /dev/null"\r
-#define GENFFS_STR "GenFfs -t %s -i \"%s\" -g %s -o \"%s\" > /dev/null"\r
-#define GENFFS_FIX "GenFfs -t %s -i \"%s\" -g %s -x -o \"%s\" > /dev/null"\r
-#endif\r
-\r
-#define DECODE_STR_ERR "%s -d -o \"%s\" \"%s\" "\r
-#define ENCODE_STR_ERR "%s -e \"%s\" -o \"%s\" "\r
-\r
-CHAR8 mFirmwareFileSystem2Guid[16] = {0x78, 0xE5, 0x8C, 0x8C, 0x3D, 0x8A, 0x1C, 0x4F, 0x99, 0x35, 0x89, 0x61, 0x85, 0xC3, 0x2D, 0xD3};\r
-\r
-CHAR8 mFirmwareFileSystem3Guid[16] = {0x7A, 0xC0, 0x73, 0x54, 0xCB, 0x3D, 0xCA, 0x4D, 0xBD, 0x6F, 0x1E, 0x96, 0x89, 0xE7, 0x34, 0x9A };\r
-extern CHAR8* mGuidToolDefinition;\r
-UINT32 PadSizeOfBfv;\r
-\r
-static CHAR8 *mSectionTypeName[] = {\r
- NULL, // 0x00 - reserved\r
- "EFI_SECTION_COMPRESSION", // 0x01\r
- "EFI_SECTION_GUID_DEFINED", // 0x02\r
- NULL, // 0x03 - reserved\r
- NULL, // 0x04 - reserved\r
- NULL, // 0x05 - reserved\r
- NULL, // 0x06 - reserved\r
- NULL, // 0x07 - reserved\r
- NULL, // 0x08 - reserved\r
- NULL, // 0x09 - reserved\r
- NULL, // 0x0A - reserved\r
- NULL, // 0x0B - reserved\r
- NULL, // 0x0C - reserved\r
- NULL, // 0x0D - reserved\r
- NULL, // 0x0E - reserved\r
- NULL, // 0x0F - reserved\r
- "EFI_SECTION_PE32", // 0x10\r
- "EFI_SECTION_PIC", // 0x11\r
- "EFI_SECTION_TE", // 0x12\r
- "EFI_SECTION_DXE_DEPEX", // 0x13\r
- "EFI_SECTION_VERSION", // 0x14\r
- "EFI_SECTION_USER_INTERFACE", // 0x15\r
- "EFI_SECTION_COMPATIBILITY16", // 0x16\r
- "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17\r
- "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18\r
- "EFI_SECTION_RAW", // 0x19\r
- NULL, // 0x1A\r
- "EFI_SECTION_PEI_DEPEX", // 0x1B\r
- "EFI_SECTION_SMM_DEPEX" // 0x1C\r
-};\r
-\r
-\r
-static CHAR8 *mFfsFileType[] = {\r
- NULL, // 0x00\r
- "EFI_FV_FILETYPE_RAW", // 0x01\r
- "EFI_FV_FILETYPE_FREEFORM", // 0x02\r
- "EFI_FV_FILETYPE_SECURITY_CORE", // 0x03\r
- "EFI_FV_FILETYPE_PEI_CORE", // 0x04\r
- "EFI_FV_FILETYPE_DXE_CORE", // 0x05\r
- "EFI_FV_FILETYPE_PEIM", // 0x06\r
- "EFI_FV_FILETYPE_DRIVER", // 0x07\r
- "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER", // 0x08\r
- "EFI_FV_FILETYPE_APPLICATION", // 0x09\r
- "EFI_FV_FILETYPE_SMM", // 0x0A\r
- "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE",// 0x0B\r
- "EFI_FV_FILETYPE_COMBINED_SMM_DXE", // 0x0C\r
- "EFI_FV_FILETYPE_SMM_CORE" // 0x0D\r
- };\r
-\r
-FV_INFORMATION *\r
-LibInitializeFvStruct (\r
- FV_INFORMATION *Fv\r
-)\r
-{\r
- UINT32 Index;\r
-\r
- if (Fv == NULL) {\r
- return NULL;\r
- }\r
-\r
- memset (Fv, '\0', sizeof (FV_INFORMATION));\r
-\r
- for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index ++) {\r
- memset (Fv->FfsAttuibutes[Index].FfsName, '\0', _MAX_PATH);\r
- memset (Fv->FfsAttuibutes[Index].UiName, '\0', _MAX_PATH);\r
-\r
- Fv->FfsAttuibutes[Index].IsLeaf = TRUE;\r
- Fv->FfsAttuibutes[Index].TotalSectionNum = 0;\r
- }\r
-\r
- Fv->PatchData = NULL;\r
- Fv->EncapData = NULL;\r
- Fv->FvNext = NULL;\r
- Fv->FvLevel = 0;\r
- Fv->IsBfvFlag = FALSE;\r
- Fv->IsInputFvFlag = FALSE;\r
-\r
- return Fv;\r
-}\r
-\r
-/**\r
- Generate the unique template filename.\r
-**/\r
-CHAR8 *\r
-GenTempFile (\r
- VOID\r
- )\r
-{\r
- CHAR8 *TemString;\r
- TemString = NULL;\r
-#ifndef __GNUC__\r
- TemString = CloneString (tmpnam (NULL));\r
-#else\r
- CHAR8 tmp[] = "/tmp/fileXXXXXX";\r
- UINTN Fdtmp;\r
- Fdtmp = mkstemp(tmp);\r
- TemString = CloneString(tmp);\r
- close(Fdtmp);\r
-#endif\r
- return TemString;\r
-}\r
-\r
-EFI_STATUS\r
-LibFindFvInFd (\r
- IN FILE *InputFile,\r
- IN OUT FIRMWARE_DEVICE **FdData\r
-)\r
-{\r
- FIRMWARE_DEVICE *LocalFdData;\r
- UINT16 Index;\r
- CHAR8 Ffs2Guid[16];\r
- CHAR8 SignatureCheck[4];\r
- CHAR8 Signature[5] = "_FVH";\r
- FV_INFORMATION *CurrentFv;\r
- FV_INFORMATION *NewFoundFv;\r
- BOOLEAN FirstMatch;\r
- UINT32 FdSize;\r
- UINT16 FvCount;\r
- VOID *FdBuffer;\r
- VOID *FdBufferOri;\r
- UINT32 Count;\r
-\r
-\r
- CurrentFv = NULL;\r
- NewFoundFv = NULL;\r
- FdBuffer = NULL;\r
- FdBufferOri = NULL;\r
- FirstMatch = TRUE;\r
- Index = 0;\r
- FdSize = 0;\r
- FvCount = 0;\r
- Count = 0;\r
- LocalFdData = NULL;\r
-\r
- if (InputFile == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Find each FVs in the FD\r
- //\r
-\r
- fseek(InputFile,0,SEEK_SET);\r
- fseek(InputFile,0,SEEK_END);\r
-\r
- FdSize = ftell(InputFile);\r
-\r
- fseek(InputFile,0,SEEK_SET);\r
- //\r
- // Create an FD structure to store useful information.\r
- //\r
- LocalFdData = (FIRMWARE_DEVICE *) calloc (sizeof (FIRMWARE_DEVICE), sizeof(UINT8));\r
- if (LocalFdData == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- LocalFdData->Fv = (FV_INFORMATION *) calloc (sizeof (FV_INFORMATION), sizeof(UINT8));\r
- if (LocalFdData->Fv == NULL) {\r
- free (LocalFdData);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- LibInitializeFvStruct (LocalFdData->Fv);\r
-\r
- //\r
- // Readout the FD file data to buffer.\r
- //\r
- FdBuffer = malloc (FdSize);\r
-\r
- if (FdBuffer == NULL) {\r
- free (LocalFdData->Fv);\r
- free (LocalFdData);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (fread (FdBuffer, 1, FdSize, InputFile) != FdSize) {\r
- free (LocalFdData->Fv);\r
- free (LocalFdData);\r
- free (FdBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- FdBufferOri = FdBuffer;\r
-\r
- for (Count=0; Count < FdSize - 4; Count++) {\r
- //\r
- // Copy 4 bytes of fd data to check the _FVH signature\r
- //\r
- memcpy (SignatureCheck, FdBuffer, 4);\r
- FdBuffer =(UINT8 *)FdBuffer + 4;\r
-\r
- if (strncmp(SignatureCheck, Signature, 4) == 0){\r
- //\r
- // Still need to determine the FileSystemGuid in EFI_FIRMWARE_VOLUME_HEADER equal to\r
- // EFI_FIRMWARE_FILE_SYSTEM2_GUID.\r
- // Turn back 28 bytes to find the GUID.\r
- //\r
- FdBuffer = (UINT8 *)FdBuffer - 28;\r
- memcpy (Ffs2Guid, FdBuffer, 16);\r
-\r
- //\r
- // Compare GUID.\r
- //\r
- for (Index = 0; Index < 16; Index ++) {\r
- if (Ffs2Guid[Index] != mFirmwareFileSystem2Guid[Index]) {\r
- break;\r
- }\r
- }\r
- if (Index != 16) {\r
- for (Index = 0; Index < 16; Index ++) {\r
- if (Ffs2Guid[Index] != mFirmwareFileSystem3Guid[Index]) {\r
- break;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Point to the original address\r
- //\r
- FdBuffer = (UINT8 *)FdBuffer + 28;\r
-\r
- //\r
- // Here we found an FV.\r
- //\r
- if (Index == 16) {\r
- if (FirstMatch) {\r
- LocalFdData->Fv->ImageAddress = (UINTN)((UINT8 *)FdBuffer - (UINT8 *)FdBufferOri) - 0x2c;\r
- CurrentFv = LocalFdData->Fv;\r
- CurrentFv->FvNext = NULL;\r
- //\r
- // Store the FV name by found sequence\r
- //\r
- sprintf(CurrentFv->FvName, "FV%d", FvCount);\r
-\r
- FirstMatch = FALSE;\r
- } else {\r
- NewFoundFv = (FV_INFORMATION *) malloc (sizeof (FV_INFORMATION));\r
- if (NULL == NewFoundFv) {\r
- free (LocalFdData->Fv);\r
- free (LocalFdData);\r
- free (FdBuffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- LibInitializeFvStruct (NewFoundFv);\r
-\r
- //\r
- // Need to turn back 0x2c bytes\r
- //\r
- NewFoundFv->ImageAddress = (UINTN)((UINT8 *)FdBuffer - (UINT8 *)FdBufferOri) - 0x2c;\r
-\r
- //\r
- // Store the FV name by found sequence\r
- //\r
- sprintf(NewFoundFv->FvName, "FV%d", FvCount);\r
-\r
- //\r
- // Value it to NULL for found FV usage.\r
- //\r
- NewFoundFv->FvNext = NULL;\r
- CurrentFv->FvNext = NewFoundFv;\r
-\r
- //\r
- // Make the CurrentFv point to next FV.\r
- //\r
- CurrentFv = CurrentFv->FvNext;\r
- }\r
-\r
- FvCount ++;\r
- Index = 0;\r
- }\r
-\r
- }\r
-\r
- //\r
- // We need to turn back 3 bytes.\r
- //\r
- FdBuffer = (UINT8 *)FdBuffer - 3;\r
- }\r
-\r
- LocalFdData->Size = FdSize;\r
-\r
- *FdData = LocalFdData;\r
-\r
- free (FdBufferOri);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/*\r
- Get size info from FV file.\r
-\r
- @param[in]\r
- @param[out]\r
-\r
- @retval\r
-\r
-*/\r
-EFI_STATUS\r
-LibGetFvSize (\r
- IN FILE *InputFile,\r
- OUT UINT32 *FvSize\r
- )\r
-{\r
-\r
- UINTN BytesRead;\r
- UINT32 Size;\r
- EFI_FV_BLOCK_MAP_ENTRY BlockMap;\r
-\r
- BytesRead = 0;\r
- Size = 0;\r
-\r
- if (InputFile == NULL || FvSize == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- fseek (InputFile, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), SEEK_CUR);\r
- do {\r
- fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
- BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
-\r
- if (BlockMap.NumBlocks != 0) {\r
- Size += BlockMap.NumBlocks * BlockMap.Length;\r
- }\r
- } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));\r
-\r
-\r
- *FvSize = Size;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
- Expands the 3 byte size commonly used in Firmware Volume data structures\r
-\r
- @param[in] Size - Address of the 3 byte array representing the size\r
-\r
- @return UINT32\r
-\r
-**/\r
-UINT32\r
-FvBufExpand3ByteSize (\r
- IN VOID* Size\r
- )\r
-{\r
- return (((UINT8*)Size)[2] << 16) +\r
- (((UINT8*)Size)[1] << 8) +\r
- ((UINT8*)Size)[0];\r
-}\r
-\r
-/**\r
-\r
- Clears out all files from the Fv buffer in memory\r
-\r
- @param[in] Fv - Address of the Fv in memory\r
-\r
- @return EFI_STATUS\r
-\r
-**/\r
-EFI_STATUS\r
-FvBufGetSize (\r
- IN VOID *Fv,\r
- OUT UINTN *Size\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *hdr;\r
- EFI_FV_BLOCK_MAP_ENTRY *blk;\r
-\r
- *Size = 0;\r
- hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;\r
- blk = hdr->BlockMap;\r
-\r
- while (blk->Length != 0 || blk->NumBlocks != 0) {\r
- *Size = *Size + (blk->Length * blk->NumBlocks);\r
- if (*Size >= 0x40000000) {\r
- //\r
- // If size is greater than 1GB, then assume it is corrupted\r
- //\r
- return EFI_VOLUME_CORRUPTED;\r
- }\r
- blk++;\r
- }\r
-\r
- if (*Size == 0) {\r
- //\r
- // If size is 0, then assume the volume is corrupted\r
- //\r
- return EFI_VOLUME_CORRUPTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-/**\r
-\r
- Iterates through the files contained within the firmware volume\r
-\r
- @param[in] Fv - Address of the Fv in memory\r
- @param[in] Key - Should be 0 to get the first file. After that, it should be\r
- passed back in without modifying it's contents to retrieve\r
- subsequent files.\r
- @param[in] File- Output file pointer\r
- File == NULL - invalid parameter\r
- otherwise - *File will be update to the location of the file\r
-\r
- @return EFI_STATUS\r
- EFI_NOT_FOUND\r
- EFI_VOLUME_CORRUPTED\r
-\r
-**/\r
-EFI_STATUS\r
-FvBufFindNextFile (\r
- IN VOID *Fv,\r
- IN OUT UINTN *Key,\r
- OUT VOID **File\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *hdr;\r
- EFI_FFS_FILE_HEADER *fhdr;\r
- EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader;\r
- EFI_FVB_ATTRIBUTES_2 FvbAttributes;\r
- UINTN fsize;\r
- EFI_STATUS Status;\r
- UINTN fvSize;\r
-\r
- hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;\r
- fhdr = NULL;\r
-\r
- if (Fv == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = FvBufGetSize (Fv, &fvSize);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (*Key == 0) {\r
- if (hdr->ExtHeaderOffset != 0) {\r
- //\r
- // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.\r
- //\r
- FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) ((UINT8 *) hdr + hdr->ExtHeaderOffset);\r
- *Key = (UINTN)hdr->ExtHeaderOffset + FwVolExtHeader->ExtHeaderSize;\r
- *Key = (UINTN)ALIGN_POINTER (*Key, 8);\r
- } else {\r
- *Key = hdr->HeaderLength;\r
- }\r
- }\r
-\r
- FvbAttributes = hdr->Attributes;\r
-\r
- for(\r
- *Key = (UINTN)ALIGN_POINTER (*Key, 8);\r
- (*Key + sizeof (*fhdr)) < fvSize;\r
- *Key = (UINTN)ALIGN_POINTER (*Key, 8)\r
- ) {\r
- fhdr = (EFI_FFS_FILE_HEADER*) ((UINT8*)hdr + *Key);\r
- fsize = GetFfsFileLength (fhdr);\r
- if (!EFI_TEST_FFS_ATTRIBUTES_BIT(\r
- FvbAttributes,\r
- fhdr->State,\r
- EFI_FILE_HEADER_VALID\r
- ) ||\r
- EFI_TEST_FFS_ATTRIBUTES_BIT(\r
- FvbAttributes,\r
- fhdr->State,\r
- EFI_FILE_HEADER_INVALID\r
- )\r
- ) {\r
- *Key = *Key + 1;\r
- continue;\r
- } else if(\r
- EFI_TEST_FFS_ATTRIBUTES_BIT(\r
- FvbAttributes,\r
- fhdr->State,\r
- EFI_FILE_MARKED_FOR_UPDATE\r
- ) ||\r
- EFI_TEST_FFS_ATTRIBUTES_BIT(\r
- FvbAttributes,\r
- fhdr->State,\r
- EFI_FILE_DELETED\r
- )\r
- ) {\r
- *Key = *Key + fsize;\r
- continue;\r
- } else if (EFI_TEST_FFS_ATTRIBUTES_BIT(\r
- FvbAttributes,\r
- fhdr->State,\r
- EFI_FILE_DATA_VALID\r
- )\r
- ) {\r
- *File = (UINT8*)hdr + *Key;\r
- *Key = *Key + fsize;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- *Key = *Key + 1;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/*\r
- Generate the leaf FFS files.\r
-\r
-*/\r
-EFI_STATUS\r
-LibGenFfsFile (\r
- EFI_FFS_FILE_HEADER2 *CurrentFile,\r
- FV_INFORMATION *CurrentFv,\r
- CHAR8 *FvName,\r
- UINT8 Level,\r
- UINT32 *FfsCount,\r
- BOOLEAN ErasePolarity\r
-)\r
-{\r
- UINT32 FfsFileSize;\r
- CHAR8 *FfsFileName;\r
- FILE *FfsFile;\r
- CHAR8 *TempDir;\r
- CHAR8 TempBuf[_MAX_PATH];\r
-\r
- FfsFileSize = 0;\r
- FfsFileName = NULL;\r
- FfsFile = NULL;\r
- TempDir = NULL;\r
-\r
- TempDir = getcwd (NULL, _MAX_PATH);\r
-\r
- if (strlen (TempDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- strncat (TempDir, OS_SEP_STR, _MAX_PATH - strlen (TempDir) - 1);\r
- strncat (TempDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TempDir) - 1);\r
- mkdir(TempDir, S_IRWXU | S_IRWXG | S_IRWXO);\r
-\r
- FfsFileName = (CHAR8 *) malloc (_MAX_PATH);\r
- if (NULL == FfsFileName) {\r
- return EFI_ABORTED;\r
- }\r
- memset (FfsFileName, '\0', _MAX_PATH);\r
- FfsFileSize = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
-\r
- sprintf (\r
- TempBuf,\r
- "-Num%d-%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X-Level%d",\r
- *FfsCount,\r
- (unsigned) CurrentFile->Name.Data1,\r
- CurrentFile->Name.Data2,\r
- CurrentFile->Name.Data3,\r
- CurrentFile->Name.Data4[0],\r
- CurrentFile->Name.Data4[1],\r
- CurrentFile->Name.Data4[2],\r
- CurrentFile->Name.Data4[3],\r
- CurrentFile->Name.Data4[4],\r
- CurrentFile->Name.Data4[5],\r
- CurrentFile->Name.Data4[6],\r
- CurrentFile->Name.Data4[7],\r
- Level\r
- );\r
- if (strlen (TempDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME) + strlen(TempBuf) > _MAX_PATH - 1) {\r
- free(FfsFileName);\r
- printf ("The directory is too long \n");\r
- return EFI_ABORTED;\r
- }\r
- strcpy (FfsFileName, TempDir);\r
- strncat (FfsFileName, OS_SEP_STR, _MAX_PATH - strlen (FfsFileName) - 1);\r
- strncat (FfsFileName, CurrentFv->FvName, _MAX_PATH - strlen (FfsFileName) - 1);\r
- strncat (FfsFileName, TempBuf, _MAX_PATH - strlen (FfsFileName) - 1);\r
-\r
- memcpy (CurrentFv->FfsAttuibutes[*FfsCount].FfsName, FfsFileName, strlen(FfsFileName));\r
-\r
- //\r
- // Update current FFS files file state.\r
- //\r
- if (ErasePolarity) {\r
- CurrentFile->State = (UINT8)~(CurrentFile->State);\r
- }\r
-\r
- FfsFile = fopen (FfsFileName, "wb+");\r
- if (FfsFile == NULL) {\r
- free(FfsFileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (fwrite (CurrentFile, 1, FfsFileSize, FfsFile) != FfsFileSize) {\r
- fclose(FfsFile);\r
- free(FfsFileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fclose(FfsFile);\r
- free(FfsFileName);\r
- FfsFileName = NULL;\r
-\r
- CurrentFv->FfsNumbers = *FfsCount;\r
-\r
- *FfsCount += 1;\r
-\r
- if (ErasePolarity) {\r
- CurrentFile->State = (UINT8)~(CurrentFile->State);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-BOOLEAN\r
-LibCheckPadFfsContainFvNameGuid (\r
- IN FV_INFORMATION *CurrentFv,\r
- IN EFI_FFS_FILE_HEADER2 *CurrentFile\r
-)\r
-{\r
- UINT32 FfsFileSize;\r
- UINT32 FfsDataSize;\r
- EFI_GUID *FfsData;\r
- ENCAP_INFO_DATA *LocalEncapData;\r
-\r
- LocalEncapData = NULL;\r
-\r
- FfsFileSize = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
- FfsDataSize = FfsFileSize - GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
- FfsData = (EFI_GUID *) ((INT8 *)CurrentFile + GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile));\r
-\r
- if (FfsDataSize == 0) {\r
- return TRUE;\r
- }\r
-\r
- LocalEncapData = CurrentFv->EncapData;\r
-\r
- do {\r
- if (LocalEncapData->FvExtHeader != NULL) {\r
- if (CompareGuid(FfsData, &LocalEncapData->FvExtHeader->FvName) == 0) {\r
- return TRUE;\r
- }\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- } while (LocalEncapData->NextNode != NULL);\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-LibCheckPadFfsNotNull (\r
- IN EFI_FFS_FILE_HEADER2 *CurrentFile\r
-)\r
-{\r
- UINT32 FfsFileSize;\r
- UINT32 FfsDataSize;\r
- INT8 *FfsData;\r
-\r
- FfsFileSize = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
- FfsDataSize = FfsFileSize - GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
- FfsData = (INT8 *)CurrentFile + GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
-\r
- if (FfsDataSize == 0) {\r
- return FALSE;\r
- }\r
-\r
- while (FfsDataSize > 0) {\r
- if (((FfsData[FfsDataSize-1]) & 0xFF) != 0xFF) {\r
- return TRUE;\r
- }\r
- FfsDataSize--;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Find a maximum length of free space in PAD FFS of Bfv.\r
-\r
- @PadFfsHeader - The header of PAD FFS file\r
-\r
- @return The length of free space\r
-\r
-**/\r
-UINT32\r
-GetBfvMaxFreeSpace (\r
- IN EFI_FFS_FILE_HEADER2 *PadFfsHeader\r
- )\r
-{\r
- UINT32 FfsSize;\r
- UINT32 Count;\r
- UINT32 Index;\r
- UINT32 MaxSize;\r
- UINT32 HeaderSize;\r
-\r
- Index = 0;\r
- MaxSize = 0;\r
-\r
- if (PadFfsHeader == NULL) {\r
- return MaxSize;\r
- }\r
-\r
- FfsSize = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) PadFfsHeader);\r
- HeaderSize = GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) PadFfsHeader);\r
-\r
- for (Count = HeaderSize; Count < FfsSize; Count++) {\r
- if (((((INT8 *)PadFfsHeader)[Count]) & 0xFF) == 0xFF) {\r
- Index++;\r
- } else {\r
- if (Index > MaxSize) {\r
- MaxSize = Index;\r
- }\r
- Index = 0;\r
- }\r
- }\r
- return MaxSize;\r
-}\r
-\r
-\r
-/**\r
-\r
- Get the Offset and data of PAD FFS file in FV file.\r
- This function should be only called for find an PAD FFS contain additional data\r
- (usually will contain FIT table data or reset vector.)\r
-\r
- BFV:\r
- ---------------------- <- Low\r
- | |\r
- | |\r
- -----------------------\r
- | FFSs ... |\r
- -----------------------\r
- | |\r
- | |\r
- -----------------------\r
- | PAD FFS file |\r
- | |\r
- | reset vector |\r
- | |\r
- | FIT table |\r
- -----------------------\r
- | SEC CORE | <- High\r
- -----------------------\r
-\r
-**/\r
-\r
-EFI_STATUS\r
-LibFindResetVectorAndFitTableData(\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
- IN EFI_FFS_FILE_HEADER2 *CurrentFile,\r
- IN OUT FV_INFORMATION *CurrentFv\r
-)\r
-{\r
- UINT32 Count1;\r
- UINT32 Count2;\r
- UINT32 FfsFileSize;\r
- BOOLEAN FfsFoundFlag;\r
- UINT32 FfsOffset;\r
- UINT32 DataOffset;\r
- UINT32 HeaderSize;\r
- PATCH_DATA_PAD_FFS *LocalPatchData;\r
-\r
- FfsFileSize = 0;\r
- Count1 = 0;\r
- Count2 = 0;\r
- FfsOffset = 0;\r
- DataOffset = 0;\r
- FfsFoundFlag = FALSE;\r
- LocalPatchData = NULL;\r
-\r
- if (CurrentFv == NULL || CurrentFile == NULL || FvImage == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- FfsFileSize = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
- HeaderSize = GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
-\r
- for (Count1=0; Count1 < (FvImage->FvLength - FfsFileSize); Count1 ++) {\r
- for (Count2=0; Count2 < FfsFileSize; Count2 ++) {\r
- if (((INT8*)FvImage)[Count1 + Count2] != ((INT8 *) CurrentFile)[Count2]){\r
- break;\r
- }\r
- }\r
- if (Count2 == FfsFileSize) {\r
- FfsFoundFlag = TRUE;\r
- FfsOffset = Count1;\r
- break;\r
- }\r
- }\r
-\r
- if (FfsFoundFlag) {\r
- //\r
- // Find data in FFS file;\r
- // Will skip FFS header;\r
- //\r
- for (Count1 = HeaderSize; Count1 < FfsFileSize; Count1++) {\r
- if (((((INT8 *)CurrentFile)[Count1]) & 0xFF) != 0xFF) {\r
- DataOffset = FfsOffset + Count1;\r
- break;\r
- }\r
- }\r
-\r
- if (CurrentFv->PatchData == NULL) {\r
- //\r
- // First time found data.\r
- //\r
- CurrentFv->PatchData = (PATCH_DATA_PAD_FFS *) malloc (sizeof (PATCH_DATA_PAD_FFS));\r
- if (CurrentFv->PatchData == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- CurrentFv->PatchData->Offset = DataOffset;\r
- CurrentFv->PatchData->Data = malloc(FfsFileSize - Count1);\r
- CurrentFv->PatchData->Length = FfsFileSize - Count1;\r
- CurrentFv->PatchData->NextNode = NULL;\r
-\r
- if (CurrentFv->PatchData->Data == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- memcpy (CurrentFv->PatchData->Data, (INT8 *)CurrentFile + Count1, FfsFileSize - Count1);\r
- } else {\r
- LocalPatchData = CurrentFv->PatchData;\r
-\r
- while (LocalPatchData->NextNode != NULL) {\r
- LocalPatchData = LocalPatchData->NextNode;\r
- }\r
-\r
- LocalPatchData = (PATCH_DATA_PAD_FFS *) malloc (sizeof (PATCH_DATA_PAD_FFS));\r
-\r
- if (LocalPatchData == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalPatchData->Offset = DataOffset;\r
- LocalPatchData->Data = malloc(FfsFileSize - Count1);\r
- LocalPatchData->Length = FfsFileSize - Count1;\r
- LocalPatchData->NextNode = NULL;\r
-\r
- if (LocalPatchData->Data == NULL) {\r
- free (LocalPatchData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- memcpy (LocalPatchData->Data, (INT8 *)CurrentFile + Count1, FfsFileSize - Count1);\r
- while (CurrentFv->PatchData->NextNode != NULL) {\r
- CurrentFv->PatchData = CurrentFv->PatchData->NextNode;\r
- }\r
- CurrentFv->PatchData->NextNode = LocalPatchData;\r
- }\r
-\r
- } else {\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/*\r
- Construct a set of blank chars based on the number.\r
-\r
- @param[in] Count The number of blank chars.\r
-\r
- @return A string contained the blank chars.\r
-\r
-*/\r
-CHAR8 *\r
-LibConstructBlankChar (\r
- IN UINT8 Count\r
-)\r
-{\r
- CHAR8 *RetStr;\r
- UINT8 Index;\r
-\r
- Index = 0;\r
- RetStr = NULL;\r
-\r
- RetStr = (CHAR8 *) malloc (Count +1);\r
-\r
- if (NULL == RetStr) {\r
- return NULL;\r
- }\r
-\r
- memset (RetStr , '\0', Count + 1);\r
-\r
- for (Index=0; Index <= Count -1; Index ++) {\r
- RetStr[Index] = ' ';\r
- }\r
-\r
- return RetStr;\r
-\r
-}\r
-\r
-VOID\r
-Unicode2AsciiString (\r
- IN CHAR16 *Source,\r
- OUT CHAR8 *Destination\r
- )\r
- /*++\r
-\r
- Routine Description:\r
-\r
- Convert a null-terminated unicode string to a null-terminated ascii string.\r
-\r
- Arguments:\r
-\r
- Source - The pointer to the null-terminated input unicode string.\r
- Destination - The pointer to the null-terminated output ascii string.\r
-\r
- Returns:\r
-\r
- N/A\r
-\r
- --*/\r
-{\r
- while (*Source != '\0') {\r
- *(Destination++) = (CHAR8) *(Source++);\r
- }\r
- //\r
- // End the ascii with a NULL.\r
- //\r
- *Destination = '\0';\r
-}\r
-\r
-\r
-/**\r
-\r
- Parses EFI Sections, if the view flag turn on, then will collect FFS section information\r
- and extract FFS files.\r
-\r
- @param[in] SectionBuffer - Buffer containing the section to parse.\r
- @param[in] BufferLength - Length of SectionBuffer\r
- @param[in, out] CurrentFv\r
- @param[in] FvName\r
- @param[in] CurrentFile\r
- @param[in] Level\r
- @param[in, out] FfsCount\r
- @param[in] ViewFlag\r
- @param[in] ErasePolarity\r
-\r
- @retval EFI_SECTION_ERROR - Problem with section parsing.\r
- (a) compression errors\r
- (b) unrecognized section\r
- @retval EFI_UNSUPPORTED - Do not know how to parse the section.\r
- @retval EFI_SUCCESS - Section successfully parsed.\r
- @retval EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
-\r
---*/\r
-EFI_STATUS\r
-LibParseSection (\r
- UINT8 *SectionBuffer,\r
- UINT32 BufferLength,\r
- FV_INFORMATION *CurrentFv,\r
- CHAR8 *FvName,\r
- EFI_FFS_FILE_HEADER2 *CurrentFile,\r
- UINT8 Level,\r
- UINT32 *FfsCount,\r
- BOOLEAN ViewFlag,\r
- BOOLEAN ErasePolarity,\r
- BOOLEAN FfsGeneratedFlag\r
- )\r
-{\r
- UINT32 ParsedLength;\r
- UINT8 *Ptr;\r
- UINT32 SectionLength;\r
- UINT32 UiSectionLength;\r
- EFI_SECTION_TYPE Type;\r
- EFI_STATUS Status;\r
- CHAR8 *ExtractionTool;\r
- CHAR8 *ToolInputFile;\r
- CHAR8 *ToolOutputFile;\r
- CHAR8 *SystemCommand;\r
- UINT8 *ToolOutputBuffer;\r
- UINT32 ToolOutputLength;\r
- CHAR16 *UIName;\r
- UINT32 UINameSize;\r
- BOOLEAN HasDepexSection;\r
- UINT32 NumberOfSections;\r
- BOOLEAN IsFfsGenerated;\r
- ENCAP_INFO_DATA *LocalEncapData;\r
- CHAR8 *BlankChar;\r
- UINT8 *UncompressedBuffer;\r
- UINT32 UncompressedLength;\r
- UINT8 *CompressedBuffer;\r
- UINT32 CompressedLength;\r
- UINT8 CompressionType;\r
- DECOMPRESS_FUNCTION DecompressFunction;\r
- GETINFO_FUNCTION GetInfoFunction;\r
- UINT32 DstSize;\r
- UINT32 ScratchSize;\r
- UINT8 *ScratchBuffer;\r
- BOOLEAN EncapDataNeedUpdata;\r
- CHAR8 *TempDir;\r
- CHAR8 *ToolInputFileFullName;\r
- CHAR8 *ToolOutputFileFullName;\r
- UINT8 LargeHeaderOffset;\r
- CHAR8 *UIFileName;\r
- CHAR8 *ToolInputFileName;\r
- CHAR8 *ToolOutputFileName;\r
-\r
- ParsedLength = 0;\r
- ToolOutputLength = 0;\r
- UINameSize = 0;\r
- NumberOfSections = 0;\r
- UncompressedLength = 0;\r
- CompressedLength = 0;\r
- CompressionType = 0;\r
- DstSize = 0;\r
- ScratchSize = 0;\r
- Ptr = NULL;\r
- ExtractionTool = NULL;\r
- ToolInputFile = NULL;\r
- ToolOutputFile = NULL;\r
- SystemCommand = NULL;\r
- ToolOutputBuffer = NULL;\r
- UIName = NULL;\r
- LocalEncapData = NULL;\r
- BlankChar = NULL;\r
- UncompressedBuffer = NULL;\r
- CompressedBuffer = NULL;\r
- ScratchBuffer = NULL;\r
- TempDir = NULL;\r
- ToolInputFileFullName = NULL;\r
- ToolOutputFileFullName = NULL;\r
- ToolInputFileName = NULL;\r
- ToolOutputFileName = NULL;\r
- HasDepexSection = FALSE;\r
- IsFfsGenerated = FfsGeneratedFlag;\r
- EncapDataNeedUpdata = TRUE;\r
- LargeHeaderOffset = 0;\r
-\r
-\r
- while (ParsedLength < BufferLength) {\r
- Ptr = SectionBuffer + ParsedLength;\r
-\r
- SectionLength = FvBufExpand3ByteSize (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
- Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
-\r
- //\r
- // This is sort of an odd check, but is necessary because FFS files are\r
- // padded to a QWORD boundary, meaning there is potentially a whole section\r
- // header worth of 0xFF bytes.\r
- //\r
- if (SectionLength == 0xffffff && Type == 0xff) {\r
- ParsedLength += 4;\r
- continue;\r
- }\r
- //\r
- //If Size is 0xFFFFFF then ExtendedSize contains the size of the section.\r
- //\r
- if (SectionLength == 0xffffff) {\r
- SectionLength = ((EFI_COMMON_SECTION_HEADER2 *) Ptr)->ExtendedSize;\r
- LargeHeaderOffset = sizeof (EFI_COMMON_SECTION_HEADER2) - sizeof (EFI_COMMON_SECTION_HEADER);\r
- }\r
-\r
- switch (Type) {\r
-\r
- case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
- EncapDataNeedUpdata = TRUE;\r
-\r
- Level ++;\r
- NumberOfSections ++;\r
-\r
- CurrentFv->FfsAttuibutes[*FfsCount].IsLeaf = FALSE;\r
-\r
- //\r
- // Put in encapsulate data information.\r
- //\r
- LocalEncapData = CurrentFv->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == Level) {\r
- EncapDataNeedUpdata = FALSE;\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- if (EncapDataNeedUpdata) {\r
- //\r
- // Put in this is an FFS with FV section\r
- //\r
- LocalEncapData = CurrentFv->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- //\r
- // Construct the new ENCAP_DATA\r
- //\r
- LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));\r
-\r
- if (LocalEncapData->NextNode == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalEncapData = LocalEncapData->NextNode;\r
-\r
- LocalEncapData->Level = Level;\r
- LocalEncapData->Type = BFM_ENCAP_TREE_FV_SECTION;\r
-\r
- //\r
- // We don't need additional data for encapsulate this FFS but type.\r
- //\r
- LocalEncapData->Data = NULL;\r
- LocalEncapData->FvExtHeader = NULL;\r
- LocalEncapData->NextNode = NULL;\r
- }\r
-\r
- Status = LibGetFvInfo ((UINT8*)((EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)Ptr + 1) + LargeHeaderOffset, CurrentFv, FvName, Level, FfsCount, ViewFlag, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_SECTION_ERROR;\r
- }\r
- break;\r
-\r
- case EFI_SECTION_COMPRESSION:\r
- Level ++;\r
- NumberOfSections ++;\r
-\r
- EncapDataNeedUpdata = TRUE;\r
- //\r
- // Put in encapsulate data information.\r
- //\r
- LocalEncapData = CurrentFv->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == Level) {\r
- EncapDataNeedUpdata = FALSE;\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- if (EncapDataNeedUpdata) {\r
- //\r
- // Put in this is an FFS with FV section\r
- //\r
- LocalEncapData = CurrentFv->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- //\r
- // Construct the new ENCAP_DATA\r
- //\r
- LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));\r
-\r
- if (LocalEncapData->NextNode == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalEncapData = LocalEncapData->NextNode;\r
-\r
- LocalEncapData->Level = Level;\r
- LocalEncapData->Type = BFM_ENCAP_TREE_COMPRESS_SECTION;\r
-\r
- //\r
- // Store the compress type\r
- //\r
- LocalEncapData->Data = malloc (sizeof (UINT8));\r
-\r
- if (LocalEncapData->Data == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- *(UINT8 *)LocalEncapData->Data = ((EFI_COMPRESSION_SECTION *) (Ptr + LargeHeaderOffset))->CompressionType;\r
- LocalEncapData->FvExtHeader = NULL;\r
- LocalEncapData->NextNode = NULL;\r
- }\r
-\r
- //\r
- // Process compressed section\r
- //\r
- CurrentFv->FfsAttuibutes[*FfsCount].IsLeaf = FALSE;\r
-\r
- UncompressedBuffer = NULL;\r
- CompressedLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION) - LargeHeaderOffset;\r
- UncompressedLength = ((EFI_COMPRESSION_SECTION *) (Ptr + LargeHeaderOffset))->UncompressedLength;\r
- CompressionType = ((EFI_COMPRESSION_SECTION *) (Ptr + LargeHeaderOffset))->CompressionType;\r
-\r
- if (CompressionType == EFI_NOT_COMPRESSED) {\r
-\r
- if (CompressedLength != UncompressedLength) {\r
- printf ("Error. File is not compressed, but the compressed length does not match the uncompressed length.\n");\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION) + LargeHeaderOffset;\r
- } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
- GetInfoFunction = EfiGetInfo;\r
- DecompressFunction = EfiDecompress;\r
-\r
- CompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION) + LargeHeaderOffset;\r
-\r
- Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- if (DstSize != UncompressedLength) {\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- ScratchBuffer = malloc (ScratchSize);\r
- if (ScratchBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UncompressedBuffer = malloc (UncompressedLength);\r
-\r
- if (UncompressedBuffer == NULL) {\r
- free (ScratchBuffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Decompress the section.\r
- //\r
- Status = DecompressFunction (\r
- CompressedBuffer,\r
- CompressedLength,\r
- UncompressedBuffer,\r
- UncompressedLength,\r
- ScratchBuffer,\r
- ScratchSize\r
- );\r
- free (ScratchBuffer);\r
- if (EFI_ERROR (Status)) {\r
- free (UncompressedBuffer);\r
- return EFI_SECTION_ERROR;\r
- }\r
- } else {\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- Status = LibParseSection ( UncompressedBuffer,\r
- UncompressedLength,\r
- CurrentFv,\r
- FvName,\r
- CurrentFile,\r
- Level,\r
- FfsCount,\r
- ViewFlag,\r
- ErasePolarity,\r
- IsFfsGenerated);\r
-\r
- if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
- //\r
- // We need to deallocate Buffer\r
- //\r
- free (UncompressedBuffer);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- break;\r
-\r
- case EFI_SECTION_GUID_DEFINED:\r
- //\r
- // Process GUID defined\r
- // looks up the appropriate tool to use for extracting\r
- // a GUID defined FV section.\r
- //\r
- Level ++;\r
- NumberOfSections++;\r
-\r
- EncapDataNeedUpdata = TRUE;\r
- //\r
- // Put in encapsulate data information.\r
- //\r
- LocalEncapData = CurrentFv->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == Level) {\r
- EncapDataNeedUpdata = FALSE;\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
- if (EncapDataNeedUpdata) {\r
-\r
- //\r
- // Put in this is an FFS with FV section\r
- //\r
- LocalEncapData = CurrentFv->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- //\r
- // Construct the new ENCAP_DATA\r
- //\r
- LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));\r
-\r
- if (LocalEncapData->NextNode == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalEncapData = LocalEncapData->NextNode;\r
-\r
- LocalEncapData->Level = Level;\r
- LocalEncapData->Type = BFM_ENCAP_TREE_GUIDED_SECTION;\r
-\r
- //\r
- // We don't need additional data for encapsulate this FFS but type.\r
- //\r
-\r
- LocalEncapData->Data = (EFI_GUID *) malloc (sizeof (EFI_GUID));\r
-\r
- if (LocalEncapData->Data == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- memcpy (LocalEncapData->Data, &((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->SectionDefinitionGuid, sizeof (EFI_GUID));\r
-\r
- LocalEncapData->FvExtHeader = NULL;\r
- LocalEncapData->NextNode = NULL;\r
- }\r
-\r
- CurrentFv->FfsAttuibutes[*FfsCount].IsLeaf = FALSE;\r
-\r
- ExtractionTool =\r
- LookupGuidedSectionToolPath (\r
- mParsedGuidedSectionTools,\r
- &((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->SectionDefinitionGuid\r
- );\r
-\r
- if ((((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
- //\r
- // Not require process, directly gets data.\r
- //\r
- Status = LibParseSection (\r
- Ptr + ((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->DataOffset,\r
- SectionLength - ((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->DataOffset,\r
- CurrentFv,\r
- FvName,\r
- CurrentFile,\r
- Level,\r
- FfsCount,\r
- ViewFlag,\r
- ErasePolarity,\r
- IsFfsGenerated\r
- );\r
- if (ExtractionTool != NULL) {\r
- free (ExtractionTool);\r
- ExtractionTool = NULL;\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return EFI_SECTION_ERROR;\r
- }\r
- } else if (ExtractionTool != NULL) {\r
-\r
- TempDir = getcwd (NULL, _MAX_PATH);\r
- if (strlen (TempDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- free (ExtractionTool);\r
- return EFI_ABORTED;\r
- }\r
- strncat (TempDir, OS_SEP_STR, _MAX_PATH - strlen (TempDir) - 1);\r
- strncat (TempDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TempDir) - 1);\r
- mkdir(TempDir, S_IRWXU | S_IRWXG | S_IRWXO);\r
-\r
- ToolInputFile = GenTempFile ();\r
- ToolOutputFile = GenTempFile ();\r
- ToolInputFileName = strrchr(ToolInputFile, OS_SEP);\r
- ToolOutputFileName = strrchr(ToolOutputFile, OS_SEP);\r
-\r
- ToolInputFileFullName = malloc (strlen("%s%s") + strlen(TempDir) + strlen(ToolInputFileName) + 1);\r
- if (ToolInputFileFullName == NULL) {\r
- free (ExtractionTool);\r
- free (ToolInputFile);\r
- free (ToolOutputFile);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- ToolOutputFileFullName = malloc (strlen("%s%s") + strlen(TempDir) + strlen(ToolOutputFileName) + 1);\r
- if (ToolOutputFileFullName == NULL) {\r
- free (ToolInputFileFullName);\r
- free (ExtractionTool);\r
- free (ToolInputFile);\r
- free (ToolOutputFile);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- sprintf (ToolInputFileFullName, "%s%s", TempDir, ToolInputFileName);\r
- sprintf (ToolOutputFileFullName, "%s%s", TempDir, ToolOutputFileName);\r
-\r
- //\r
- // Construction 'system' command string\r
- //\r
- SystemCommand = malloc (\r
- strlen (DECODE_STR) +\r
- strlen (ExtractionTool) +\r
- strlen (ToolInputFileFullName) +\r
- strlen (ToolOutputFileFullName) +\r
- 1\r
- );\r
- if (SystemCommand == NULL) {\r
- free (ToolInputFile);\r
- free (ToolOutputFile);\r
- free (ToolInputFileFullName);\r
- free (ToolOutputFileFullName);\r
- free (ExtractionTool);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- DECODE_STR,\r
- ExtractionTool,\r
- ToolOutputFileFullName,\r
- ToolInputFileFullName\r
- );\r
-\r
- Status = PutFileImage (\r
- ToolInputFileFullName,\r
- (CHAR8*) Ptr + ((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->DataOffset,\r
- SectionLength - ((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->DataOffset\r
- );\r
-\r
- if (HasDepexSection) {\r
- HasDepexSection = FALSE;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- free(SystemCommand);\r
- free (ToolOutputFileFullName);\r
- free (ToolOutputFile);\r
- remove (ToolInputFileFullName);\r
- free (ToolInputFile);\r
- free (ToolInputFileFullName);\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- SystemCommand = malloc (\r
- strlen (DECODE_STR_ERR) +\r
- strlen (ExtractionTool) +\r
- strlen (ToolInputFileFullName) +\r
- strlen (ToolOutputFileFullName) +\r
- 1\r
- );\r
- if (SystemCommand == NULL) {\r
- free (ExtractionTool);\r
- LibRmDir (TempDir);\r
- remove (ToolInputFileFullName);\r
- free (ToolInputFile);\r
- free (ToolInputFileFullName);\r
- free (ToolOutputFileFullName);\r
- free (ToolOutputFile);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- DECODE_STR_ERR,\r
- ExtractionTool,\r
- ToolOutputFileFullName,\r
- ToolInputFileFullName\r
- );\r
- system (SystemCommand);\r
- printf("Command failed: %s\n", SystemCommand);\r
- free (ExtractionTool);\r
- ExtractionTool = NULL;\r
- LibRmDir (TempDir);\r
- free(SystemCommand);\r
- remove (ToolInputFileFullName);\r
- free (ToolInputFile);\r
- free (ToolInputFileFullName);\r
- free (ToolOutputFileFullName);\r
- free (ToolOutputFile);\r
- return EFI_ABORTED;\r
- }\r
- free (ExtractionTool);\r
- ExtractionTool = NULL;\r
- free (SystemCommand);\r
- remove (ToolInputFileFullName);\r
- free (ToolInputFile);\r
- free (ToolInputFileFullName);\r
- ToolInputFile = NULL;\r
- ToolInputFileFullName = NULL;\r
-\r
-\r
- Status = GetFileImage (\r
- ToolOutputFileFullName,\r
- (CHAR8 **)&ToolOutputBuffer,\r
- &ToolOutputLength\r
- );\r
- remove (ToolOutputFileFullName);\r
- free (ToolOutputFile);\r
- free (ToolOutputFileFullName);\r
- ToolOutputFile = NULL;\r
- ToolOutputFileFullName = NULL;\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- Status = LibParseSection (\r
- ToolOutputBuffer,\r
- ToolOutputLength,\r
- CurrentFv,\r
- FvName,\r
- CurrentFile,\r
- Level,\r
- FfsCount,\r
- ViewFlag,\r
- ErasePolarity,\r
- IsFfsGenerated\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_SECTION_ERROR;\r
- }\r
- } else {\r
- //\r
- // We don't know how to parse it now.\r
- //\r
- if (ExtractionTool != NULL) {\r
- free (ExtractionTool);\r
- ExtractionTool = NULL;\r
- }\r
- printf(" EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in %s file.\n", mGuidToolDefinition);\r
- printf(" Its GUID is: ");\r
- PrintGuid(&(((EFI_GUID_DEFINED_SECTION *)(Ptr + LargeHeaderOffset))->SectionDefinitionGuid));\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- break;\r
-\r
- //\r
- //Leaf sections\r
- //\r
- case EFI_SECTION_RAW:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- if (!ViewFlag) {\r
- if (!IsFfsGenerated) {\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- IsFfsGenerated = TRUE;\r
- }\r
- }\r
-\r
- break;\r
- case EFI_SECTION_PE32:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- if (!ViewFlag) {\r
- if (!IsFfsGenerated) {\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- IsFfsGenerated = TRUE;\r
- }\r
- }\r
-\r
- break;\r
- case EFI_SECTION_PIC:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- if (!ViewFlag) {\r
- if (!IsFfsGenerated) {\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- IsFfsGenerated = TRUE;\r
- }\r
- }\r
-\r
- break;\r
- case EFI_SECTION_TE:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- if (!ViewFlag) {\r
- if (!IsFfsGenerated) {\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- IsFfsGenerated = TRUE;\r
- }\r
- }\r
- break;\r
-\r
- case EFI_SECTION_COMPATIBILITY16:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
-\r
- if (!ViewFlag) {\r
- if (!IsFfsGenerated) {\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- IsFfsGenerated = TRUE;\r
- }\r
- }\r
- break;\r
-\r
- case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- if (!ViewFlag) {\r
- if (!IsFfsGenerated) {\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- IsFfsGenerated = TRUE;\r
- }\r
- }\r
- break;\r
-\r
- case EFI_SECTION_VERSION:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- break;\r
- case EFI_SECTION_PEI_DEPEX:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- HasDepexSection = TRUE;\r
- break;\r
- case EFI_SECTION_DXE_DEPEX:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- HasDepexSection = TRUE;\r
- break;\r
- case EFI_SECTION_SMM_DEPEX:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- HasDepexSection = TRUE;\r
- break;\r
-\r
- case EFI_SECTION_USER_INTERFACE:\r
- NumberOfSections ++;\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
-\r
- UiSectionLength = FvBufExpand3ByteSize (((EFI_USER_INTERFACE_SECTION *) Ptr)->CommonHeader.Size);\r
- if (UiSectionLength == 0xffffff) {\r
- UiSectionLength = ((EFI_USER_INTERFACE_SECTION2 *) Ptr)->CommonHeader.ExtendedSize;\r
- UINameSize = UiSectionLength - sizeof(EFI_COMMON_SECTION_HEADER2);\r
- } else {\r
- UINameSize = UiSectionLength - sizeof(EFI_COMMON_SECTION_HEADER);\r
- }\r
-\r
- UIName = (CHAR16 *) malloc (UINameSize + 2);\r
- if (UIName != NULL) {\r
- memset (UIName, '\0', UINameSize + 2);\r
- if (UiSectionLength >= 0xffffff) {\r
- memcpy(UIName, ((EFI_USER_INTERFACE_SECTION2 *) Ptr)->FileNameString, UINameSize);\r
- } else {\r
- memcpy(UIName, ((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UINameSize);\r
- }\r
- } else {\r
- return EFI_ABORTED;\r
- }\r
-\r
- BlankChar = LibConstructBlankChar( CurrentFv->FvLevel * 2);\r
- if (BlankChar == NULL) {\r
- free (UIName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (ViewFlag) {\r
- UIFileName = malloc (UINameSize + 2);\r
- if (UIFileName == NULL) {\r
- free(BlankChar);\r
- free(UIName);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- Unicode2AsciiString (UIName, UIFileName);\r
- fprintf(stdout, "%sFile \"%s\"\n", BlankChar, UIFileName);\r
- free(UIFileName);\r
- }\r
-\r
- free (BlankChar);\r
- BlankChar = NULL;\r
-\r
- //\r
- // If Ffs file has been generated, then the FfsCount should decrease 1.\r
- //\r
- if (IsFfsGenerated) {\r
- memcpy (CurrentFv->FfsAttuibutes[*FfsCount -1].UiName, UIName, UINameSize);\r
- } else {\r
- memcpy (CurrentFv->FfsAttuibutes[*FfsCount].UiName, UIName, UINameSize);\r
- }\r
- HasDepexSection = FALSE;\r
- free(UIName);\r
- UINameSize = 0;\r
-\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- ParsedLength += SectionLength;\r
- //\r
- // We make then next section begin on a 4-byte boundary\r
- //\r
- ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
- }\r
-\r
- if (ParsedLength < BufferLength) {\r
- return EFI_SECTION_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
- Add function description\r
-\r
- FvImage - add argument description\r
- FileHeader - add argument description\r
- ErasePolarity - add argument description\r
-\r
- EFI_SUCCESS - Add description for return value\r
- EFI_ABORTED - Add description for return value\r
-\r
-**/\r
-EFI_STATUS\r
-LibGetFileInfo (\r
- EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
- EFI_FFS_FILE_HEADER2 *CurrentFile,\r
- BOOLEAN ErasePolarity,\r
- FV_INFORMATION *CurrentFv,\r
- CHAR8 *FvName,\r
- UINT8 Level,\r
- UINT32 *FfsCount,\r
- BOOLEAN ViewFlag\r
- )\r
-{\r
- UINT32 FileLength;\r
- UINT8 FileState;\r
- UINT8 Checksum;\r
- EFI_FFS_FILE_HEADER2 BlankHeader;\r
- EFI_STATUS Status;\r
- ENCAP_INFO_DATA *LocalEncapData;\r
- BOOLEAN EncapDataNeedUpdateFlag;\r
- UINT32 FfsFileHeaderSize;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- LocalEncapData = NULL;\r
- EncapDataNeedUpdateFlag = TRUE;\r
-\r
- FfsFileHeaderSize = GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
- FileLength = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) CurrentFile);\r
-\r
- //\r
- // Check if we have free space\r
- //\r
- if (ErasePolarity) {\r
- memset (&BlankHeader, -1, FfsFileHeaderSize);\r
- } else {\r
- memset (&BlankHeader, 0, FfsFileHeaderSize);\r
- }\r
-\r
- //\r
- // Is this FV blank?\r
- //\r
- if (memcmp (&BlankHeader, CurrentFile, FfsFileHeaderSize) == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Print file information.\r
- //\r
- FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER *)CurrentFile);\r
-\r
- if (FileState == EFI_FILE_DATA_VALID) {\r
- //\r
- // Calculate header checksum\r
- //\r
- Checksum = CalculateSum8 ((UINT8 *) CurrentFile, FfsFileHeaderSize);\r
- Checksum = (UINT8) (Checksum - CurrentFile->IntegrityCheck.Checksum.File);\r
- Checksum = (UINT8) (Checksum - CurrentFile->State);\r
- if (Checksum != 0) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (CurrentFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
- //\r
- // Calculate file checksum\r
- //\r
- Checksum = CalculateSum8 ((UINT8 *) ((UINTN)CurrentFile + FfsFileHeaderSize), FileLength - FfsFileHeaderSize);\r
- Checksum = Checksum + CurrentFile->IntegrityCheck.Checksum.File;\r
- if (Checksum != 0) {\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- if (CurrentFile->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- } else {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Level += 1;\r
-\r
- if (CurrentFile->Type != EFI_FV_FILETYPE_ALL) {\r
-\r
- //\r
- // Put in encapsulate data information.\r
- //\r
- LocalEncapData = CurrentFv->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == Level) {\r
- EncapDataNeedUpdateFlag = FALSE;\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- if (EncapDataNeedUpdateFlag) {\r
- //\r
- // Construct the new ENCAP_DATA\r
- //\r
- LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));\r
-\r
- if (LocalEncapData->NextNode == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalEncapData = LocalEncapData->NextNode;\r
-\r
- LocalEncapData->Level = Level;\r
- LocalEncapData->Type = BFM_ENCAP_TREE_FFS;\r
- LocalEncapData->FvExtHeader = NULL;\r
-\r
- //\r
- // Store the header of FFS file.\r
- //\r
- LocalEncapData->Data = malloc (FfsFileHeaderSize);\r
- if (LocalEncapData->Data == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- memcpy (LocalEncapData->Data, CurrentFile, FfsFileHeaderSize);\r
-\r
- LocalEncapData->NextNode = NULL;\r
- }\r
-\r
- if ( CurrentFile->Type == EFI_FV_FILETYPE_FREEFORM ){\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- if (!ViewFlag) {\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- }\r
- }else if ( CurrentFile->Type == EFI_FV_FILETYPE_RAW){\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- if (!ViewFlag){\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- }\r
- } else if ( CurrentFile->Type == EFI_FV_FILETYPE_SECURITY_CORE){\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- //\r
- // If an FV contain SECCORE, this FV will be considered as BFV.\r
- //\r
- CurrentFv->IsBfvFlag = TRUE;\r
- if (!ViewFlag){\r
- LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- }\r
- } else if( CurrentFile->Type == EFI_FV_FILETYPE_FFS_PAD){\r
- //\r
- // First check whether the FFS file contain FvExtended FvNameGuid information.\r
- //\r
- if (!LibCheckPadFfsContainFvNameGuid (CurrentFv, CurrentFile)) {\r
- //\r
- // Then check whether the PAD file have no additional data or not.\r
- //\r
- if (LibCheckPadFfsNotNull (CurrentFile)) {\r
- CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;\r
- //\r
- // Get the size of PAD in BFV\r
- //\r
- PadSizeOfBfv = GetBfvMaxFreeSpace (CurrentFile);\r
- if (!ViewFlag){\r
- //\r
- //LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);\r
- //\r
- Status = LibFindResetVectorAndFitTableData (FvImage, CurrentFile, CurrentFv);\r
- if (EFI_ERROR (Status)) {\r
- printf ("Find reset vector and FIT table data failed. \n");\r
- return EFI_ABORTED;\r
- }\r
- }\r
- }\r
- }\r
- } else {\r
- //\r
- // All other files have sections\r
- //\r
- Status = LibParseSection (\r
- (UINT8 *) ((UINTN) CurrentFile + FfsFileHeaderSize),\r
- FileLength - FfsFileHeaderSize,\r
- CurrentFv,\r
- FvName,\r
- CurrentFile,\r
- Level,\r
- FfsCount,\r
- ViewFlag,\r
- ErasePolarity,\r
- FALSE\r
- );\r
- }\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while parse the FFS file.\n");\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
- Get firmware information. Including the FV headers,\r
-\r
- @param[in] Fv - Firmware Volume to get information from\r
-\r
- @return EFI_STATUS\r
-\r
-**/\r
-EFI_STATUS\r
-LibGetFvInfo (\r
- IN VOID *Fv,\r
- IN OUT FV_INFORMATION *CurrentFv,\r
- IN CHAR8 *FvName,\r
- IN UINT8 Level,\r
- IN UINT32 *FfsCount,\r
- IN BOOLEAN ViewFlag,\r
- IN BOOLEAN IsChildFv\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN NumberOfFiles;\r
- BOOLEAN ErasePolarity;\r
- UINTN FvSize;\r
- EFI_FFS_FILE_HEADER2 *CurrentFile;\r
- UINTN Key;\r
- ENCAP_INFO_DATA *LocalEncapData;\r
- EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHdrPtr;\r
-\r
- NumberOfFiles = 0;\r
- Key = 0;\r
- LocalEncapData = NULL;\r
- CurrentFile = NULL;\r
-\r
- Level += 1;\r
- CurrentFv->FvLevel += 1;\r
-\r
- Status = FvBufGetSize (Fv, &FvSize);\r
-\r
- ErasePolarity = (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ? TRUE : FALSE;\r
-\r
- if (!IsChildFv) {\r
- //\r
- // Write FV header information into CurrentFv struct.\r
- //\r
- CurrentFv->FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) malloc (sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
-\r
- if (CurrentFv->FvHeader == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Get the FV Header information\r
- //\r
- memcpy (CurrentFv->FvHeader, Fv, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
- CurrentFv->FvExtHeader = NULL;\r
-\r
- //\r
- // Exist Extend FV header.\r
- //\r
- if (CurrentFv->FvHeader->ExtHeaderOffset != 0){\r
- CurrentFv->FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) malloc (sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER));\r
-\r
- if (CurrentFv->FvExtHeader == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Get the FV extended Header information\r
- //\r
- memcpy (CurrentFv->FvExtHeader, (VOID *)((UINTN)Fv + CurrentFv->FvHeader->ExtHeaderOffset), sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER));\r
- if (mFvGuidIsSet) {\r
- if (CompareGuid (&CurrentFv->FvExtHeader->FvName, &mFvNameGuid) == 0) {\r
- CurrentFv->IsInputFvFlag = TRUE;\r
- }\r
- }\r
-\r
- }\r
-\r
- }\r
-\r
- //\r
- // Put encapsulate information into structure.\r
- //\r
- if (CurrentFv->EncapData == NULL && !IsChildFv) {\r
- //\r
- // First time in, the root FV\r
- //\r
- CurrentFv->EncapData = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));\r
-\r
- if (CurrentFv->EncapData == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- CurrentFv->EncapData->FvExtHeader = NULL;\r
- CurrentFv->EncapData->Level = Level;\r
- CurrentFv->EncapData->Type = BFM_ENCAP_TREE_FV;\r
- CurrentFv->EncapData->Data = (EFI_FIRMWARE_VOLUME_HEADER *) malloc (sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
-\r
- if (CurrentFv->EncapData->Data == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- memcpy (CurrentFv->EncapData->Data, Fv, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
-\r
- if (((EFI_FIRMWARE_VOLUME_HEADER *)(CurrentFv->EncapData->Data))->ExtHeaderOffset != 0) {\r
- ExtHdrPtr = (VOID *)((UINTN)Fv + ((EFI_FIRMWARE_VOLUME_HEADER *)(CurrentFv->EncapData->Data))->ExtHeaderOffset);\r
- CurrentFv->EncapData->FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) malloc (ExtHdrPtr->ExtHeaderSize);\r
-\r
- if (CurrentFv->EncapData->FvExtHeader == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Get the FV extended Header information\r
- //\r
- memcpy(CurrentFv->EncapData->FvExtHeader, (VOID *)((UINTN)Fv + ((EFI_FIRMWARE_VOLUME_HEADER *)(CurrentFv->EncapData->Data))->ExtHeaderOffset), ExtHdrPtr->ExtHeaderSize);\r
- if (mFvGuidIsSet) {\r
- if (CompareGuid (&CurrentFv->EncapData->FvExtHeader->FvName, &mFvNameGuid) == 0) {\r
- CurrentFv->IsInputFvFlag = TRUE;\r
- }\r
- }\r
-\r
- }\r
-\r
- CurrentFv->EncapData->NextNode = NULL;\r
-\r
- } else if (CurrentFv->EncapData == NULL) {\r
- return EFI_ABORTED;\r
- } else if (IsChildFv) {\r
-\r
- LocalEncapData = CurrentFv->EncapData;\r
-\r
- while (LocalEncapData->NextNode != NULL) {\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- //\r
- // Construct the new ENCAP_DATA\r
- //\r
- LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));\r
-\r
- if (LocalEncapData->NextNode == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalEncapData = LocalEncapData->NextNode;\r
-\r
- LocalEncapData->Level = Level;\r
- LocalEncapData->Type = BFM_ENCAP_TREE_FV;\r
- LocalEncapData->Data = (EFI_FIRMWARE_VOLUME_HEADER *) malloc (sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
- LocalEncapData->FvExtHeader = NULL;\r
-\r
- if (LocalEncapData->Data == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- memcpy (LocalEncapData->Data, Fv, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
-\r
- if (((EFI_FIRMWARE_VOLUME_HEADER *)(LocalEncapData->Data))->ExtHeaderOffset != 0) {\r
- ExtHdrPtr = (VOID *)((UINTN)Fv + ((EFI_FIRMWARE_VOLUME_HEADER *)(LocalEncapData->Data))->ExtHeaderOffset);\r
- LocalEncapData->FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)malloc(ExtHdrPtr->ExtHeaderSize);\r
-\r
- if (LocalEncapData->FvExtHeader == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Get the FV extended Header information\r
- //\r
- memcpy(LocalEncapData->FvExtHeader, (VOID *)((UINTN)Fv + ((EFI_FIRMWARE_VOLUME_HEADER *)(LocalEncapData->Data))->ExtHeaderOffset), ExtHdrPtr->ExtHeaderSize);\r
- }\r
-\r
- LocalEncapData->NextNode = NULL;\r
-\r
- }\r
-\r
-\r
- //\r
- // Get the first file\r
- //\r
- Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
- if (Status == EFI_NOT_FOUND) {\r
- CurrentFile = NULL;\r
- } else if (EFI_ERROR (Status)) {\r
- printf ("Failed to find the first file from Fv. \n");\r
- return Status;\r
- }\r
-\r
- while (CurrentFile != NULL) {\r
-\r
- //\r
- // Increment the number of files counter\r
- //\r
- NumberOfFiles++;\r
-\r
- //\r
- // Store FFS file Header information\r
- //\r
- CurrentFv->FfsHeader[*FfsCount].Attributes = CurrentFile->Attributes;\r
- CurrentFv->FfsHeader[*FfsCount].IntegrityCheck = CurrentFile->IntegrityCheck;\r
- CurrentFv->FfsHeader[*FfsCount].Name = CurrentFile->Name;\r
- CurrentFv->FfsHeader[*FfsCount].Size[0] = CurrentFile->Size[0];\r
- CurrentFv->FfsHeader[*FfsCount].Size[1] = CurrentFile->Size[1];\r
- CurrentFv->FfsHeader[*FfsCount].Size[2] = CurrentFile->Size[2];\r
- CurrentFv->FfsHeader[*FfsCount].State = CurrentFile->State;\r
- CurrentFv->FfsHeader[*FfsCount].Type = CurrentFile->Type;\r
- CurrentFv->FfsHeader[*FfsCount].ExtendedSize = CurrentFile->ExtendedSize;\r
-\r
- //\r
- // Display info about this file\r
- //\r
- Status = LibGetFileInfo (Fv, CurrentFile, ErasePolarity, CurrentFv, FvName, Level, FfsCount, ViewFlag);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the next file\r
- //\r
- Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
- if (Status == EFI_NOT_FOUND) {\r
- CurrentFile = NULL;\r
- } else if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-LibGenExtFile(\r
- CONST EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtPtr,\r
- FILE *InfFile\r
-)\r
-{\r
- CHAR8 *TempDir;\r
- FILE *ExtFile;\r
- CHAR8 OutputExtFile[_MAX_PATH];\r
- CHAR8 Line[512];\r
- size_t Len;\r
-\r
- TempDir = NULL;\r
-\r
- TempDir = getcwd(NULL, _MAX_PATH);\r
-\r
- if (strlen (TempDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- strncat (TempDir, OS_SEP_STR, _MAX_PATH - strlen (TempDir) - 1);\r
- strncat (TempDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TempDir) - 1);\r
- mkdir(TempDir, S_IRWXU | S_IRWXG | S_IRWXO);\r
-\r
- sprintf(\r
- Line,\r
- "%c%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%d.ext",\r
- OS_SEP,\r
- (unsigned)ExtPtr->FvName.Data1,\r
- ExtPtr->FvName.Data2,\r
- ExtPtr->FvName.Data3,\r
- ExtPtr->FvName.Data4[0],\r
- ExtPtr->FvName.Data4[1],\r
- ExtPtr->FvName.Data4[2],\r
- ExtPtr->FvName.Data4[3],\r
- ExtPtr->FvName.Data4[4],\r
- ExtPtr->FvName.Data4[5],\r
- ExtPtr->FvName.Data4[6],\r
- ExtPtr->FvName.Data4[7],\r
- ExtPtr->ExtHeaderSize\r
- );\r
- if (strlen (TempDir) + strlen (Line) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- return EFI_ABORTED;\r
- }\r
- strncpy (OutputExtFile, TempDir, _MAX_PATH - 1);\r
- OutputExtFile[_MAX_PATH - 1] = 0;\r
- strncat (OutputExtFile, Line, _MAX_PATH - strlen (OutputExtFile) - 1);\r
-\r
-\r
- ExtFile = fopen(OutputExtFile, "wb+");\r
- if (ExtFile == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (fwrite(ExtPtr, 1, ExtPtr->ExtHeaderSize, ExtFile) != ExtPtr->ExtHeaderSize) {\r
- fclose(ExtFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fclose(ExtFile);\r
-\r
- strcpy (Line, "EFI_FV_EXT_HEADER_FILE_NAME = ");\r
- if (strlen (Line) + strlen (OutputExtFile) + 1 > sizeof(Line) / sizeof (CHAR8) - 1) {\r
- printf ("The directory is too long \n");\r
- return EFI_ABORTED;\r
- }\r
- strncat (Line, OutputExtFile, sizeof(Line) / sizeof (CHAR8) - strlen (Line) - 1);\r
- strncat (Line, "\n", sizeof(Line) / sizeof (CHAR8) - strlen (Line) - 1);\r
- Len = strlen(Line);\r
- if (fwrite(Line, 1, Len, InfFile) != Len) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-\r
- This function returns the next larger size that meets the alignment\r
- requirement specified.\r
-\r
- @param[in] ActualSize The size.\r
- @param[in] Alignment The desired alignment.\r
-\r
- @retval EFI_SUCCESS Function completed successfully.\r
- @retval EFI_ABORTED The function encountered an error.\r
-\r
-**/\r
-UINT32\r
-GetOccupiedSize (\r
- IN UINT32 ActualSize,\r
- IN UINT32 Alignment\r
- )\r
-{\r
- UINT32 OccupiedSize;\r
-\r
- OccupiedSize = ActualSize;\r
- while ((OccupiedSize & (Alignment - 1)) != 0) {\r
- OccupiedSize++;\r
- }\r
-\r
- return OccupiedSize;\r
-}\r
-\r
-/**\r
- Converts ASCII characters to Unicode.\r
- Assumes that the Unicode characters are only these defined in the ASCII set.\r
-\r
- String - Pointer to string that is written to FILE.\r
- UniString - Pointer to unicode string\r
-\r
- The address to the ASCII string - same as AsciiStr.\r
-\r
-**/\r
-VOID\r
-LibAscii2Unicode (\r
- IN CHAR8 *String,\r
- OUT CHAR16 *UniString\r
- )\r
-{\r
- while (*String != '\0') {\r
- *(UniString++) = (CHAR16) *(String++);\r
- }\r
- //\r
- // End the UniString with a NULL.\r
- //\r
- *UniString = '\0';\r
-}\r
-\r
-\r
-EFI_STATUS\r
-LibCreateGuidedSectionOriginalData(\r
- IN CHAR8* FileIn,\r
- IN CHAR8* ToolName,\r
- IN CHAR8* FileOut\r
-)\r
-{\r
- CHAR8* SystemCommand;\r
-\r
- SystemCommand = NULL;\r
-\r
- if (FileIn == NULL ||\r
- ToolName == NULL ||\r
- FileOut == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- SystemCommand = malloc (\r
- strlen (ENCODE_STR) +\r
- strlen (FileIn) +\r
- strlen (ToolName) +\r
- strlen (FileOut) +\r
- 1\r
- );\r
-\r
- if (NULL == SystemCommand) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- ENCODE_STR,\r
- ToolName,\r
- FileIn,\r
- FileOut\r
- );\r
-\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- SystemCommand = malloc (\r
- strlen (ENCODE_STR_ERR) +\r
- strlen (FileIn) +\r
- strlen (ToolName) +\r
- strlen (FileOut) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_ABORTED;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- ENCODE_STR_ERR,\r
- ToolName,\r
- FileIn,\r
- FileOut\r
- );\r
- system (SystemCommand);\r
- printf("Command failed: %s\n", SystemCommand);\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
- This function convert the FV header's attribute to a string. The converted string\r
- will be put into an INF file as the input of GenFV.\r
-\r
- @param[in] Attr FV header's attribute.\r
- @param[out] InfFile InfFile contain FV header attribute information.\r
-\r
- @retval EFI_SUCCESS.\r
- @retval EFI_INVLID_PARAMETER\r
- @retval EFI_OUT_OF_RESOURCES\r
-\r
-**/\r
-EFI_STATUS\r
-LibFvHeaderAttributeToStr (\r
- IN EFI_FVB_ATTRIBUTES_2 Attr,\r
- IN FILE* InfFile\r
-)\r
-{\r
- CHAR8 *LocalStr;\r
-\r
- LocalStr = NULL;\r
-\r
- LocalStr = (CHAR8 *) malloc (1024 * 4);\r
-\r
- if (LocalStr == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (LocalStr, '\0', 1024 * 4);\r
-\r
- if (Attr == 0 || InfFile == NULL) {\r
- free (LocalStr);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- strncat (LocalStr, "[attributes] \n", sizeof("[attributes] \n"));\r
-\r
- if (Attr & EFI_FVB2_READ_DISABLED_CAP) {\r
- strncat (LocalStr, "EFI_READ_DISABLED_CAP = TRUE \n", sizeof ("EFI_READ_DISABLED_CAP = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_READ_ENABLED_CAP) {\r
- strncat (LocalStr, "EFI_READ_ENABLED_CAP = TRUE \n", sizeof ("EFI_READ_ENABLED_CAP = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_READ_STATUS) {\r
- strncat (LocalStr, "EFI_READ_STATUS = TRUE \n", sizeof ("EFI_READ_STATUS = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_WRITE_DISABLED_CAP) {\r
- strncat (LocalStr, "EFI_WRITE_DISABLED_CAP = TRUE \n", sizeof ("EFI_WRITE_DISABLED_CAP = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_WRITE_ENABLED_CAP) {\r
- strncat (LocalStr, "EFI_WRITE_ENABLED_CAP = TRUE \n", sizeof ("EFI_WRITE_ENABLED_CAP = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_WRITE_STATUS) {\r
- strncat (LocalStr, "EFI_WRITE_STATUS = TRUE \n", sizeof ("EFI_WRITE_STATUS = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_LOCK_CAP) {\r
- strncat (LocalStr, "EFI_LOCK_CAP = TRUE \n", sizeof ("EFI_LOCK_CAP = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_LOCK_STATUS) {\r
- strncat (LocalStr, "EFI_LOCK_STATUS = TRUE \n", sizeof ("EFI_LOCK_STATUS = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_STICKY_WRITE) {\r
- strncat (LocalStr, "EFI_STICKY_WRITE = TRUE \n", sizeof ("EFI_STICKY_WRITE = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_MEMORY_MAPPED) {\r
- strncat (LocalStr, "EFI_MEMORY_MAPPED = TRUE \n", sizeof ("EFI_MEMORY_MAPPED = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_ERASE_POLARITY) {\r
- strncat (LocalStr, "EFI_ERASE_POLARITY = 1 \n", sizeof ("EFI_ERASE_POLARITY = 1 \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_READ_LOCK_CAP) {\r
- strncat (LocalStr, "EFI_READ_LOCK_CAP = TRUE \n", sizeof ("EFI_READ_LOCK_CAP = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_READ_LOCK_STATUS) {\r
- strncat (LocalStr, "EFI_READ_LOCK_STATUS = TRUE \n", sizeof ("EFI_READ_LOCK_STATUS = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_WRITE_LOCK_CAP) {\r
- strncat (LocalStr, "EFI_WRITE_LOCK_CAP = TRUE \n", sizeof ("EFI_WRITE_LOCK_CAP = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_WRITE_LOCK_STATUS) {\r
- strncat (LocalStr, "EFI_WRITE_LOCK_STATUS = TRUE \n", sizeof ("EFI_WRITE_LOCK_STATUS = TRUE \n"));\r
- }\r
-\r
- if (Attr & EFI_FVB2_LOCK_STATUS) {\r
- strncat (LocalStr, "EFI_READ_LOCK_STATUS = TRUE \n", sizeof ("EFI_READ_LOCK_STATUS = TRUE \n"));\r
- }\r
-\r
- //\r
- // Alignment\r
- //\r
- if (Attr & EFI_FVB2_ALIGNMENT_1) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_1 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_2) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_2 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_4) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_4 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_4 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_8) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_8 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_8 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_16) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_16 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_16 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_32) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_32 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_32 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_64) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_64 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_64 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_128) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_128 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_128 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_256) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_256 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_256 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_512) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_512 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_512 = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_1K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_1K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_2K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_2K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_4K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_4K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_4K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_8K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_8K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_8K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_16K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_16K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_16K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_32K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_32K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_32K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_64K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_64K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_64K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_128K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_128K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_128K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_256K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_256K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_256K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_512K) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_512K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_512K = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_1M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_1M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_2M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_2M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_4M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_4M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_4M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_8M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_8M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_8M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_16M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_16M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_16M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_32M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_32M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_32M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_64M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_64M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_64M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_128M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_128M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_128M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_256M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_256M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_256M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_512M) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_512M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_512M = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_1G) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_1G = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1G = TRUE \n"));\r
- } else if (Attr & EFI_FVB2_ALIGNMENT_2G) {\r
- strncat (LocalStr, "EFI_FVB2_ALIGNMENT_2G = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2G = TRUE \n"));\r
- }\r
-\r
- if (fwrite (LocalStr, 1, (size_t) strlen (LocalStr), InfFile) != (size_t) strlen (LocalStr)) {\r
- printf ("Error while write data to %p file. \n", (void*)InfFile);\r
- free (LocalStr);\r
- return EFI_ABORTED;\r
- }\r
-\r
- free (LocalStr);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- This function fill the FV inf files option field.\r
-\r
- @param[in] BlockMap FV header's attribute.\r
- @param[out] InfFile InfFile contain FV header attribute information.\r
-\r
- @retval EFI_SUCCESS.\r
- @retval EFI_INVLID_PARAMETER\r
-\r
-**/\r
-EFI_STATUS\r
-LibFvHeaderOptionToStr (\r
- IN EFI_FV_BLOCK_MAP_ENTRY *BlockMap,\r
- IN FILE* InfFile,\r
- IN BOOLEAN IsRootFv\r
-)\r
-{\r
- CHAR8 *LocalStr;\r
- CHAR8 *BlockSize;\r
- CHAR8 *NumOfBlocks;\r
-\r
- LocalStr = NULL;\r
- BlockSize = NULL;\r
- NumOfBlocks = NULL;\r
-\r
- if (BlockMap == NULL || InfFile == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // This section will not over 1024 bytes and each line will never over 128 bytes.\r
- //\r
- LocalStr = (CHAR8 *) malloc (1024);\r
- BlockSize = (CHAR8 *) malloc (128);\r
- NumOfBlocks = (CHAR8 *) malloc (128);\r
-\r
- if (LocalStr == NULL ||\r
- BlockSize == NULL ||\r
- NumOfBlocks == NULL) {\r
- if (LocalStr != NULL) {\r
- free (LocalStr);\r
- }\r
- if (BlockSize != NULL) {\r
- free (BlockSize);\r
- }\r
- if (NumOfBlocks != NULL) {\r
- free (NumOfBlocks);\r
- }\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (LocalStr, '\0', 1024);\r
- memset (BlockSize, '\0', 128);\r
- memset (NumOfBlocks, '\0', 128);\r
-\r
- strncat (LocalStr, "[options] \n", sizeof("[Options] \n"));\r
-\r
- sprintf (BlockSize, "EFI_BLOCK_SIZE = 0x%x \n", BlockMap->Length);\r
- strncat (LocalStr, BlockSize, strlen(BlockSize));\r
-\r
- if (IsRootFv) {\r
- sprintf (NumOfBlocks, "EFI_NUM_BLOCKS = 0x%x \n", BlockMap->NumBlocks);\r
- strncat (LocalStr, NumOfBlocks, strlen(NumOfBlocks));\r
- }\r
-\r
- if (fwrite (LocalStr, 1, (size_t) strlen (LocalStr), InfFile) != (size_t) strlen (LocalStr)) {\r
- free (LocalStr);\r
- free (BlockSize);\r
- free (NumOfBlocks);\r
- return EFI_ABORTED;\r
- }\r
-\r
- free (LocalStr);\r
- free (BlockSize);\r
- free (NumOfBlocks);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function fill the FV inf files option field.\r
-\r
- @param[in] FfsName Ffs file path/name.\r
- @param[out] InfFile InfFile contain FV header attribute information\r
- @param[in] FirstIn Is the first time call this function? If yes, should create [files] section.\r
-\r
- @retval EFI_SUCCESS.\r
- @retval EFI_INVLID_PARAMETER\r
-\r
-**/\r
-EFI_STATUS\r
-LibAddFfsFileToFvInf (\r
- IN CHAR8 *FfsName,\r
- IN FILE* InfFile,\r
- IN BOOLEAN FirstIn\r
-)\r
-{\r
-\r
- CHAR8 *LocalStr;\r
-\r
- LocalStr = NULL;\r
-\r
- if (FfsName == NULL || InfFile == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (strlen(FfsName) == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- LocalStr = (CHAR8 *) malloc (_MAX_PATH);\r
-\r
- if (LocalStr == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (LocalStr, '\0', _MAX_PATH);\r
-\r
- if (FirstIn) {\r
- sprintf (LocalStr, "[files] \nEFI_FILE_NAME = %s \n", FfsName);\r
- } else {\r
- sprintf (LocalStr, "EFI_FILE_NAME = %s \n", FfsName);\r
- }\r
-\r
- if (fwrite (LocalStr, 1, (size_t) strlen (LocalStr), InfFile) != (size_t) strlen (LocalStr)) {\r
- printf ("Error while write data to %p file. \n", (void*)InfFile);\r
- free (LocalStr);\r
- return EFI_ABORTED;\r
- }\r
-\r
- free (LocalStr);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Convert EFI file to PE or TE section\r
-\r
- @param[in] InputFilePath .efi file, it's optional unless process PE/TE section.\r
- @param[in] Type PE or TE and UI/Version\r
- @param[in] OutputFilePath .te or .pe file\r
- @param[in] UiString String for generate UI section usage, this parameter is optional\r
- unless Type is EFI_SECTION_USER_INTERFACE.\r
- @param[in] VerString String for generate Version section usage, this parameter is optional\r
- unless Type is EFI_SECTION_VERSION.\r
-\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-LibCreateFfsSection (\r
- IN CHAR8* InputFilePath, OPTIONAL\r
- IN CHAR8* Sections, OPTIONAL\r
- IN UINT8 Type,\r
- IN CHAR8* OutputFilePath,\r
- IN CHAR8* UiString, OPTIONAL\r
- IN CHAR8* VerString, OPTIONAL\r
- IN CHAR8* GuidToolGuid, OPTIONAL\r
- IN CHAR8* CompressType OPTIONAL\r
- )\r
-{\r
- CHAR8* SystemCommand;\r
- SystemCommand = NULL;\r
-\r
- //\r
- // Call GenSec tool to generate FFS section.\r
- //\r
-\r
- //\r
- // -s SectionType.\r
- //\r
- if (Type != 0) {\r
- switch (Type) {\r
- //\r
- // Process compression section\r
- //\r
- case EFI_SECTION_COMPRESSION:\r
- SystemCommand = malloc (\r
- strlen (GENSEC_COMPRESSION) +\r
- strlen (mSectionTypeName[Type]) +\r
- strlen (CompressType) +\r
- strlen (InputFilePath) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENSEC_COMPRESSION,\r
- mSectionTypeName[Type],\r
- CompressType,\r
- InputFilePath,\r
- OutputFilePath\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- break;\r
-\r
- //\r
- // Process GUID defined section\r
- //\r
- case EFI_SECTION_GUID_DEFINED:\r
- SystemCommand = malloc (\r
- strlen (GENSEC_GUID) +\r
- strlen (mSectionTypeName[Type]) +\r
- strlen (GuidToolGuid) +\r
- strlen (InputFilePath) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENSEC_GUID,\r
- mSectionTypeName[Type],\r
- GuidToolGuid,\r
- InputFilePath,\r
- OutputFilePath\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- break;\r
-\r
- case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
- SystemCommand = malloc (\r
- strlen (GENSEC_STR) +\r
- strlen (mSectionTypeName[Type]) +\r
- strlen (InputFilePath) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENSEC_STR,\r
- mSectionTypeName[Type],\r
- InputFilePath,\r
- OutputFilePath\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- break;\r
-\r
- case EFI_SECTION_RAW:\r
- SystemCommand = malloc (\r
- strlen (GENSEC_STR) +\r
- strlen (mSectionTypeName[Type]) +\r
- strlen (InputFilePath) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENSEC_STR,\r
- mSectionTypeName[Type],\r
- InputFilePath,\r
- OutputFilePath\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- break;\r
-\r
- default:\r
- printf ("Please specify the section type while call GenSec tool.\n");\r
- return EFI_UNSUPPORTED;\r
- }\r
- } else {\r
- //\r
- // Create Dummy section.\r
- //\r
- SystemCommand = malloc (\r
- strlen (GENSEC_ALIGN) +\r
- strlen (InputFilePath) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENSEC_ALIGN,\r
- InputFilePath,\r
- OutputFilePath\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Encapsulate FFSs to FV\r
-\r
- @param[in] InputFilePath Section file will be read into this FFS file. This option is required.\r
- @param[in] OutputFilePath The created PI firmware file name. This option is required.\r
- @param[in] BlockSize BlockSize is one HEX or DEC format value required by FV image.\r
- @param[in] FileTakeSize\r
-\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-LibEncapsulateFfsToFv (\r
- IN CHAR8* InfFilePath,\r
- IN CHAR8* InputFFSs,\r
- IN CHAR8* OutputFilePath,\r
- IN CHAR8* FvGuidName\r
- )\r
-{\r
-\r
- CHAR8* SystemCommand;\r
- CHAR8* FfsGuid = "8c8ce578-8a3d-4f1c-9935-896185c32dd3";\r
-\r
- SystemCommand = NULL;\r
-\r
- if (OutputFilePath == NULL ||\r
- InfFilePath == NULL ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (InfFilePath != NULL) {\r
- if (FvGuidName == NULL) {\r
- SystemCommand = malloc (\r
- strlen (GENFV_STR) +\r
- strlen (InfFilePath) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- GENFV_STR,\r
- InfFilePath, // -i\r
- OutputFilePath // -o\r
- );\r
-\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- } else {\r
- //\r
- // Have FvGuidName in it.\r
- //\r
- SystemCommand = malloc (\r
- strlen (GENFV_FVGUID) +\r
- strlen (InfFilePath) +\r
- strlen (OutputFilePath) +\r
- strlen (FvGuidName) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- GENFV_FVGUID,\r
- InfFilePath, // -i\r
- OutputFilePath, // -o\r
- FvGuidName // FvNameGuid\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
-\r
- }\r
- }\r
-\r
- if (InputFFSs != NULL) {\r
- SystemCommand = malloc (\r
- strlen (GENFV_FFS) +\r
- strlen (InputFFSs) +\r
- strlen (FfsGuid) +\r
- strlen (OutputFilePath) +\r
- 100\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- GENFV_FFS,\r
- InputFFSs, // -f\r
- FfsGuid, // -g\r
- OutputFilePath // -o\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-\r
- Convert a GUID to a string.\r
-\r
-\r
- @param[in] Guid - Pointer to GUID to print.\r
-\r
-\r
- @return The string after convert.\r
-\r
-**/\r
-CHAR8 *\r
-LibBfmGuidToStr (\r
- IN EFI_GUID *Guid\r
-)\r
-{\r
- CHAR8 * Buffer;\r
-\r
- Buffer = NULL;\r
-\r
- if (Guid == NULL) {\r
- printf ("The guid is NULL while convert guid to string! \n");\r
- return NULL;\r
- }\r
-\r
- Buffer = (CHAR8 *) malloc (36 + 1);\r
-\r
- if (Buffer == NULL) {\r
- printf ("Error while allocate resource! \n");\r
- return NULL;\r
- }\r
- memset (Buffer, '\0', 36 + 1);\r
-\r
- sprintf (\r
- Buffer,\r
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
- Guid->Data1,\r
- Guid->Data2,\r
- Guid->Data3,\r
- Guid->Data4[0],\r
- Guid->Data4[1],\r
- Guid->Data4[2],\r
- Guid->Data4[3],\r
- Guid->Data4[4],\r
- Guid->Data4[5],\r
- Guid->Data4[6],\r
- Guid->Data4[7]\r
- );\r
-\r
- return Buffer;\r
-}\r
-\r
-/**\r
- Encapsulate an FFS section file to an FFS file.\r
-\r
- @param[in] Type Type is one FV file type defined in PI spec, which is one type of EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FREEFORM,\r
- EFI_FV_FILETYPE_SECURITY_CORE, EFI_FV_FILETYPE_PEIM, EFI_FV_FILETYPE_PEI_CORE, EFI_FV_FILETYPE_DXE_CORE,\r
- EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION, EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\r
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE. This option is required.\r
- @param[in] InputFilePath Section file will be read into this FFS file. This option is required.\r
- @param[in] OutputFilePath The created PI firmware file name. This option is required.\r
- @param[in] FileGuid FileGuid is the unique identifier for this FFS file. This option is required.\r
- @param[in] Fixed Set fixed attribute in FFS file header to indicate that the file may not be moved from its present location.\r
- @param[in] SectionAlign FileAlign specifies FFS file alignment, which only support the following alignment: 8,16,128,512,1K,4K,32K,64K.\r
-\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-LibEncapSectionFileToFFS (\r
- IN UINT8 Type,\r
- IN CHAR8* InputFilePath,\r
- IN CHAR8* OutputFilePath,\r
- IN EFI_GUID FileGuid,\r
- IN BOOLEAN Fixed,\r
- IN UINT32 SectionAlign\r
- )\r
-{\r
- CHAR8* SystemCommand;\r
- CHAR8* GuidStr;\r
-\r
- SystemCommand = NULL;\r
- GuidStr = NULL;\r
-\r
- GuidStr = LibBfmGuidToStr(&FileGuid);\r
-\r
- if (NULL == GuidStr) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (Type == EFI_FV_FILETYPE_RAW) {\r
- SystemCommand = malloc (\r
- strlen (GENFFS_STR) +\r
- strlen (mFfsFileType[Type]) +\r
- strlen (InputFilePath) +\r
- strlen (GuidStr) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- free (GuidStr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENFFS_STR,\r
- mFfsFileType[Type], // -t\r
- InputFilePath, // -i\r
- GuidStr, // -g\r
- OutputFilePath // -o\r
- );\r
-\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- free (GuidStr);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
-\r
- } else {\r
- //\r
- // -t Type\r
- // -i InputFilePath\r
- // -o OutPutFilePath\r
- // -g FileGuid\r
- // -x Fixed\r
- // -n SectionAlign\r
- //\r
- if (Fixed) {\r
- SystemCommand = malloc (\r
- strlen (GENFFS_FIX) +\r
- strlen (mFfsFileType[Type]) +\r
- strlen (InputFilePath) +\r
- strlen (GuidStr) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- free (GuidStr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENFFS_FIX,\r
- mFfsFileType[Type], // -t\r
- InputFilePath, // -i\r
- GuidStr, // -g\r
- OutputFilePath // -o\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- free (GuidStr);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- } else {\r
- SystemCommand = malloc (\r
- strlen (GENFFS_STR) +\r
- strlen (mFfsFileType[Type]) +\r
- strlen (InputFilePath) +\r
- strlen (GuidStr) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- free (GuidStr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENFFS_STR,\r
- mFfsFileType[Type], // -t\r
- InputFilePath, // -i\r
- GuidStr, // -g\r
- OutputFilePath // -o\r
- );\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- free (GuidStr);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
- }\r
- }\r
- free (GuidStr);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-LibCreateNewFdCopy(\r
- IN CHAR8* OldFd,\r
- IN CHAR8* NewFd\r
-)\r
-{\r
- CHAR8* SystemCommand;\r
- SystemCommand = NULL;\r
-\r
-\r
- if (OldFd == NULL ||\r
- NewFd == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Create a copy the new file.\r
- //\r
-\r
- SystemCommand = malloc (\r
- strlen (COPY_STR) +\r
- strlen (OldFd) +\r
- strlen (NewFd) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- COPY_STR,\r
- OldFd,\r
- NewFd\r
- );\r
-\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- This function will assemble the filename, directory and extend and return the combined string.\r
- Like FileName = file1, Dir = c:\temp extend = txt, the output string will be:\r
- c:\temp\file1.txt.\r
-\r
- @param[in]\r
- @param[in]\r
- @param[in]\r
-\r
- @retrun A string contain all the input information.\r
-\r
-**/\r
-CHAR8 *\r
-LibFilenameStrExtended (\r
- IN CHAR8 *FileName,\r
- IN CHAR8 *Dir,\r
- IN CHAR8 *Extend\r
-)\r
-{\r
- CHAR8 *RetStr;\r
-\r
- RetStr = NULL;\r
-\r
- if (FileName == NULL) {\r
- return NULL;\r
- }\r
-\r
- if (Dir == NULL || Extend == NULL) {\r
- return FileName;\r
- }\r
-\r
- RetStr = (CHAR8 *) malloc (strlen (FileName) +\r
- strlen (Dir) +\r
- strlen (Extend) +\r
- strlen ("%s%s.%s") +\r
- 1);\r
- if (NULL == RetStr) {\r
- return NULL;\r
- }\r
-\r
- memset (RetStr, '\0', (strlen (FileName) + strlen (Dir) + strlen (Extend) + strlen("%s%s.%s") + 1));\r
-\r
- sprintf (RetStr, "%s%s.%s", Dir, FileName, Extend);\r
-\r
- return RetStr;\r
-}\r
-\r
-/**\r
- Delete a directory and files in it.\r
-\r
- @param[in] DirName Name of the directory need to be deleted.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-LibRmDir (\r
- IN CHAR8* DirName\r
-)\r
-{\r
- CHAR8* SystemCommand;\r
- SystemCommand = NULL;\r
-\r
-\r
- if (DirName == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (access (DirName, 0) == -1){\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Delete a directory and files in it\r
- //\r
- SystemCommand = malloc (\r
- strlen (RMDIR_STR) +\r
- strlen (DirName) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- RMDIR_STR,\r
- DirName\r
- );\r
-\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Delete a file.\r
-\r
- @param[in] FileName Name of the file need to be deleted.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-LibBfmDeleteFile(\r
- IN CHAR8 *FileName\r
-)\r
-{\r
- CHAR8* SystemCommand;\r
-\r
- SystemCommand = NULL;\r
-\r
-\r
- if (FileName == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
-\r
- //\r
- // Delete a file.\r
- //\r
- SystemCommand = malloc (\r
- strlen (DEL_STR) +\r
- strlen (FileName) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- DEL_STR,\r
- FileName\r
- );\r
-\r
- if (system (SystemCommand) != EFI_SUCCESS) {\r
- free(SystemCommand);\r
- return EFI_ABORTED;\r
- }\r
- free(SystemCommand);\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-\r
-/**\r
-\r
- Free the whole Fd data structure.\r
-\r
- @param[in] Fd The pointer point to the Fd data structure.\r
-\r
-**/\r
-VOID\r
-LibBfmFreeFd (\r
- FIRMWARE_DEVICE *Fd\r
- )\r
-{\r
- FV_INFORMATION *CurrentFv;\r
- FV_INFORMATION *TempFv;\r
- ENCAP_INFO_DATA *EncapData1;\r
- ENCAP_INFO_DATA *EncapData2;\r
-\r
- CurrentFv = NULL;\r
- TempFv = NULL;\r
- EncapData1 = NULL;\r
- EncapData2 = NULL;\r
-\r
- if (Fd == NULL) {\r
- return;\r
- }\r
-\r
- CurrentFv = Fd->Fv;\r
-\r
- do {\r
- TempFv = CurrentFv;\r
- CurrentFv = CurrentFv->FvNext;\r
-\r
- if (TempFv->FvHeader != NULL) {\r
- free (TempFv->FvHeader);\r
- }\r
- if (TempFv->FvExtHeader != NULL) {\r
- free (TempFv->FvExtHeader);\r
- }\r
-\r
- //\r
- // Free encapsulate data;\r
- //\r
- EncapData1 = TempFv->EncapData;\r
-\r
- while (EncapData1 != NULL) {\r
-\r
- EncapData2 = EncapData1;\r
- EncapData1 = EncapData1->NextNode;\r
-\r
- if (EncapData2->Data != NULL) {\r
- free (EncapData2->Data);\r
- }\r
- if (EncapData2->FvExtHeader != NULL) {\r
- free(EncapData2->FvExtHeader);\r
- }\r
- free (EncapData2);\r
- EncapData2 = NULL;\r
- }\r
-\r
- EncapData1 = NULL;\r
-\r
- free (TempFv);\r
- TempFv = NULL;\r
-\r
- } while (CurrentFv != NULL);\r
-\r
- CurrentFv = NULL;\r
- free (Fd);\r
- Fd = NULL;\r
-\r
- return;\r
-}\r
-\r
-/**\r
- Generate the compressed section with specific type.\r
- Type could be EFI_STANDARD_COMPRESSION or EFI_NOT_COMPRESSED\r
-\r
- @param[in] InputFileName File name of the raw data.\r
- @param[in] OutPutFileName File name of the sectioned data.\r
- @param[in] CompressionType The compression type.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_ABORTED\r
- @return EFI_OUT_OF_RESOURCES\r
- @return EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-LibGenCompressedSection (\r
- CHAR8 *InputFileName,\r
- CHAR8 *OutPutFileName,\r
- UINT8 CompressionType\r
-)\r
-{\r
- FILE *UnCompressFile;\r
- FILE *CompressedFile;\r
- VOID *UnCompressedBuffer;\r
- VOID *CompressedBuffer;\r
- UINT32 UnCompressedSize;\r
- UINT32 CompressedSize;\r
- CHAR8 *TempName;\r
- CHAR8 *TemDir;\r
- CHAR8 *TemString;\r
- EFI_STATUS Status;\r
-\r
- UnCompressFile = NULL;\r
- CompressedFile = NULL;\r
- UnCompressedBuffer = NULL;\r
- CompressedBuffer = NULL;\r
- TempName = NULL;\r
- TemDir = NULL;\r
- TemString = NULL;\r
- UnCompressedSize = 0;\r
- CompressedSize = 0;\r
-\r
- if ( InputFileName == NULL ||\r
- OutPutFileName == NULL) {\r
- printf ("Error while generate compressed section!\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
- UnCompressFile = fopen (InputFileName, "rb");\r
- if (UnCompressFile == NULL) {\r
- printf ("Error while open file %s \n", InputFileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- TemDir = getcwd (NULL, _MAX_PATH);\r
- if (strlen (TemDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- fclose (UnCompressFile);\r
- return EFI_ABORTED;\r
- }\r
- strncat (TemDir, OS_SEP_STR, _MAX_PATH - strlen (TemDir) - 1);\r
- strncat (TemDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TemDir) - 1);\r
- TemString = GenTempFile ();\r
- TempName= LibFilenameStrExtended (strrchr(TemString, OS_SEP), TemDir, "comp");\r
- free (TemString);\r
- TemString = NULL;\r
- if (TempName == NULL) {\r
- fclose(UnCompressFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- CompressedFile = fopen (TempName, "wb+");\r
- if (CompressedFile == NULL) {\r
- printf ("Error while open file %s \n", TempName);\r
- fclose(UnCompressFile);\r
- free (TempName);\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Get the original file size;\r
- //\r
- fseek(UnCompressFile,0,SEEK_SET);\r
- fseek(UnCompressFile,0,SEEK_END);\r
-\r
- UnCompressedSize = ftell(UnCompressFile);\r
-\r
- fseek(UnCompressFile,0,SEEK_SET);\r
-\r
- UnCompressedBuffer = malloc (UnCompressedSize);\r
-\r
- if (UnCompressedBuffer == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- fclose (CompressedFile);\r
- fclose(UnCompressFile);\r
- free (TempName);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- CompressedBuffer = malloc (UnCompressedSize);\r
-\r
- if (CompressedBuffer == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- free (UnCompressedBuffer);\r
- fclose (CompressedFile);\r
- fclose(UnCompressFile);\r
- free (TempName);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (fread (UnCompressedBuffer, 1, (size_t) UnCompressedSize, UnCompressFile) == (size_t) UnCompressedSize) {\r
- CompressedSize = UnCompressedSize;\r
-\r
- Status = EfiCompress ( UnCompressedBuffer,\r
- UnCompressedSize,\r
- CompressedBuffer,\r
- &CompressedSize);\r
-\r
- if (EFI_ERROR(Status)) {\r
- printf("Error while do compress operation! \n");\r
- free (UnCompressedBuffer);\r
- free (CompressedBuffer);\r
- fclose (CompressedFile);\r
- fclose(UnCompressFile);\r
- free (TempName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (CompressedSize > UnCompressedSize) {\r
- printf("Error while do compress operation! \n");\r
- free (UnCompressedBuffer);\r
- free (CompressedBuffer);\r
- fclose (CompressedFile);\r
- fclose(UnCompressFile);\r
- free (TempName);\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- printf("Error while reading file %s! \n", InputFileName);\r
- free (UnCompressedBuffer);\r
- free (CompressedBuffer);\r
- fclose (CompressedFile);\r
- fclose(UnCompressFile);\r
- free (TempName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Write the compressed data into output file\r
- //\r
- if (fwrite (CompressedBuffer, 1, (size_t) CompressedSize, CompressedFile) != (size_t) CompressedSize) {\r
- printf ("Error while writing %s file. \n", OutPutFileName);\r
- free (UnCompressedBuffer);\r
- free (CompressedBuffer);\r
- fclose(UnCompressFile);\r
- fclose (CompressedFile);\r
- free (TempName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fclose(UnCompressFile);\r
- fclose (CompressedFile);\r
- free (UnCompressedBuffer);\r
- free (CompressedBuffer);\r
-\r
- //\r
- // Call GenSec tool to generate the compressed section.\r
- //\r
- LibCreateFfsSection(TempName, NULL, EFI_SECTION_COMPRESSION, OutPutFileName, NULL, NULL, NULL, "PI_STD");\r
- free (TempName);\r
- TempName = NULL;\r
-\r
- } else if (CompressionType == EFI_NOT_COMPRESSED) {\r
-\r
- LibCreateFfsSection(InputFileName, NULL, EFI_SECTION_COMPRESSION, OutPutFileName, NULL, NULL, NULL, "PI_NONE");\r
-\r
- } else {\r
- printf ("Error while generate compressed section, unknown compression type! \n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-#define BUILD_IN_TOOL_COUNT 4\r
-\r
-EFI_HANDLE\r
-LibPreDefinedGuidedTools (\r
- VOID\r
-)\r
-{\r
- EFI_GUID Guid;\r
- STRING_LIST *Tool;\r
- GUID_SEC_TOOL_ENTRY *FirstGuidTool;\r
- GUID_SEC_TOOL_ENTRY *LastGuidTool;\r
- GUID_SEC_TOOL_ENTRY *NewGuidTool;\r
- UINT8 Index;\r
- EFI_STATUS Status;\r
-\r
- CHAR8 PreDefinedGuidedTool[BUILD_IN_TOOL_COUNT][255] = {\r
- "a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress",\r
- "ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress",\r
- "fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32",\r
- "3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress"\r
- };\r
-\r
-\r
- Tool = NULL;\r
- FirstGuidTool = NULL;\r
- LastGuidTool = NULL;\r
- NewGuidTool = NULL;\r
- Index = 0;\r
-\r
- for (Index = 0; Index < BUILD_IN_TOOL_COUNT; Index++) {\r
- Tool = SplitStringByWhitespace (PreDefinedGuidedTool[Index]);\r
- if ((Tool != NULL) &&\r
- (Tool->Count == 3)\r
- ) {\r
- Status = StringToGuid (Tool->Strings[0], &Guid);\r
- if (!EFI_ERROR (Status)) {\r
- NewGuidTool = malloc (sizeof (GUID_SEC_TOOL_ENTRY));\r
- if (NewGuidTool != NULL) {\r
- memcpy (&(NewGuidTool->Guid), &Guid, sizeof (Guid));\r
- NewGuidTool->Name = CloneString(Tool->Strings[1]);\r
- NewGuidTool->Path = CloneString(Tool->Strings[2]);\r
- NewGuidTool->Next = NULL;\r
- } else {\r
- printf ( "Fail to allocate memory. \n");\r
- if (Tool != NULL) {\r
- FreeStringList (Tool);\r
- }\r
- return NULL;\r
- }\r
- if (FirstGuidTool == NULL) {\r
- FirstGuidTool = NewGuidTool;\r
- } else {\r
- LastGuidTool->Next = NewGuidTool;\r
- }\r
- LastGuidTool = NewGuidTool;\r
- }\r
- } else {\r
- fprintf (stdout, "Error");\r
- }\r
- if (Tool != NULL) {\r
- FreeStringList (Tool);\r
- Tool = NULL;\r
- }\r
- }\r
- return FirstGuidTool;\r
-}\r
-\r
-EFI_STATUS\r
-LibLocateFvViaFvId (\r
- IN FIRMWARE_DEVICE *FdData,\r
- IN CHAR8 *FvId,\r
- IN OUT FV_INFORMATION **FvInFd\r
-)\r
-{\r
- UINT8 FvIndex1;\r
- UINT8 FvIndex2;\r
- BOOLEAN FvFoundFlag;\r
-\r
- FvIndex1 = 0;\r
- FvIndex2 = 0;\r
- FvFoundFlag = FALSE;\r
-\r
- if (FdData == NULL || FvId == NULL) {\r
- printf ( "Error while find FV in FD. \n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *FvInFd = FdData->Fv;\r
-\r
- FvIndex1 = (UINT8) atoi (FvId + 2);\r
-\r
- while (FvInFd != NULL) {\r
- if (((*FvInFd)->FvName) != NULL) {\r
- FvIndex2 = (UINT8) atoi ((*FvInFd)->FvName + 2);\r
-\r
- if ((FvIndex2 <= FvIndex1) && (((*FvInFd)->FvLevel + FvIndex2) -1 >= FvIndex1)) {\r
- FvFoundFlag = TRUE;\r
- break;\r
- }\r
- if ((*FvInFd)->FvNext == 0) {\r
- break;\r
- }\r
- *FvInFd = (*FvInFd)->FvNext;\r
- }\r
- }\r
-\r
- //\r
- // The specified FV id has issue, can not find the FV in FD.\r
- //\r
- if (!FvFoundFlag) {\r
- printf ( "Error while find FV in FD. \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-\r
-EFI_STATUS\r
-LibPatchResetVectorAndFitTableData (\r
-IN CHAR8 *OutputFileName,\r
-IN PATCH_DATA_PAD_FFS *PatchData\r
-)\r
-{\r
- FILE* NewFvFile;\r
- UINT64 NewFvLength;\r
- UINT8 *Buffer;\r
- UINT32 Count;\r
-\r
-\r
- Count = 0;\r
- Buffer = NULL;\r
- NewFvFile = NULL;\r
-\r
- if (OutputFileName == NULL || PatchData == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- NewFvFile = fopen (OutputFileName, "rb+");\r
- if (NewFvFile == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- fseek(NewFvFile, 0, SEEK_SET);\r
- fseek(NewFvFile, 0, SEEK_END);\r
-\r
- NewFvLength = ftell(NewFvFile);\r
-\r
- do {\r
-\r
- //\r
- // The FV length should larger than Offset.\r
- //\r
- if (NewFvLength < PatchData->Offset) {\r
- fclose (NewFvFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fseek(NewFvFile,PatchData->Offset,SEEK_SET);\r
-\r
- Buffer = (UINT8 *) malloc (PatchData->Length);\r
-\r
- if (Buffer == NULL) {\r
- fclose (NewFvFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (fread (Buffer, 1, (size_t) PatchData->Length, NewFvFile) != (size_t) PatchData->Length) {\r
- fclose (NewFvFile);\r
- free(Buffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // The area used to patch data should be filled by 0xff.\r
- //\r
- for (Count = 0; Count< PatchData->Length; Count++) {\r
- if (Buffer[Count] != 0xff){\r
- fclose (NewFvFile);\r
- free(Buffer);\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- free(Buffer);\r
-\r
- fseek(NewFvFile,PatchData->Offset,SEEK_SET);\r
-\r
- if (fwrite (PatchData->Data, 1, (size_t) PatchData->Length, NewFvFile) != (size_t) PatchData->Length) {\r
- fclose (NewFvFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- PatchData = PatchData->NextNode;\r
- } while (PatchData != NULL);\r
-\r
- fclose (NewFvFile);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-LibEncapNewFvFile(\r
- IN FV_INFORMATION *FvInFd,\r
- IN CHAR8 *TemDir,\r
- OUT CHAR8 **OutputFile\r
-)\r
-{\r
- EFI_STATUS Status;\r
- UINT32 ParentType;\r
- UINT8 ParentLevel;\r
- UINT32 Type;\r
- UINT8 Level;\r
- CHAR8 *InfFileName;\r
- FILE *InfFile;\r
- ENCAP_INFO_DATA *LocalEncapData;\r
- BOOLEAN FfsFoundFlag;\r
- UINT32 Index;\r
- CHAR8 *ExtractionTool;\r
- BOOLEAN IsLastLevelFfs;\r
- BOOLEAN IsLeafFlagIgnore;\r
- BOOLEAN FirstInFlag;\r
- CHAR8 *InputFileName;\r
- CHAR8 *OutputFileName;\r
- CHAR8 *FvGuidName;\r
-\r
- Index = 0;\r
- ParentType = 0;\r
- ParentLevel = 0;\r
- Type = 0;\r
- Level = 0;\r
- FfsFoundFlag = FALSE;\r
- ExtractionTool = NULL;\r
- InputFileName = NULL;\r
- OutputFileName = NULL;\r
- IsLastLevelFfs = TRUE;\r
- IsLeafFlagIgnore = FALSE;\r
- FirstInFlag = TRUE;\r
- FvGuidName = NULL;\r
-\r
- //\r
- // Encapsulate from the lowest FFS file level.\r
- //\r
- LocalEncapData = FvInFd->EncapData;\r
- Level = LocalEncapData->Level;\r
- Type = LocalEncapData->Type;\r
-\r
- //\r
- // Get FV Name GUID\r
- //\r
-\r
- while (LocalEncapData != NULL) {\r
- //\r
- // Has changed.\r
- //\r
- if (LocalEncapData->Level > Level) {\r
- if (LocalEncapData->Type == BFM_ENCAP_TREE_FFS) {\r
- ParentLevel = Level;\r
- ParentType = Type;\r
- }\r
-\r
- Level = LocalEncapData->Level;\r
- Type = LocalEncapData->Type;\r
- }\r
-\r
- if (LocalEncapData->NextNode != NULL) {\r
- LocalEncapData = LocalEncapData->NextNode;\r
- } else {\r
- break;\r
- }\r
- }\r
-\r
- do {\r
- switch (ParentType) {\r
- case BFM_ENCAP_TREE_FV:\r
-\r
- //\r
- // Generate FV.inf attributes.\r
- //\r
- InfFileName = LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "inf");\r
-\r
- InfFile = fopen (InfFileName, "wt+");\r
-\r
- if (InfFile == NULL) {\r
- printf ("Could not open inf file %s to store FV information. \n", InfFileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalEncapData = FvInFd->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == ParentLevel) {\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- if (((EFI_FIRMWARE_VOLUME_HEADER *)(LocalEncapData->Data))->ExtHeaderOffset != 0) {\r
- //\r
- // FV GUID Name memory allocation\r
- //\r
- FvGuidName = (CHAR8 *) malloc (255);\r
-\r
- if (FvGuidName == NULL) {\r
- printf ("Out of resource, memory allocation failed. \n");\r
- fclose (InfFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- memset(FvGuidName, '\0', 255);\r
-\r
- sprintf(\r
- FvGuidName,\r
- "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",\r
- LocalEncapData->FvExtHeader->FvName.Data1,\r
- LocalEncapData->FvExtHeader->FvName.Data2,\r
- LocalEncapData->FvExtHeader->FvName.Data3,\r
- LocalEncapData->FvExtHeader->FvName.Data4[0],\r
- LocalEncapData->FvExtHeader->FvName.Data4[1],\r
- LocalEncapData->FvExtHeader->FvName.Data4[2],\r
- LocalEncapData->FvExtHeader->FvName.Data4[3],\r
- LocalEncapData->FvExtHeader->FvName.Data4[4],\r
- LocalEncapData->FvExtHeader->FvName.Data4[5],\r
- LocalEncapData->FvExtHeader->FvName.Data4[6],\r
- LocalEncapData->FvExtHeader->FvName.Data4[7]\r
- );\r
-\r
- } else {\r
- FvGuidName = NULL;\r
- }\r
-\r
-\r
- if (ParentLevel == 1) {\r
- Status = LibFvHeaderOptionToStr(((EFI_FIRMWARE_VOLUME_HEADER *)LocalEncapData->Data)->BlockMap, InfFile, TRUE);\r
- } else {\r
- Status = LibFvHeaderOptionToStr(((EFI_FIRMWARE_VOLUME_HEADER *)LocalEncapData->Data)->BlockMap, InfFile, FALSE);\r
- }\r
-\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Generate FV INF file [Options] section failed.\n");\r
- fclose (InfFile);\r
- if (FvGuidName != NULL) {\r
- free (FvGuidName);\r
- }\r
- return Status;\r
- }\r
-\r
- Status = LibFvHeaderAttributeToStr(((EFI_FIRMWARE_VOLUME_HEADER *)LocalEncapData->Data)->Attributes, InfFile);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Generate FV header attribute failed.\n");\r
- if (FvGuidName != NULL) {\r
- free (FvGuidName);\r
- }\r
- fclose (InfFile);\r
- return Status;\r
- }\r
- if (LocalEncapData->FvExtHeader != NULL) {\r
- Status = LibGenExtFile(LocalEncapData->FvExtHeader, InfFile);\r
- if (FvGuidName != NULL) {\r
- free (FvGuidName);\r
- }\r
- if (EFI_ERROR(Status)) {\r
- printf("Generate FV EXT header failed.\n");\r
- fclose (InfFile);\r
- return Status;\r
- }\r
- FvGuidName = NULL;\r
- }\r
-\r
- //\r
- // Found FFSs from Fv structure.\r
- //\r
- FfsFoundFlag = FALSE;\r
- for (Index = 0; Index <= FvInFd->FfsNumbers; Index++) {\r
-\r
- //\r
- // For the last level FFS, the level below FFSs we should not care the IsLeaf Flag.\r
- //\r
- if (IsLastLevelFfs) {\r
- IsLeafFlagIgnore = TRUE;\r
- } else {\r
- IsLeafFlagIgnore = FvInFd->FfsAttuibutes[Index].IsLeaf;\r
- }\r
-\r
- if (FvInFd->FfsAttuibutes[Index].Level >= ParentLevel + 1 && IsLeafFlagIgnore) {\r
- if (FirstInFlag) {\r
- Status = LibAddFfsFileToFvInf (FvInFd->FfsAttuibutes[Index].FfsName, InfFile, TRUE);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate FV inf file [files] section. \n");\r
- fclose (InfFile);\r
- return Status;\r
- }\r
-\r
- FvInFd->FfsAttuibutes[Index].Level = 0;\r
- FirstInFlag = FALSE;\r
- } else {\r
- Status = LibAddFfsFileToFvInf (FvInFd->FfsAttuibutes[Index].FfsName, InfFile, FALSE);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate FV inf file [files] section. \n");\r
- fclose (InfFile);\r
- return Status;\r
- }\r
-\r
- FvInFd->FfsAttuibutes[Index].Level = 0;\r
- }\r
- FfsFoundFlag = TRUE;\r
- }\r
- //\r
- // Also add the sub FV\r
- //\r
- if (FvInFd->FfsAttuibutes[Index].Level - 1 == ParentLevel+ 1) {\r
- LocalEncapData = FvInFd->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == ParentLevel + 2) {\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- if (LocalEncapData->Type == BFM_ENCAP_TREE_GUIDED_SECTION) {\r
- Status = LibAddFfsFileToFvInf (FvInFd->FfsAttuibutes[Index].FfsName, InfFile, FALSE);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate FV inf file [files] section.\n");\r
- fclose (InfFile);\r
- return Status;\r
- }\r
-\r
- FvInFd->FfsAttuibutes[Index].Level = 0;\r
- }\r
-\r
- }\r
- }\r
-\r
- IsLastLevelFfs = FALSE;\r
- FirstInFlag = TRUE;\r
- if (!FfsFoundFlag) {\r
- Status = LibAddFfsFileToFvInf (OutputFileName, InfFile, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate FV inf file [files] section.\n");\r
- fclose (InfFile);\r
- return Status;\r
- }\r
- }\r
- /*\r
- if (OutputFileName != NULL && FfsFoundFlag) {\r
- Status = LibAddFfsFileToFvInf (OutputFileName, InfFile, FALSE);\r
-\r
- if (EFI_ERROR (Status)) {\r
- //Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");\r
- return Status;\r
- }\r
- }\r
- */\r
- //\r
- // Create FV\r
- //\r
- fclose (InfFile);\r
- OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "FV");\r
- Status = LibEncapsulateFfsToFv (InfFileName, NULL, OutputFileName, FvGuidName);\r
- if (FvGuidName != NULL) {\r
- free (FvGuidName);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Patch FIT Table Data or reset vector data if exist.\r
- //\r
- if ((FvInFd->PatchData != NULL) && (1 == ParentLevel)) {\r
- Status = LibPatchResetVectorAndFitTableData(OutputFileName, FvInFd->PatchData);\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while patch FIT Table Data or reset vector data. \n");\r
- return Status;\r
- }\r
- }\r
-\r
- break;\r
- case BFM_ENCAP_TREE_FFS:\r
- if (OutputFileName != NULL) {\r
- InputFileName = OutputFileName;\r
- OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "ffs");\r
-\r
- LocalEncapData = FvInFd->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == Level) {\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- Status = LibEncapSectionFileToFFS(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, InputFileName, OutputFileName, ((EFI_FFS_FILE_HEADER *)LocalEncapData->Data)->Name, FALSE, 0);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate FFS file. \n");\r
- return Status;\r
- }\r
- }\r
- break;\r
- case BFM_ENCAP_TREE_GUIDED_SECTION:\r
- //\r
- // Create the guided section original data, do compress operation.\r
- //\r
- InputFileName = OutputFileName;\r
- OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "compressed");\r
-\r
- //\r
- // Use the guided section header guid to find out compress application name.\r
- //\r
- LocalEncapData = FvInFd->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == ParentLevel) {\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- ExtractionTool =\r
- LookupGuidedSectionToolPath (\r
- mParsedGuidedSectionTools,\r
- (EFI_GUID *)LocalEncapData->Data\r
- );\r
-\r
- Status = LibCreateGuidedSectionOriginalData (InputFileName, ExtractionTool, OutputFileName);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while compress guided data. \n");\r
- return Status;\r
- }\r
-\r
- InputFileName = OutputFileName;\r
- OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "guided");\r
-\r
- Status = LibCreateFfsSection(InputFileName, NULL, EFI_SECTION_GUID_DEFINED, OutputFileName, NULL, NULL, LibBfmGuidToStr((EFI_GUID *)LocalEncapData->Data), NULL);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate guided section. \n");\r
- return Status;\r
- }\r
-\r
- break;\r
- case BFM_ENCAP_TREE_COMPRESS_SECTION:\r
- if (OutputFileName != NULL) {\r
- InputFileName = OutputFileName;\r
-\r
- OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "comsec");\r
-\r
- LocalEncapData = FvInFd->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == ParentLevel) {\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
-\r
- Status = LibGenCompressedSection (InputFileName, OutputFileName, *(UINT8 *)(LocalEncapData->Data));\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate compressed section. \n");\r
- return Status;\r
- }\r
- }\r
- break;\r
- case BFM_ENCAP_TREE_FV_SECTION:\r
- InputFileName = OutputFileName;\r
- OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "sec");\r
-\r
- Status = LibCreateFfsSection(InputFileName, NULL, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, OutputFileName, NULL, NULL, NULL, NULL);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate FV section. \n");\r
- return Status;\r
- }\r
-\r
- InputFileName = OutputFileName;\r
- OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "sec");\r
-\r
- //\r
- // Make it alignment.\r
- //\r
- Status = LibCreateFfsSection(InputFileName, NULL, 0, OutputFileName, NULL, NULL, NULL, NULL);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while generate FV section. \n");\r
- return Status;\r
- }\r
-\r
- break;\r
- default:\r
- printf("Don't know how to encapsulate the FD file! \n");\r
- return EFI_ABORTED;\r
- }\r
-\r
-\r
- //\r
- // Find next level and encapsulate type\r
- //\r
- ParentLevel -= 1;\r
- LocalEncapData = FvInFd->EncapData;\r
- while (LocalEncapData->NextNode != NULL) {\r
- if (LocalEncapData->Level == ParentLevel) {\r
- ParentType = LocalEncapData->Type;\r
- break;\r
- }\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
- } while (ParentLevel != 0);\r
-\r
-\r
- *OutputFile = OutputFileName;\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-LibLocateBfv(\r
- IN FIRMWARE_DEVICE *FdData,\r
- IN OUT CHAR8 **FvId,\r
- IN OUT FV_INFORMATION **FvInFd\r
-)\r
-{\r
- UINT8 FvIndex1;\r
- UINT8 FvIndex2;\r
- BOOLEAN FvFoundFlag;\r
-\r
- FvIndex1 = 0;\r
- FvIndex2 = 0;\r
- FvFoundFlag = FALSE;\r
-\r
- if (FdData == NULL || FvId == NULL || FvInFd == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- *FvId = (*FvInFd)->FvName;\r
-\r
- FvIndex1 = (UINT8) atoi ((*FvInFd)->FvName + 2);\r
-\r
- *FvInFd = FdData->Fv;\r
-\r
- while (FvInFd != NULL) {\r
- if (((*FvInFd)->FvName) != NULL) {\r
- FvIndex2 = (UINT8) atoi ((*FvInFd)->FvName + 2);\r
-\r
- if ((FvIndex2 <= FvIndex1) && (((*FvInFd)->FvLevel + FvIndex2) -1 >= FvIndex1)) {\r
- FvFoundFlag = TRUE;\r
- break;\r
- }\r
- if ((*FvInFd)->FvNext == 0) {\r
- break;\r
- }\r
- *FvInFd = (*FvInFd)->FvNext;\r
- }\r
- }\r
-\r
- //\r
- // The specified FV id has issue, can not find the FV in FD.\r
- //\r
- if (!FvFoundFlag) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
- Get the length of a file.\r
-\r
- @param[in] FileName The name of a file.\r
-\r
- @retval The length of file.\r
-\r
-**/\r
-UINT64\r
-GetFileSize (\r
- IN CHAR8 *FileName\r
-)\r
-{\r
- FILE* File;\r
- UINT64 Length;\r
-\r
- File = NULL;\r
-\r
- if (FileName == NULL) {\r
- return 0;\r
- }\r
- File = fopen(FileName, "r");\r
-\r
- if (File == NULL) {\r
- return 0;\r
- }\r
- fseek(File, 0L, SEEK_END);\r
- Length = ftell(File);\r
- fclose(File);\r
-\r
- return Length;\r
-}\r
-\r
-/**\r
-\r
- Get the length of BFV PAD file.\r
-\r
- @retval The length of PAD file.\r
-\r
-**/\r
-UINT32\r
-GetBfvPadSize (\r
- VOID\r
-)\r
-{\r
- return PadSizeOfBfv;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
-\r
- The main entry of BFM tool.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BinFileManager.h"\r
-\r
-BOOLEAN mFvGuidIsSet = FALSE;\r
-EFI_GUID mFvNameGuid = {0};\r
-CHAR8* mFvNameGuidString = NULL;\r
-CHAR8* mGuidToolDefinition = "GuidToolDefinitionConf.ini";\r
-\r
-//\r
-// Store GUIDed Section guid->tool mapping\r
-//\r
-EFI_HANDLE mParsedGuidedSectionTools = NULL;\r
-\r
-\r
-/**\r
- Search the config file from the path list.\r
-\r
- Split the path from env PATH, and then search the cofig\r
- file from these paths. The priority is from left to\r
- right of PATH string. When met the first Config file, it\r
- will break and return the pointer to the full file name.\r
-\r
- @param PathList the pointer to the path list.\r
- @param FileName the pointer to the file name.\r
-\r
- @retval The pointer to the file name.\r
- @return NULL An error occurred.\r
-**/\r
-CHAR8 *\r
-SearchConfigFromPathList (\r
- IN CHAR8 *PathList,\r
- IN CHAR8 *FileName\r
-)\r
-{\r
- CHAR8 *CurDir;\r
- CHAR8 *FileNamePath;\r
-\r
- CurDir = NULL;\r
- FileNamePath = NULL;\r
-#ifndef __GNUC__\r
- CurDir = strtok (PathList,";");\r
-#else\r
- CurDir = strtok (PathList,":");\r
-#endif\r
- while (CurDir != NULL) {\r
- FileNamePath = (char *)calloc(\r
- strlen (CurDir) + strlen (OS_SEP_STR) +strlen (FileName) + 1,\r
- sizeof(char)\r
- );\r
- if (FileNamePath == NULL) {\r
- return NULL;\r
- }\r
- sprintf(FileNamePath, "%s%c%s", CurDir, OS_SEP, FileName);\r
- if (access (FileNamePath, 0) != -1) {\r
- return FileNamePath;\r
- }\r
-#ifndef __GNUC__\r
- CurDir = strtok(NULL, ";");\r
-#else\r
- CurDir = strtok(NULL, ":");\r
-#endif\r
- free (FileNamePath);\r
- FileNamePath = NULL;\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
-\r
- Show the FD image layout information. Only display the modules with UI name.\r
-\r
- @param[in] FdInName Input FD binary/image file name;\r
- @param[in] FvName The FV ID in the FD file;\r
- @param[in] ViewFlag Is this call for view or other operate(add/del/replace)\r
- @param[in] FdData The Fd data structure store the FD information.\r
-\r
- @retval EFI_SUCCESS\r
- @retval EFI_INVALID_PARAMETER\r
- @retval EFI_ABORTED\r
-\r
-**/\r
-EFI_STATUS\r
-BfmImageView (\r
- IN CHAR8* FdInName,\r
- IN CHAR8* FvName,\r
- IN BOOLEAN ViewFlag,\r
- IN FIRMWARE_DEVICE **FdData\r
-)\r
-{\r
- EFI_STATUS Status;\r
- FIRMWARE_DEVICE *LocalFdData;\r
- FV_INFORMATION *CurrentFv;\r
- FILE *InputFile;\r
- UINT32 FvSize;\r
- UINTN BytesRead;\r
- EFI_FIRMWARE_VOLUME_HEADER *FvImage;\r
- UINT32 FfsCount;\r
- UINT8 FvCount;\r
- UINT8 LastFvNumber;\r
-\r
- LocalFdData = NULL;\r
- CurrentFv = NULL;\r
- FvImage = NULL;\r
- FvSize = 0;\r
- BytesRead = 0;\r
- FfsCount = 0;\r
- FvCount = 0;\r
- LastFvNumber = 0;\r
-\r
- //\r
- // Check the FD file name/path.\r
- //\r
- if (FdInName == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Open the file containing the FV\r
- //\r
- InputFile = fopen (FdInName, "rb");\r
- if (InputFile == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = LibFindFvInFd (InputFile, &LocalFdData);\r
-\r
- if (EFI_ERROR(Status)) {\r
- fclose (InputFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- CurrentFv = LocalFdData->Fv;\r
-\r
- do {\r
-\r
- memset (CurrentFv->FvName, '\0', _MAX_PATH);\r
-\r
- if (LastFvNumber == 0) {\r
- sprintf (CurrentFv->FvName, "FV%d", LastFvNumber);\r
- } else {\r
- sprintf (CurrentFv->FvName, "FV%d", LastFvNumber);\r
- }\r
-\r
- //\r
- // Determine size of FV\r
- //\r
- if (fseek (InputFile, CurrentFv->ImageAddress, SEEK_SET) != 0) {\r
- fclose (InputFile);\r
- LibBfmFreeFd( LocalFdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Status = LibGetFvSize(InputFile, &FvSize);\r
- if (EFI_ERROR (Status)) {\r
- fclose (InputFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Seek to the start of the image, then read the entire FV to the buffer\r
- //\r
- fseek (InputFile, CurrentFv->ImageAddress, SEEK_SET);\r
-\r
- FvImage = (EFI_FIRMWARE_VOLUME_HEADER *) malloc (FvSize);\r
-\r
- if (FvImage == NULL) {\r
- fclose (InputFile);\r
- LibBfmFreeFd( LocalFdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- BytesRead = fread (FvImage, 1, FvSize, InputFile);\r
- if ((unsigned int) BytesRead != FvSize) {\r
- free (FvImage);\r
- fclose (InputFile);\r
- LibBfmFreeFd( LocalFdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Collect FV information each by each.\r
- //\r
- Status = LibGetFvInfo (FvImage, CurrentFv, FvName, 0, &FfsCount, ViewFlag, FALSE);\r
- free (FvImage);\r
- FvImage = NULL;\r
- if (EFI_ERROR (Status)) {\r
- fclose (InputFile);\r
- LibBfmFreeFd( LocalFdData);\r
- return Status;\r
- }\r
- FvCount = CurrentFv->FvLevel;\r
- LastFvNumber = LastFvNumber+FvCount;\r
-\r
- FfsCount = 0;\r
-\r
- CurrentFv = CurrentFv->FvNext;\r
-\r
- } while (CurrentFv != NULL);\r
-\r
- if (!ViewFlag) {\r
- *FdData = LocalFdData;\r
- } else {\r
- LibBfmFreeFd( LocalFdData);\r
- }\r
-\r
- fclose (InputFile);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Add an FFS file into a specify FV.\r
-\r
- @param[in] FdInName Input FD binary/image file name;\r
- @param[in] NewFile The name of the file add in;\r
- @param[in] FdOutName Name of output fd file.\r
-\r
- @retval EFI_SUCCESS\r
- @retval EFI_INVALID_PARAMETER\r
- @retval EFI_ABORTED\r
-\r
-**/\r
-EFI_STATUS\r
-BfmImageAdd (\r
- IN CHAR8* FdInName,\r
- IN CHAR8* NewFile,\r
- IN CHAR8* FdOutName\r
-)\r
-{\r
- EFI_STATUS Status;\r
- FIRMWARE_DEVICE *FdData;\r
- FV_INFORMATION *FvInFd;\r
- ENCAP_INFO_DATA *LocalEncapData;\r
- ENCAP_INFO_DATA *LocalEncapDataTemp;\r
- FILE* NewFdFile;\r
- FILE* NewFvFile;\r
- UINT64 NewFvLength;\r
- UINT64 NewFfsLength;\r
- VOID* Buffer;\r
- CHAR8 *TemDir;\r
- UINT8 FvEncapLevel;\r
- UINT8 NewAddedFfsLevel;\r
- BOOLEAN FfsLevelFoundFlag;\r
- CHAR8 *OutputFileName;\r
- CHAR8 *FvId;\r
- BOOLEAN FirstInFlag;\r
- BOOLEAN FvGuidExisted;\r
-\r
- NewFvLength = 0;\r
- FvEncapLevel = 0;\r
- NewAddedFfsLevel = 0;\r
-\r
- FfsLevelFoundFlag = FALSE;\r
- FirstInFlag = TRUE;\r
- FdData = NULL;\r
- FvInFd = NULL;\r
- LocalEncapData = NULL;\r
- NewFdFile = NULL;\r
- NewFvFile = NULL;\r
- Buffer = NULL;\r
- TemDir = NULL;\r
- LocalEncapDataTemp = NULL;\r
- OutputFileName = NULL;\r
- FvId = NULL;\r
- FvGuidExisted = FALSE;\r
-\r
- //\r
- // Get the size of ffs file to be inserted.\r
- //\r
- NewFfsLength = GetFileSize(NewFile);\r
-\r
- Status = BfmImageView (FdInName, NULL, FALSE, &FdData);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while parse %s FD image.\n", FdInName);\r
- return Status;\r
- }\r
- //\r
- // Check the FvGuid whether exists or not when the BIOS hasn't default setting.\r
- // If the FV image with -g GUID can't be found, the storage is still saved into the BFV and report warning message.\r
- //\r
- FvInFd = FdData->Fv;\r
- do {\r
- if (mFvGuidIsSet && FvInFd->IsInputFvFlag) {\r
- FvGuidExisted = TRUE;\r
- break;\r
- }\r
- FvInFd = FvInFd->FvNext;\r
- } while (FvInFd != NULL);\r
-\r
- if (mFvGuidIsSet && !FvGuidExisted) {\r
- printf ("Fv image with the specified FV Name Guid %s can't be found in current FD.\n", mFvNameGuidString);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Iterate to write FFS to each BFV.\r
- //\r
- FvInFd = FdData->Fv;\r
- do {\r
- if ((FvGuidExisted && mFvGuidIsSet && FvInFd->IsInputFvFlag) || ((!FvGuidExisted || (!mFvGuidIsSet)) && FvInFd->IsBfvFlag)) {\r
-\r
- Status = LibLocateBfv (FdData, &FvId, &FvInFd);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf("Error while locate BFV from FD.\n");\r
- LibBfmFreeFd(FdData);\r
- return Status;\r
- }\r
-\r
- //\r
- // Determine the new added ffs file level in the FV.\r
- //\r
- LocalEncapData = FvInFd->EncapData;\r
-\r
- while (LocalEncapData != NULL && !FfsLevelFoundFlag ) {\r
- if (LocalEncapData->Type == BFM_ENCAP_TREE_FV) {\r
- if (FvEncapLevel == ((UINT8) atoi (FvId + 2) - (UINT8) atoi (FvInFd->FvName + 2))) {\r
- //\r
- // Found the FFS level in this FV.\r
- //\r
- LocalEncapDataTemp = LocalEncapData;\r
- while (LocalEncapDataTemp != NULL) {\r
- if (LocalEncapDataTemp->Type == BFM_ENCAP_TREE_FFS) {\r
- NewAddedFfsLevel = LocalEncapDataTemp->Level;\r
- FfsLevelFoundFlag = TRUE;\r
- break;\r
- }\r
- if (LocalEncapDataTemp->NextNode != NULL) {\r
- LocalEncapDataTemp = LocalEncapDataTemp->NextNode;\r
- } else {\r
- break;\r
- }\r
- }\r
- }\r
- FvEncapLevel ++;\r
- }\r
-\r
- if (LocalEncapData->NextNode == NULL) {\r
- break;\r
- } else {\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
- }\r
-\r
- //\r
- // Add the new file into FV.\r
- //\r
- FvInFd->FfsNumbers += 1;\r
- if (strlen (NewFile) > _MAX_PATH - 1) {\r
- printf ("The NewFile name is too long \n");\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
- strncpy (FvInFd->FfsAttuibutes[FvInFd->FfsNumbers].FfsName, NewFile, _MAX_PATH - 1);\r
- FvInFd->FfsAttuibutes[FvInFd->FfsNumbers].FfsName[_MAX_PATH - 1] = 0;\r
- FvInFd->FfsAttuibutes[FvInFd->FfsNumbers].Level = NewAddedFfsLevel;\r
-\r
- TemDir = getcwd (NULL, _MAX_PATH);\r
- if (strlen (TemDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
- strncat (TemDir, OS_SEP_STR, _MAX_PATH - strlen (TemDir) - 1);\r
- strncat (TemDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TemDir) - 1);\r
- mkdir(TemDir, S_IRWXU | S_IRWXG | S_IRWXO);\r
- Status = LibEncapNewFvFile (FvInFd, TemDir, &OutputFileName);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf("Error. The boot firmware volume (BFV) has only the spare space 0x%lx bytes. But the default setting data takes 0x%llx bytes, which can't be inserted into BFV. \n",(unsigned long) GetBfvPadSize (), (unsigned long long)NewFfsLength);\r
- LibBfmFreeFd(FdData);\r
- return Status;\r
- }\r
-\r
- if (FirstInFlag) {\r
- //\r
- // Write New Fv file into the NewFd file.\r
- //\r
- Status = LibCreateNewFdCopy (FdInName, FdOutName);\r
- if (EFI_ERROR (Status)) {\r
- printf("Error while copy from %s to %s file. \n", FdInName, FdOutName);\r
- LibBfmFreeFd(FdData);\r
- return Status;\r
- }\r
- FirstInFlag = FALSE;\r
- }\r
-\r
- NewFdFile = fopen (FdOutName, "rb+");\r
- if (NewFdFile == NULL) {\r
- printf("Error while create FD file %s. \n", FdOutName);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- NewFvFile = fopen (OutputFileName, "rb+");\r
-\r
- if (NewFvFile == NULL) {\r
- printf("Error while create Fv file %s. \n", OutputFileName);\r
- fclose(NewFdFile);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fseek(NewFvFile,0,SEEK_SET);\r
- fseek(NewFvFile,0,SEEK_END);\r
-\r
- NewFvLength = ftell(NewFvFile);\r
-\r
- fseek(NewFvFile,0,SEEK_SET);\r
-\r
- Buffer = malloc ((size_t)NewFvLength);\r
-\r
- if (Buffer == NULL) {\r
- printf ("Error while allocate resource! \n");\r
- fclose(NewFdFile);\r
- fclose(NewFvFile);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (fread (Buffer, 1, (size_t) NewFvLength, NewFvFile) != (size_t) NewFvLength) {\r
- printf("Error while reading Fv file %s. \n", OutputFileName);\r
- free (Buffer);\r
- fclose(NewFdFile);\r
- fclose(NewFvFile);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fseek(NewFdFile, FvInFd->ImageAddress, SEEK_SET);\r
- fseek(NewFdFile, FvInFd->ImageAddress, SEEK_SET);\r
-\r
- if (NewFvLength <= FvInFd->FvHeader->FvLength) {\r
- if (fwrite (Buffer, 1, (size_t) NewFvLength, NewFdFile) != (size_t) NewFvLength) {\r
- printf("Error while writing FD file %s. \n", FdOutName);\r
- fclose(NewFdFile);\r
- fclose (NewFvFile);\r
- free (Buffer);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- printf("Error. The new size of BFV is 0x%llx bytes, which is larger than the previous size of BFV 0x%llx bytes. \n", (unsigned long long) NewFvLength, (unsigned long long) FvInFd->FvHeader->FvLength);\r
- free (Buffer);\r
- fclose(NewFdFile);\r
- fclose(NewFvFile);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fclose(NewFdFile);\r
- fclose(NewFvFile);\r
- free (Buffer);\r
- Buffer = NULL;\r
-\r
- }\r
- FvInFd = FvInFd->FvNext;\r
- } while (FvInFd != NULL);\r
-\r
-\r
- LibBfmFreeFd(FdData);\r
-\r
- if (TemDir == NULL) {\r
- if (mFvGuidIsSet) {\r
- printf ("Fv image with the specified FV Name Guid %s can't be found.\n", mFvNameGuidString);\r
- } else {\r
- printf ("BFV image can't be found.\n");\r
- }\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Status = LibRmDir (TemDir);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf("Error while remove temporary directory. \n");\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Replace an FFS file into a specify FV.\r
-\r
- @param[in] FdInName Input FD binary/image file name;\r
- @param[in] NewFile The name of the file add in;\r
- @param[in] FdOutName Name of output fd file.\r
-\r
- @retval EFI_SUCCESS\r
- @retval EFI_INVALID_PARAMETER\r
- @retval EFI_ABORTED\r
-\r
-**/\r
-EFI_STATUS\r
-BfmImageReplace (\r
- IN CHAR8* FdInName,\r
- IN CHAR8* NewFile,\r
- IN CHAR8* FdOutName\r
-)\r
-{\r
- EFI_STATUS Status;\r
- FIRMWARE_DEVICE *FdData;\r
- FV_INFORMATION *FvInFd;\r
- FILE* NewFdFile;\r
- FILE* NewFvFile;\r
- UINT64 NewFvLength;\r
- UINT64 NewFfsLength;\r
- VOID* Buffer;\r
- CHAR8 *TemDir;\r
- CHAR8 *OutputFileName;\r
- CHAR8 *FvId;\r
- BOOLEAN FirstInFlag;\r
- UINT32 Index;\r
- BOOLEAN FvToBeUpdate;\r
- BOOLEAN FdIsUpdate;\r
- ENCAP_INFO_DATA *LocalEncapData;\r
- ENCAP_INFO_DATA *LocalEncapDataTemp;\r
- UINT8 FvEncapLevel;\r
- UINT8 NewAddedFfsLevel;\r
- BOOLEAN FfsLevelFoundFlag;\r
- EFI_GUID EfiNewAddToBfvGuid;\r
- FILE* FfsFile;\r
- UINTN BytesRead;\r
- BOOLEAN ReplaceSameFv;\r
- BOOLEAN FvGuidExisted;\r
-\r
- NewFvLength = 0;\r
- FdIsUpdate = FALSE;\r
- FirstInFlag = TRUE;\r
- FdData = NULL;\r
- FvInFd = NULL;\r
- NewFdFile = NULL;\r
- NewFvFile = NULL;\r
- Buffer = NULL;\r
- TemDir = NULL;\r
- OutputFileName = NULL;\r
- FvId = NULL;\r
- FfsFile = NULL;\r
- BytesRead = 0;\r
- ReplaceSameFv = FALSE;\r
- FvGuidExisted = FALSE;\r
-\r
- //\r
- // Get the size of ffs file to be inserted.\r
- //\r
- NewFfsLength = GetFileSize(NewFile);\r
- //\r
- // Get FFS GUID\r
- //\r
- FfsFile = fopen (NewFile, "rb");\r
- if (FfsFile == NULL) {\r
- printf ("Error while read %s.\n", NewFile);\r
- return EFI_ABORTED;\r
- }\r
- fseek (FfsFile, 0, SEEK_SET);\r
- BytesRead = fread (&EfiNewAddToBfvGuid, 1, sizeof(EFI_GUID), FfsFile);\r
- fclose (FfsFile);\r
- if (BytesRead != sizeof(EFI_GUID)) {\r
- printf ("Error while read the GUID from %s.\n", NewFile);\r
- return EFI_ABORTED;\r
- }\r
- Status = BfmImageView (FdInName, NULL, FALSE, &FdData);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error while parse %s FD image.\n", FdInName);\r
- return Status;\r
- }\r
-\r
- //\r
- // Check the FvGuid whether exists or not when the BIOS has default setting.\r
- // 1. No option means the storage is saved into the same FV image.\r
- // 2. The FV image with -g GUID can't be found. The storage is still saved into the same FV image and report warning message.\r
- //\r
- if (!mFvGuidIsSet) {\r
- ReplaceSameFv = TRUE;\r
- }\r
- FvInFd = FdData->Fv;\r
- do {\r
- if (mFvGuidIsSet && FvInFd->IsInputFvFlag) {\r
- FvGuidExisted = TRUE;\r
- break;\r
- }\r
- FvInFd = FvInFd->FvNext;\r
- } while (FvInFd != NULL);\r
-\r
- if (mFvGuidIsSet && !FvGuidExisted) {\r
- printf ("Fv image with the specified FV Name Guid %s can't be found in current FD.\n", mFvNameGuidString);\r
- ReplaceSameFv = TRUE;\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Interate to insert or replace default setting to Fv\r
- //\r
- FvInFd = FdData->Fv;\r
- do {\r
- FvToBeUpdate = FALSE;\r
- if (mFvGuidIsSet && FvInFd->IsInputFvFlag) {\r
- FvToBeUpdate = TRUE;\r
- }\r
-\r
- Status = LibLocateBfv (FdData, &FvId, &FvInFd);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf("Error while locate BFV from FD.\n");\r
- LibBfmFreeFd(FdData);\r
- return Status;\r
- }\r
-\r
- Index = 0;\r
- while (Index <= FvInFd->FfsNumbers) {\r
- //\r
- // Locate the multi-platform ffs in Fv and then replace or delete it.\r
- //\r
- if (!CompareGuid(&FvInFd->FfsHeader[Index].Name, &EfiNewAddToBfvGuid)) {\r
- if (ReplaceSameFv) {\r
- FvToBeUpdate = TRUE;\r
- }\r
- break;\r
- }\r
- Index ++;\r
- }\r
-\r
- if (FvToBeUpdate || (Index <= FvInFd->FfsNumbers)) {\r
- if (FvToBeUpdate) {\r
- FdIsUpdate = TRUE;\r
- if (Index <= FvInFd->FfsNumbers) {\r
- //\r
- // Override original default data by New File\r
- //\r
- if (strlen (NewFile) > _MAX_PATH - 1) {\r
- printf ("The NewFile name is too long \n");\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
- strncpy (FvInFd->FfsAttuibutes[Index].FfsName, NewFile, _MAX_PATH - 1);\r
- FvInFd->FfsAttuibutes[Index].FfsName[_MAX_PATH - 1] = 0;\r
- } else {\r
- FfsLevelFoundFlag = FALSE;\r
- FvEncapLevel = 0;\r
- NewAddedFfsLevel = 0;\r
- //\r
- // Determine the new added ffs file level in the FV.\r
- //\r
- LocalEncapData = FvInFd->EncapData;\r
-\r
- while (LocalEncapData != NULL && !FfsLevelFoundFlag ) {\r
- if (LocalEncapData->Type == BFM_ENCAP_TREE_FV) {\r
- if (FvEncapLevel == ((UINT8) atoi (FvId + 2) - (UINT8) atoi (FvInFd->FvName + 2))) {\r
- //\r
- // Found the FFS level in this FV.\r
- //\r
- LocalEncapDataTemp = LocalEncapData;\r
- while (LocalEncapDataTemp != NULL) {\r
- if (LocalEncapDataTemp->Type == BFM_ENCAP_TREE_FFS) {\r
- NewAddedFfsLevel = LocalEncapDataTemp->Level;\r
- FfsLevelFoundFlag = TRUE;\r
- break;\r
- }\r
- if (LocalEncapDataTemp->NextNode != NULL) {\r
- LocalEncapDataTemp = LocalEncapDataTemp->NextNode;\r
- } else {\r
- break;\r
- }\r
- }\r
- }\r
- FvEncapLevel ++;\r
- }\r
-\r
- if (LocalEncapData->NextNode == NULL) {\r
- break;\r
- } else {\r
- LocalEncapData = LocalEncapData->NextNode;\r
- }\r
- }\r
-\r
- //\r
- // Add the new file into FV.\r
- //\r
- FvInFd->FfsNumbers += 1;\r
- memcpy (FvInFd->FfsAttuibutes[FvInFd->FfsNumbers].FfsName, NewFile, _MAX_PATH);\r
- FvInFd->FfsAttuibutes[FvInFd->FfsNumbers].Level = NewAddedFfsLevel;\r
- }\r
- } else {\r
- //\r
- // Remove original default data from FV.\r
- //\r
- FvInFd->FfsAttuibutes[Index].FfsName[0] = '\0';\r
- }\r
-\r
- if (TemDir == NULL) {\r
- TemDir = getcwd (NULL, _MAX_PATH);\r
- if (strlen (TemDir) + strlen (OS_SEP_STR)+ strlen (TEMP_DIR_NAME) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
- strncat (TemDir, OS_SEP_STR, _MAX_PATH - strlen (TemDir) - 1);\r
- strncat (TemDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TemDir) - 1);\r
- mkdir(TemDir, S_IRWXU | S_IRWXG | S_IRWXO);\r
- }\r
-\r
- Status = LibEncapNewFvFile (FvInFd, TemDir, &OutputFileName);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf("Error. The boot firmware volume (BFV) has only the spare space 0x%lx bytes. But the default setting data takes 0x%llx bytes, which can't be inserted into BFV. \n", (unsigned long) GetBfvPadSize (), (unsigned long long) NewFfsLength);\r
- LibBfmFreeFd(FdData);\r
- return Status;\r
- }\r
-\r
- if (FirstInFlag) {\r
- //\r
- // Write New Fv file into the NewFd file.\r
- //\r
- Status = LibCreateNewFdCopy (FdInName, FdOutName);\r
- if (EFI_ERROR (Status)) {\r
- printf("Error while copy from %s to %s file. \n", FdInName, FdOutName);\r
- LibBfmFreeFd(FdData);\r
- return Status;\r
- }\r
- FirstInFlag = FALSE;\r
- }\r
-\r
- NewFdFile = fopen (FdOutName, "rb+");\r
- if (NewFdFile == NULL) {\r
- printf("Error while create FD file %s. \n", FdOutName);\r
- LibBfmFreeFd(FdData);\r
- return EFI_ABORTED;\r
- }\r
-\r
- NewFvFile = fopen (OutputFileName, "rb+");\r
-\r
- if (NewFvFile == NULL) {\r
- printf("Error while create Fv file %s. \n", OutputFileName);\r
- LibBfmFreeFd(FdData);\r
- fclose (NewFdFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fseek(NewFvFile,0,SEEK_SET);\r
- fseek(NewFvFile,0,SEEK_END);\r
-\r
- NewFvLength = ftell(NewFvFile);\r
-\r
- fseek(NewFvFile,0,SEEK_SET);\r
-\r
- Buffer = malloc ((size_t)NewFvLength);\r
-\r
- if (Buffer == NULL) {\r
- LibBfmFreeFd(FdData);\r
- fclose (NewFdFile);\r
- fclose (NewFvFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (fread (Buffer, 1, (size_t) NewFvLength, NewFvFile) != (size_t) NewFvLength) {\r
- printf("Error while read Fv file %s. \n", OutputFileName);\r
- LibBfmFreeFd(FdData);\r
- free (Buffer);\r
- fclose (NewFdFile);\r
- fclose (NewFvFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fseek(NewFdFile, FvInFd->ImageAddress, SEEK_SET);\r
- fseek(NewFdFile, FvInFd->ImageAddress, SEEK_SET);\r
-\r
- if (NewFvLength <= FvInFd->FvHeader->FvLength) {\r
- if (fwrite (Buffer, 1, (size_t) NewFvLength, NewFdFile) != (size_t) NewFvLength) {\r
- printf("Error while write FD file %s. \n", FdOutName);\r
- fclose(NewFdFile);\r
- fclose (NewFvFile);\r
- LibBfmFreeFd(FdData);\r
- free (Buffer);\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- printf("Error. The new size of BFV is 0x%llx bytes, which is larger than the previous size of BFV 0x%llx bytes. \n", (unsigned long long) NewFvLength, (unsigned long long) FvInFd->FvHeader->FvLength);\r
- free (Buffer);\r
- LibBfmFreeFd(FdData);\r
- fclose (NewFdFile);\r
- fclose (NewFvFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fclose(NewFdFile);\r
- fclose(NewFvFile);\r
- free (Buffer);\r
- Buffer = NULL;\r
-\r
- }\r
- FvInFd = FvInFd->FvNext;\r
- } while (FvInFd != NULL);\r
-\r
- LibBfmFreeFd(FdData);\r
-\r
- if (TemDir == NULL || !FdIsUpdate) {\r
- if (mFvGuidIsSet) {\r
- printf ("Fv image with the specified FV Name Guid %s can't be found.\n", mFvNameGuidString);\r
- } else {\r
- printf ("BFV image can't be found.\n");\r
- }\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Status = LibRmDir (TemDir);\r
-\r
- if (EFI_ERROR (Status)) {\r
- printf("Error while remove temporary directory. \n");\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
- The main entry of BFM tool.\r
-\r
-**/\r
-int main(\r
- int Argc,\r
- char *Argv[]\r
-)\r
-{\r
- EFI_STATUS Status;\r
- FIRMWARE_DEVICE *FdData;\r
- CHAR8 *InFilePath;\r
- CHAR8 FullGuidToolDefinition[_MAX_PATH];\r
- CHAR8 *FileName;\r
- UINTN FileNameIndex;\r
- CHAR8 *PathList;\r
- UINTN EnvLen;\r
- CHAR8 *NewPathList;\r
-\r
- FdData = NULL;\r
- PathList = NULL;\r
- NewPathList = NULL;\r
- EnvLen = 0;\r
-\r
- if (Argc <= 1) {\r
- return -1;\r
- }\r
- FileName = Argv[0];\r
- //\r
- // Save, skip filename arg\r
- //\r
- Argc--;\r
- Argv++;\r
-\r
- if ((stricmp(Argv[0], "-v") == 0)) {\r
- //\r
- // Check the revison of BfmLib\r
- // BfmLib -v\r
- //\r
- printf("%s\n", __BUILD_VERSION);\r
- return 1;\r
-\r
- }\r
- //\r
- // Workaroud: the first call to this function\r
- // returns a file name ends with dot\r
- //\r
-#ifndef __GNUC__\r
- tmpnam (NULL);\r
-#else\r
- CHAR8 tmp[] = "/tmp/fileXXXXXX";\r
- UINTN Fdtmp;\r
- Fdtmp = mkstemp(tmp);\r
- close(Fdtmp);\r
-#endif\r
- //\r
- // Get the same path with the application itself\r
- //\r
- if (strlen (FileName) > _MAX_PATH - 1) {\r
- Error (NULL, 0, 2000, "Parameter: Input file name is too long", NULL);\r
- return -1;\r
- }\r
- strncpy (FullGuidToolDefinition, FileName, _MAX_PATH - 1);\r
- FullGuidToolDefinition[_MAX_PATH - 1] = 0;\r
- FileNameIndex = strlen (FullGuidToolDefinition);\r
- while (FileNameIndex != 0) {\r
- FileNameIndex --;\r
- if (FullGuidToolDefinition[FileNameIndex] == OS_SEP) {\r
- FullGuidToolDefinition[FileNameIndex] = 0;\r
- break;\r
- }\r
- }\r
- //\r
- // Build the path list for Config file scan. The priority is below.\r
- // 1. Scan the current path\r
- // 2. Scan the same path with the application itself\r
- // 3. Scan the current %PATH% of OS environment\r
- // 4. Use the build-in default configuration\r
- //\r
- PathList = getenv("PATH");\r
- if (PathList == NULL) {\r
- Error (NULL, 0, 1001, "Option: Environment variable 'PATH' does not exist", NULL);\r
- return -1;\r
- }\r
- EnvLen = strlen(PathList);\r
- NewPathList = (char *)calloc(\r
- strlen (".")\r
- + strlen (";")\r
- + strlen (FullGuidToolDefinition)\r
- + strlen (";")\r
- + EnvLen\r
- + 1,\r
- sizeof(char)\r
- );\r
- if (NewPathList == NULL) {\r
- Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);\r
- PathList = NULL;\r
- free (PathList);\r
- return -1;\r
- }\r
-#ifndef __GNUC__\r
- sprintf (NewPathList, "%s;%s;%s", ".", FullGuidToolDefinition, PathList);\r
-#else\r
- sprintf (NewPathList, "%s:%s:%s", ".", FullGuidToolDefinition, PathList);\r
-#endif\r
-\r
- PathList = NULL;\r
- free (PathList);\r
- //\r
- // Load Guid Tools definition\r
- //\r
- InFilePath = SearchConfigFromPathList(NewPathList, mGuidToolDefinition);\r
- free (NewPathList);\r
- if (InFilePath != NULL) {\r
- printf ("\nThe Guid Tool Definition of BfmLib comes from the '%s'. \n", InFilePath);\r
- mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (InFilePath);\r
- free (InFilePath);\r
- } else {\r
- //\r
- // Use the pre-defined standard guided tools.\r
- //\r
- printf ("\nThe Guid Tool Definition of BfmLib comes from the build-in default configuration. \n");\r
- mParsedGuidedSectionTools = LibPreDefinedGuidedTools ();\r
- }\r
-\r
- //\r
- // BfmLib -e FdName.Fd\r
- //\r
- if ((stricmp(Argv[0], "-e") == 0)) {\r
-\r
- if (Argc != 2) {\r
- return -1;\r
- }\r
- //\r
- // Extract FFS files.\r
- //\r
- Status = BfmImageView (Argv[1], NULL, FALSE, &FdData);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return -1;\r
- }\r
-\r
- if (FdData == NULL) {\r
- return -1;\r
- }\r
-\r
- LibBfmFreeFd(FdData);\r
-\r
- } else if ((stricmp(Argv[0], "-i") == 0)) {\r
- //\r
- // Insert FFS files to BFV\r
- // BfmLib -i InFdName.Fd FfsName.ffs OutFdName.Fd -g FvNameGuid\r
- //\r
- if (Argc == 6) {\r
- mFvGuidIsSet = TRUE;\r
- mFvNameGuidString = Argv[5];\r
- StringToGuid (Argv[5], &mFvNameGuid);\r
- Argc -= 2;\r
- }\r
- if (Argc != 4) {\r
- return -1;\r
- }\r
- Status = BfmImageAdd(Argv[1], Argv[2], Argv[3]);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return -1;\r
- }\r
-\r
- } else if ((stricmp(Argv[0], "-r") == 0)) {\r
- //\r
- // Replace FFS files in BFV\r
- // BfmLib -r InFdName.Fd FfsName.ffs OutFdName.Fd -g FvNameGuid\r
- //\r
- if (Argc == 6) {\r
- mFvGuidIsSet = TRUE;\r
- mFvNameGuidString = Argv[5];\r
- StringToGuid (Argv[5], &mFvNameGuid);\r
- Argc -= 2;\r
- }\r
- if (Argc != 4) {\r
- return -1;\r
- }\r
- Status = BfmImageReplace (Argv[1], Argv[2], Argv[3]);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return -1;\r
- }\r
-\r
- } else {\r
- //\r
- // Invalid parameter.\r
- //\r
- return -1;\r
- }\r
-\r
- return 1;\r
-}\r
-\r