/** @file\r
This file contains functions required to generate a Firmware File System file.\r
\r
-Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
+#ifndef __GNUC__\r
+#include <windows.h>\r
+#include <io.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#endif\r
+\r
#include <stdio.h>\r
#include <stdlib.h>\r
#include <string.h>\r
#include "CommonLib.h"\r
#include "ParseInf.h"\r
#include "EfiUtilityMsgs.h"\r
+#include "FvLib.h"\r
+#include "PeCoffLib.h"\r
\r
#define UTILITY_NAME "GenFfs"\r
#define UTILITY_MAJOR_VERSION 0\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
+ "EFI_FV_FILETYPE_SMM_CORE", // 0x0D\r
+ "EFI_FV_FILETYPE_MM_STANDALONE", // 0x0E\r
+ "EFI_FV_FILETYPE_MM_CORE_STANDALONE" // 0x0F\r
+};\r
\r
STATIC CHAR8 *mAlignName[] = {\r
"1", "2", "4", "8", "16", "32", "64", "128", "256", "512",\r
- "1K", "2K", "4K", "8K", "16K", "32K", "64K"\r
+ "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",\r
+ "512K", "1M", "2M", "4M", "8M", "16M"\r
};\r
\r
STATIC CHAR8 *mFfsValidAlignName[] = {\r
- "8", "16", "128", "512", "1K", "4K", "32K", "64K"\r
+ "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K","256K",\r
+ "512K", "1M", "2M", "4M", "8M", "16M"\r
};\r
\r
-STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536};\r
+STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536, 131072, 262144,\r
+ 524288, 1048576, 2097152, 4194304, 8388608, 16777216};\r
\r
STATIC EFI_GUID mZeroGuid = {0};\r
\r
STATIC EFI_GUID mEfiFfsSectionAlignmentPaddingGuid = EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID;\r
\r
STATIC\r
-VOID \r
+VOID\r
Version (\r
VOID\r
)\r
Arguments:\r
\r
None\r
- \r
+\r
Returns:\r
\r
None\r
- \r
---*/ \r
+\r
+--*/\r
{\r
fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
}\r
// Summary usage\r
//\r
fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);\r
- \r
+\r
//\r
// Copyright declaration\r
- // \r
- fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
+ //\r
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
\r
//\r
// Details Option\r
EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION,\n\\r
EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\n\\r
EFI_FV_FILETYPE_SMM, EFI_FV_FILETYPE_SMM_CORE,\n\\r
+ EFI_FV_FILETYPE_MM_STANDALONE,\n\\r
+ EFI_FV_FILETYPE_MM_CORE_STANDALONE,\n\\r
EFI_FV_FILETYPE_COMBINED_SMM_DXE, \n\\r
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE.\n");\r
fprintf (stdout, " -g FileGuid, --fileguid FileGuid\n\\r
fprintf (stdout, " -s, --checksum Indicates to calculate file checksum.\n");\r
fprintf (stdout, " -a FileAlign, --align FileAlign\n\\r
FileAlign points to file alignment, which only support\n\\r
- the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n");\r
+ the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n\\r
+ 128K,256K,512K,1M,2M,4M,8M,16M\n");\r
fprintf (stdout, " -i SectionFile, --sectionfile SectionFile\n\\r
Section file will be contained in this FFS file.\n");\r
fprintf (stdout, " -n SectionAlign, --sectionalign SectionAlign\n\\r
SectionAlign points to section alignment, which support\n\\r
- the alignment scope 1~64K. It is specified together\n\\r
- with sectionfile to point its alignment in FFS file.\n");\r
+ the alignment scope 0~16M. If SectionAlign is specified\n\\r
+ as 0, tool get alignment value from SectionFile. It is\n\\r
+ specified together with sectionfile to point its\n\\r
+ alignment in FFS file.\n");\r
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");\r
fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");\r
\r
Routine Description:\r
\r
- Converts Align String to align value (1~64K). \r
+ Converts Align String to align value (1~16M).\r
\r
Arguments:\r
\r
--*/\r
{\r
UINT8 Index = 0;\r
- \r
+\r
if (String == NULL) {\r
return EFI_FV_FILETYPE_ALL;\r
}\r
OUT UINT8 *PESectionNum\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
- \r
+\r
Get the contents of all section files specified in InputFileName\r
into FileBuffer.\r
- \r
+\r
Arguments:\r
- \r
+\r
InputFileName - Name of the input file.\r
- \r
+\r
InputFileAlign - Alignment required by the input file data.\r
\r
InputFileNum - Number of input files. Should be at least 1.\r
\r
FileBuffer - Output buffer to contain data\r
\r
- BufferLength - On input, this is size of the FileBuffer. \r
+ BufferLength - On input, this is size of the FileBuffer.\r
On output, this is the actual length of the data.\r
\r
MaxAlignment - The max alignment required by all the input file datas.\r
- \r
+\r
PeSectionNum - Calculate the number of Pe/Te Section in this FFS file.\r
\r
Returns:\r
- \r
+\r
EFI_SUCCESS on successful return\r
EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.\r
EFI_ABORTED if unable to open input file.\r
while ((Size & 0x03) != 0) {\r
Size++;\r
}\r
- \r
- // \r
+\r
+ //\r
// Open file and read contents\r
//\r
InFile = fopen (LongFilePath (InputFileName[Index]), "rb");\r
fseek (InFile, 0, SEEK_END);\r
FileSize = ftell (InFile);\r
fseek (InFile, 0, SEEK_SET);\r
- DebugMsg (NULL, 0, 9, "Input section files", \r
- "the input section name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); \r
+ DebugMsg (NULL, 0, 9, "Input section files",\r
+ "the input section name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize);\r
\r
//\r
// Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.\r
}\r
}\r
(*PESectionNum) ++;\r
- } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION || \r
+ } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION ||\r
TempSectHeader.Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
//\r
- // for the encapsulated section, assume it contains Pe/Te section \r
+ // for the encapsulated section, assume it contains Pe/Te section\r
//\r
(*PESectionNum) ++;\r
}\r
if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {\r
Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
Offset = Offset - Size - HeaderSize - TeOffset;\r
- \r
+\r
if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
//\r
// The maximal alignment is 64K, the raw section size must be less than 0xffffff\r
SectHeader->CommonHeader.Type = EFI_SECTION_RAW;\r
}\r
}\r
- DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment", \r
+ DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment",\r
"Pad Raw section size is %u", (unsigned) Offset);\r
\r
Size = Size + Offset;\r
}\r
}\r
\r
+EFI_STATUS\r
+FfsRebaseImageRead (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINT32 *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+ /*++\r
+\r
+ Routine Description:\r
+\r
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+ Arguments:\r
+\r
+ FileHandle - The handle to the PE/COFF file\r
+\r
+ FileOffset - The offset, in bytes, into the file to read\r
+\r
+ ReadSize - The number of bytes to read from the file starting at FileOffset\r
+\r
+ Buffer - A pointer to the buffer to read the data into.\r
+\r
+ Returns:\r
+\r
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+ --*/\r
+{\r
+ CHAR8 *Destination8;\r
+ CHAR8 *Source8;\r
+ UINT32 Length;\r
+\r
+ Destination8 = Buffer;\r
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+ Length = *ReadSize;\r
+ while (Length--) {\r
+ *(Destination8++) = *(Source8++);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)\r
+ /*++\r
+ InFile is input file for getting alignment\r
+ return the alignment\r
+ --*/\r
+{\r
+ FILE *InFileHandle;\r
+ UINT8 *PeFileBuffer;\r
+ UINTN PeFileSize;\r
+ UINT32 CurSecHdrSize;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ EFI_COMMON_SECTION_HEADER *CommonHeader;\r
+ EFI_STATUS Status;\r
+\r
+ InFileHandle = NULL;\r
+ PeFileBuffer = NULL;\r
+ *Alignment = 0;\r
+\r
+ memset (&ImageContext, 0, sizeof (ImageContext));\r
+\r
+ InFileHandle = fopen(LongFilePath(InFile), "rb");\r
+ if (InFileHandle == NULL){\r
+ Error (NULL, 0, 0001, "Error opening file", InFile);\r
+ return EFI_ABORTED;\r
+ }\r
+ PeFileSize = _filelength (fileno(InFileHandle));\r
+ PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
+ if (PeFileBuffer == NULL) {\r
+ fclose (InFileHandle);\r
+ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);\r
+ fclose (InFileHandle);\r
+ CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;\r
+ CurSecHdrSize = GetSectionHeaderLength(CommonHeader);\r
+ ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);\r
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;\r
+ Status = PeCoffLoaderGetImageInfo(&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);\r
+ return Status;\r
+ }\r
+ *Alignment = ImageContext.SectionAlignment;\r
+ // Free the allocated memory resource\r
+ if (PeFileBuffer != NULL) {\r
+ free (PeFileBuffer);\r
+ PeFileBuffer = NULL;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
int\r
main (\r
int argc,\r
UINT64 LogLevel;\r
UINT8 PeSectionNum;\r
UINT32 HeaderSize;\r
- \r
+ UINT32 Alignment;\r
+ //\r
+ // Workaround for static code checkers.\r
+ // Ensures the size of 'AlignmentBuffer' can hold all the digits of an\r
+ // unsigned 32-bit integer plus the size unit character.\r
+ //\r
+ CHAR8 AlignmentBuffer[16];\r
+\r
//\r
// Init local variables\r
//\r
LogLevel = 0;\r
Index = 0;\r
- FfsAttrib = 0; \r
+ FfsAttrib = 0;\r
FfsAlign = 0;\r
FfsFiletype = EFI_FV_FILETYPE_ALL;\r
OutputFileName = NULL;\r
if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
Version ();\r
Usage ();\r
- return STATUS_SUCCESS; \r
+ return STATUS_SUCCESS;\r
}\r
\r
if (stricmp (argv[0], "--version") == 0) {\r
Version ();\r
- return STATUS_SUCCESS; \r
+ return STATUS_SUCCESS;\r
}\r
\r
while (argc > 0) {\r
}\r
argc -= 2;\r
argv += 2;\r
- continue; \r
+ continue;\r
}\r
\r
if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
OutputFileName = argv[1];\r
argc -= 2;\r
argv += 2;\r
- continue; \r
+ continue;\r
}\r
\r
if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--fileguid") == 0)) {\r
return STATUS_ERROR;\r
}\r
memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
- \r
+\r
InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
if (InputFileAlign == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
InputFileName,\r
(InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
);\r
- \r
+\r
if (InputFileName == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
free (InputFileAlign);\r
InputFileAlign,\r
(InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)\r
);\r
- \r
+\r
if (InputFileAlign == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
free (InputFileName);\r
}\r
memset (&(InputFileAlign[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));\r
}\r
- \r
+\r
InputFileName[InputFileNum] = argv[1];\r
argc -= 2;\r
argv += 2;\r
\r
if (argc <= 0) {\r
- InputFileNum ++;\r
+ InputFileNum ++;\r
break;\r
}\r
- \r
+\r
//\r
// Section File alignment requirement\r
//\r
if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {\r
- Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum]));\r
+ if ((argv[1] != NULL) && (stricmp("0", argv[1]) == 0)) {\r
+ Status = GetAlignmentFromFile(InputFileName[InputFileNum], &Alignment);\r
+ if (EFI_ERROR(Status)) {\r
+ Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);\r
+ goto Finish;\r
+ }\r
+ if (Alignment < 0x400){\r
+ sprintf (AlignmentBuffer, "%d", Alignment);\r
+ }\r
+ else if (Alignment >= 0x400) {\r
+ if (Alignment >= 0x100000) {\r
+ sprintf (AlignmentBuffer, "%dM", Alignment/0x100000);\r
+ } else {\r
+ sprintf (AlignmentBuffer, "%dK", Alignment/0x400);\r
+ }\r
+ }\r
+ Status = StringtoAlignment (AlignmentBuffer, &(InputFileAlign[InputFileNum]));\r
+ }\r
+ else {\r
+ Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum]));\r
+ }\r
if (EFI_ERROR (Status)) {\r
Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
goto Finish;\r
argv += 2;\r
}\r
InputFileNum ++;\r
- continue; \r
+ continue;\r
}\r
\r
if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {\r
continue;\r
}\r
\r
- Error (NULL, 0, 1000, "Unknown option", argv[0]);\r
+ Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);\r
goto Finish;\r
}\r
\r
//\r
if (FfsFiletype == EFI_FV_FILETYPE_ALL) {\r
Error (NULL, 0, 1001, "Missing option", "filetype");\r
- goto Finish; \r
+ goto Finish;\r
}\r
\r
if (CompareGuid (&FileGuid, &mZeroGuid) == 0) {\r
Error (NULL, 0, 1001, "Missing option", "fileguid");\r
- goto Finish; \r
+ goto Finish;\r
}\r
\r
if (InputFileNum == 0) {\r
Error (NULL, 0, 1001, "Missing option", "Input files");\r
goto Finish;\r
}\r
- \r
+\r
//\r
// Output input parameter information\r
//\r
VerboseMsg ("Fv File type is %s", mFfsFileType [FfsFiletype]);\r
VerboseMsg ("Output file name is %s", OutputFileName);\r
- VerboseMsg ("FFS File Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
+ VerboseMsg ("FFS File Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",\r
(unsigned) FileGuid.Data1,\r
FileGuid.Data2,\r
FileGuid.Data3,\r
}\r
VerboseMsg ("the %dth input section name is %s and section alignment is %u", Index, InputFileName[Index], (unsigned) InputFileAlign[Index]);\r
}\r
- \r
+\r
//\r
// Calculate the size of all input section files.\r
- // \r
+ //\r
Status = GetSectionContents (\r
InputFileName,\r
InputFileAlign,\r
&MaxAlignment,\r
&PeSectionNum\r
);\r
- \r
- if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE || \r
+\r
+ if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE ||\r
FfsFiletype == EFI_FV_FILETYPE_PEI_CORE ||\r
FfsFiletype == EFI_FV_FILETYPE_DXE_CORE) && (PeSectionNum != 1)) {\r
Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %u Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum);\r
goto Finish;\r
}\r
- \r
+\r
if ((FfsFiletype == EFI_FV_FILETYPE_PEIM ||\r
FfsFiletype == EFI_FV_FILETYPE_DRIVER ||\r
FfsFiletype == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER ||\r
FfsFiletype == EFI_FV_FILETYPE_APPLICATION) && (PeSectionNum < 1)) {\r
Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have at least one Pe or Te section, but no Pe/Te section is input", mFfsFileType [FfsFiletype]);\r
- goto Finish; \r
+ goto Finish;\r
}\r
\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
goto Finish;\r
}\r
memset (FileBuffer, 0, FileSize);\r
- \r
+\r
//\r
// read all input file contents into a buffer\r
//\r
);\r
}\r
\r
- if (EFI_ERROR (Status) || (FileBuffer == NULL)) {\r
+ if (EFI_ERROR (Status)) {\r
+ goto Finish;\r
+ }\r
+\r
+ if (FileBuffer == NULL && FileSize != 0) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
goto Finish;\r
}\r
- \r
+\r
//\r
// Create Ffs file header.\r
//\r
memcpy (&FfsFileHeader.Name, &FileGuid, sizeof (EFI_GUID));\r
FfsFileHeader.Type = FfsFiletype;\r
//\r
- // Update FFS Alignment based on the max alignment required by input section files \r
+ // Update FFS Alignment based on the max alignment required by input section files\r
//\r
- VerboseMsg ("the max alignment of all input sections is %u", (unsigned) MaxAlignment); \r
+ VerboseMsg ("the max alignment of all input sections is %u", (unsigned) MaxAlignment);\r
for (Index = 0; Index < sizeof (mFfsValidAlign) / sizeof (UINT32) - 1; Index ++) {\r
if ((MaxAlignment > mFfsValidAlign [Index]) && (MaxAlignment <= mFfsValidAlign [Index + 1])) {\r
break;\r
if (FfsAlign < Index) {\r
FfsAlign = Index;\r
}\r
- VerboseMsg ("the alignment of the generated FFS file is %u", (unsigned) mFfsValidAlign [FfsAlign + 1]); \r
- \r
+ VerboseMsg ("the alignment of the generated FFS file is %u", (unsigned) mFfsValidAlign [FfsAlign + 1]);\r
+\r
//\r
// Now FileSize includes the EFI_FFS_FILE_HEADER\r
//\r
}\r
VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);\r
\r
- FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));\r
+ //FfsAlign larger than 7, set FFS_ATTRIB_DATA_ALIGNMENT2\r
+ if (FfsAlign < 8) {\r
+ FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));\r
+ } else {\r
+ FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | ((FfsAlign & 0x7) << 3) | FFS_ATTRIB_DATA_ALIGNMENT2);\r
+ }\r
\r
//\r
// Fill in checksums and state, these must be zero for checksumming\r
// Ffs header checksum = zero, so only need to calculate ffs body.\r
//\r
FfsFileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
- FileBuffer, \r
+ FileBuffer,\r
FileSize - HeaderSize\r
- ); \r
+ );\r
} else {\r
FfsFileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
}\r
\r
FfsFileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;\r
- \r
+\r
//\r
// Open output file to write ffs data.\r
//\r
//\r
// write data\r
//\r
- fwrite (FileBuffer, 1, FileSize - HeaderSize, FfsFile);\r
+ if (FileBuffer != NULL) {\r
+ fwrite (FileBuffer, 1, FileSize - HeaderSize, FfsFile);\r
+ }\r
\r
fclose (FfsFile);\r
}\r