/** @file\r
+Creates output file that is a properly formed section per the PI spec.\r
\r
-Copyright (c) 2004 - 2011, 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
+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
-Module Name:\r
-\r
- GenSection.c\r
-\r
-Abstract:\r
-\r
- Creates output file that is a properly formed section per the PI spec.\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
**/\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 "Crc32.h"\r
#include "EfiUtilityMsgs.h"\r
#include "ParseInf.h"\r
+#include "FvLib.h"\r
+#include "PeCoffLib.h"\r
\r
//\r
// GenSec Tool Information\r
#define UTILITY_MAJOR_VERSION 0\r
#define UTILITY_MINOR_VERSION 1\r
\r
-#define MAX_SECTION_SIZE 0x1000000\r
-\r
STATIC CHAR8 *mSectionTypeName[] = {\r
NULL, // 0x00 - reserved\r
"EFI_SECTION_COMPRESSION", // 0x01\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
//\r
UINT32 CRC32Checksum;\r
} CRC32_SECTION_HEADER;\r
\r
+typedef struct {\r
+ EFI_GUID_DEFINED_SECTION2 GuidSectionHeader;\r
+ UINT32 CRC32Checksum;\r
+} CRC32_SECTION_HEADER2;\r
+\r
STATIC EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
STATIC EFI_GUID mEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_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] [input_file]\n\n", UTILITY_NAME);\r
- \r
+\r
//\r
// Copyright declaration\r
- // \r
- fprintf (stdout, "Copyright (c) 2007 - 2010, 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_SECTION_ALL is default section type.\n");\r
fprintf (stdout, " -c [Type], --compress [Type]\n\\r
Compress method type can be PI_NONE or PI_STD.\n\\r
- if -c option is not given, PI_STD is default type.\n"); \r
+ if -c option is not given, PI_STD is default type.\n");\r
fprintf (stdout, " -g GuidValue, --vendor GuidValue\n\\r
GuidValue is one specific vendor guid value.\n\\r
Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
fprintf (stdout, " -n String, --name String\n\\r
String is a NULL terminated string used in Ui section.\n");\r
fprintf (stdout, " -j Number, --buildnumber Number\n\\r
- Number is an integer value between 0000 and 9999\n\\r
+ Number is an integer value between 0 and 65535\n\\r
used in Ver section.\n");\r
fprintf (stdout, " --sectionalign SectionAlign\n\\r
SectionAlign points to section alignment, which support\n\\r
- the alignment scope 1~64K. It is specified in same\n\\r
- order that the section file is input.\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 in same order that the section file is input.\n");\r
+ fprintf (stdout, " --dummy dummyfile\n\\r
+ compare dummpyfile with input_file to decide whether\n\\r
+ need to set PROCESSING_REQUIRED attribute.\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
- Write ascii string as unicode string format to FILE \r
+ Write ascii string as unicode string format to FILE\r
\r
Arguments:\r
\r
// End the UniString with a NULL.\r
//\r
*UniString = '\0';\r
-} \r
+}\r
\r
STATUS\r
GenSectionCommonLeafSection (\r
UINT8 **OutFileBuffer\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
- \r
+\r
Generate a leaf section of type other than EFI_SECTION_VERSION\r
and EFI_SECTION_USER_INTERFACE. Input file must be well formed.\r
The function won't validate the input file's contents. For\r
common leaf sections, the input file may be a binary file.\r
The utility will add section header to the file.\r
- \r
+\r
Arguments:\r
- \r
+\r
InputFileName - Name of the input file.\r
- \r
+\r
InputFileNum - Number of input files. Should be 1 for leaf section.\r
\r
SectionType - A valid section type string\r
OutFileBuffer - Buffer pointer to Output file contents\r
\r
Returns:\r
- \r
+\r
STATUS_ERROR - can't continue\r
STATUS_SUCCESS - successful return\r
\r
FILE *InFile;\r
UINT8 *Buffer;\r
UINT32 TotalLength;\r
+ UINT32 HeaderLength;\r
EFI_COMMON_SECTION_HEADER *CommonSect;\r
STATUS Status;\r
\r
if (InputFileNum > 1) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "more than one input file specified");\r
+ Error (NULL, 0, 2000, "Invalid parameter", "more than one input file specified");\r
return STATUS_ERROR;\r
} else if (InputFileNum < 1) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "no input file specified");\r
+ Error (NULL, 0, 2000, "Invalid parameter", "no input file specified");\r
return STATUS_ERROR;\r
}\r
//\r
// Open the input file\r
//\r
- InFile = fopen (InputFileName[0], "rb");\r
+ InFile = fopen (LongFilePath (InputFileName[0]), "rb");\r
if (InFile == NULL) {\r
Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
return STATUS_ERROR;\r
//\r
// Size must fit in 3 bytes\r
//\r
+ //if (TotalLength >= MAX_SECTION_SIZE) {\r
+ // Error (NULL, 0, 2000, "Invalid parameter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);\r
+ // goto Done;\r
+ //}\r
+ HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER);\r
if (TotalLength >= MAX_SECTION_SIZE) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);\r
- goto Done;\r
+ TotalLength = sizeof (EFI_COMMON_SECTION_HEADER2) + InputFileLength;\r
+ HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER2);\r
}\r
VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
//\r
//\r
Buffer = (UINT8 *) malloc ((size_t) TotalLength);\r
if (Buffer == NULL) {\r
- Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); \r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
goto Done;\r
}\r
CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;\r
CommonSect->Type = SectionType;\r
- CommonSect->Size[0] = (UINT8) (TotalLength & 0xff);\r
- CommonSect->Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
- CommonSect->Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
- \r
+ if (TotalLength < MAX_SECTION_SIZE) {\r
+ CommonSect->Size[0] = (UINT8) (TotalLength & 0xff);\r
+ CommonSect->Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+ CommonSect->Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+ } else {\r
+ memset(CommonSect->Size, 0xff, sizeof(UINT8) * 3);\r
+ ((EFI_COMMON_SECTION_HEADER2 *)CommonSect)->ExtendedSize = TotalLength;\r
+ }\r
+\r
//\r
// read data from the input file.\r
//\r
if (InputFileLength != 0) {\r
- if (fread (Buffer + sizeof (EFI_COMMON_SECTION_HEADER), (size_t) InputFileLength, 1, InFile) != 1) {\r
+ if (fread (Buffer + HeaderLength, (size_t) InputFileLength, 1, InFile) != 1) {\r
Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);\r
goto Done;\r
}\r
}\r
\r
//\r
- // Set OutFileBuffer \r
+ // Set OutFileBuffer\r
//\r
*OutFileBuffer = Buffer;\r
Status = STATUS_SUCCESS;\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
UINT32 *BufferLength\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
InputFileAlign - Alignment required by the input file data.\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
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
UINT32 Index;\r
FILE *InFile;\r
EFI_COMMON_SECTION_HEADER *SectHeader;\r
- EFI_COMMON_SECTION_HEADER TempSectHeader;\r
+ EFI_COMMON_SECTION_HEADER2 TempSectHeader;\r
EFI_TE_IMAGE_HEADER TeHeader;\r
UINT32 TeOffset;\r
EFI_GUID_DEFINED_SECTION GuidSectHeader;\r
+ EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;\r
UINT32 HeaderSize;\r
\r
if (InputFileNum < 1) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "must specify at least one input file");\r
+ Error (NULL, 0, 2000, "Invalid parameter", "must specify at least one input file");\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if (BufferLength == NULL) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "BufferLength can't be NULL");\r
+ Error (NULL, 0, 2000, "Invalid parameter", "BufferLength can't be NULL");\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
}\r
Size++;\r
}\r
- \r
- // \r
+\r
+ //\r
// Open file and read contents\r
//\r
- InFile = fopen (InputFileName[Index], "rb");\r
+ InFile = fopen (LongFilePath (InputFileName[Index]), "rb");\r
if (InFile == NULL) {\r
Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);\r
return EFI_ABORTED;\r
fseek (InFile, 0, SEEK_END);\r
FileSize = ftell (InFile);\r
fseek (InFile, 0, SEEK_SET);\r
- DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); \r
+ DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize);\r
//\r
// Adjust section buffer when section alignment is required.\r
//\r
// Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.\r
//\r
TeOffset = 0;\r
- HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
- fread (&TempSectHeader, 1, sizeof (TempSectHeader), InFile);\r
+ //\r
+ // The section might be EFI_COMMON_SECTION_HEADER2\r
+ // But only Type needs to be checked\r
+ //\r
+ if (FileSize >= MAX_SECTION_SIZE) {\r
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);\r
+ } else {\r
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
+ }\r
+ fread (&TempSectHeader, 1, HeaderSize, InFile);\r
if (TempSectHeader.Type == EFI_SECTION_TE) {\r
fread (&TeHeader, 1, sizeof (TeHeader), InFile);\r
if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
}\r
} else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {\r
fseek (InFile, 0, SEEK_SET);\r
- fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);\r
- if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
- HeaderSize = GuidSectHeader.DataOffset;\r
+ if (FileSize >= MAX_SECTION_SIZE) {\r
+ fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);\r
+ if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+ HeaderSize = GuidSectHeader2.DataOffset;\r
+ }\r
+ } else {\r
+ fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);\r
+ if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+ HeaderSize = GuidSectHeader.DataOffset;\r
+ }\r
}\r
- } \r
+ }\r
\r
fseek (InFile, 0, SEEK_SET);\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
+ //\r
memset (FileBuffer + Size, 0, Offset);\r
SectHeader = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);\r
SectHeader->Type = EFI_SECTION_RAW;\r
fclose (InFile);\r
Size += FileSize;\r
}\r
- \r
+\r
//\r
// Set the real required buffer size.\r
//\r
UINT8 **OutFileBuffer\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
- \r
+\r
Generate an encapsulating section of type EFI_SECTION_COMPRESSION\r
Input file must be already sectioned. The function won't validate\r
- the input files' contents. Caller should hand in files already \r
+ the input files' contents. Caller should hand in files already\r
with section header.\r
- \r
+\r
Arguments:\r
- \r
+\r
InputFileName - Name of the input file.\r
\r
InputFileAlign - Alignment required by the input file data.\r
\r
InputFileNum - Number of input files. Should be at least 1.\r
\r
- SectCompSubType - Specify the compression algorithm requested. \r
- \r
+ SectCompSubType - Specify the compression algorithm requested.\r
+\r
OutFileBuffer - Buffer pointer to Output file contents\r
\r
Returns:\r
- \r
+\r
EFI_SUCCESS on successful return\r
EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
EFI_ABORTED if unable to open input file.\r
UINT32 TotalLength;\r
UINT32 InputLength;\r
UINT32 CompressedLength;\r
+ UINT32 HeaderLength;\r
UINT8 *FileBuffer;\r
UINT8 *OutputBuffer;\r
EFI_STATUS Status;\r
EFI_COMPRESSION_SECTION *CompressionSect;\r
+ EFI_COMPRESSION_SECTION2 *CompressionSect2;\r
COMPRESS_FUNCTION CompressFunction;\r
\r
InputLength = 0;\r
FileBuffer = NULL;\r
OutputBuffer = NULL;\r
CompressedLength = 0;\r
+ TotalLength = 0;\r
//\r
// read all input file contents into a buffer\r
// first get the size of all file contents\r
return Status;\r
}\r
\r
+ if (FileBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
CompressFunction = NULL;\r
\r
//\r
switch (SectCompSubType) {\r
case EFI_NOT_COMPRESSED:\r
CompressedLength = InputLength;\r
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION);\r
+ if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {\r
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);\r
+ }\r
+ TotalLength = CompressedLength + HeaderLength;\r
//\r
// Copy file buffer to the none compressed data.\r
//\r
- OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
+ OutputBuffer = malloc (TotalLength);\r
if (OutputBuffer == NULL) {\r
free (FileBuffer);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- memcpy (OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), FileBuffer, CompressedLength);\r
+ memcpy (OutputBuffer + HeaderLength, FileBuffer, CompressedLength);\r
+ free (FileBuffer);\r
FileBuffer = OutputBuffer;\r
break;\r
\r
break;\r
\r
default:\r
- Error (NULL, 0, 2000, "Invalid paramter", "unknown compression type");\r
+ Error (NULL, 0, 2000, "Invalid parameter", "unknown compression type");\r
free (FileBuffer);\r
return EFI_ABORTED;\r
}\r
\r
Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
- OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION);\r
+ if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {\r
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);\r
+ }\r
+ TotalLength = CompressedLength + HeaderLength;\r
+ OutputBuffer = malloc (TotalLength);\r
if (!OutputBuffer) {\r
free (FileBuffer);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), &CompressedLength);\r
+ Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + HeaderLength, &CompressedLength);\r
}\r
\r
free (FileBuffer);\r
\r
return Status;\r
}\r
- }\r
\r
- DebugMsg (NULL, 0, 9, "comprss file size", \r
- "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);\r
- TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);\r
- if (TotalLength >= MAX_SECTION_SIZE) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
- if (FileBuffer != NULL) {\r
- free (FileBuffer);\r
- }\r
- if (OutputBuffer != NULL) {\r
- free (OutputBuffer);\r
+ if (FileBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
- return STATUS_ERROR;\r
}\r
+\r
+ DebugMsg (NULL, 0, 9, "comprss file size",\r
+ "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);\r
+\r
+ //if (TotalLength >= MAX_SECTION_SIZE) {\r
+ // Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
+ // if (FileBuffer != NULL) {\r
+ // free (FileBuffer);\r
+ // }\r
+ // if (OutputBuffer != NULL) {\r
+ // free (OutputBuffer);\r
+ // }\r
+ // return STATUS_ERROR;\r
+ //}\r
VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
\r
//\r
// Add the section header for the compressed data\r
//\r
- CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
- \r
- CompressionSect->CommonHeader.Type = EFI_SECTION_COMPRESSION;\r
- CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
- CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
- CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
- CompressionSect->CompressionType = SectCompSubType;\r
- CompressionSect->UncompressedLength = InputLength;\r
+ if (TotalLength >= MAX_SECTION_SIZE) {\r
+ CompressionSect2 = (EFI_COMPRESSION_SECTION2 *)FileBuffer;\r
+\r
+ memset(CompressionSect2->CommonHeader.Size, 0xff, sizeof(UINT8) * 3);\r
+ CompressionSect2->CommonHeader.Type = EFI_SECTION_COMPRESSION;\r
+ CompressionSect2->CommonHeader.ExtendedSize = TotalLength;\r
+ CompressionSect2->CompressionType = SectCompSubType;\r
+ CompressionSect2->UncompressedLength = InputLength;\r
+ } else {\r
+ CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
+\r
+ CompressionSect->CommonHeader.Type = EFI_SECTION_COMPRESSION;\r
+ CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
+ CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+ CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+ CompressionSect->CompressionType = SectCompSubType;\r
+ CompressionSect->UncompressedLength = InputLength;\r
+ }\r
\r
//\r
- // Set OutFileBuffer \r
+ // Set OutFileBuffer\r
//\r
*OutFileBuffer = FileBuffer;\r
\r
UINT8 **OutFileBuffer\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
- \r
+\r
Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED\r
Input file must be already sectioned. The function won't validate\r
- the input files' contents. Caller should hand in files already \r
+ the input files' contents. Caller should hand in files already\r
with section header.\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
VendorGuid - Specify vendor guid value.\r
\r
- DataAttribute - Specify attribute for the vendor guid data. \r
- \r
+ DataAttribute - Specify attribute for the vendor guid data.\r
+\r
DataHeaderSize- Guided Data Header Size\r
- \r
+\r
OutFileBuffer - Buffer pointer to Output file contents\r
\r
Returns:\r
- \r
+\r
EFI_SUCCESS on successful return\r
EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
EFI_ABORTED if unable to open input file.\r
UINT32 Crc32Checksum;\r
EFI_STATUS Status;\r
CRC32_SECTION_HEADER *Crc32GuidSect;\r
+ CRC32_SECTION_HEADER2 *Crc32GuidSect2;\r
EFI_GUID_DEFINED_SECTION *VendorGuidSect;\r
+ EFI_GUID_DEFINED_SECTION2 *VendorGuidSect2;\r
\r
InputLength = 0;\r
Offset = 0;\r
FileBuffer = NULL;\r
-\r
- if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {\r
- Offset = sizeof (CRC32_SECTION_HEADER);\r
- } else {\r
- Offset = sizeof (EFI_GUID_DEFINED_SECTION);\r
- }\r
+ TotalLength = 0;\r
\r
//\r
// read all input file contents into a buffer\r
);\r
\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {\r
+ Offset = sizeof (CRC32_SECTION_HEADER);\r
+ if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
+ Offset = sizeof (CRC32_SECTION_HEADER2);\r
+ }\r
+ } else {\r
+ Offset = sizeof (EFI_GUID_DEFINED_SECTION);\r
+ if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
+ Offset = sizeof (EFI_GUID_DEFINED_SECTION2);\r
+ }\r
+ }\r
+ TotalLength = InputLength + Offset;\r
+\r
FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
if (FileBuffer == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
}\r
\r
if (InputLength == 0) {\r
+ if (FileBuffer != NULL) {\r
+ free (FileBuffer);\r
+ }\r
Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
return EFI_NOT_FOUND;\r
}\r
\r
+ //\r
+ // InputLength != 0, but FileBuffer == NULL means out of resources.\r
+ //\r
+ if (FileBuffer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
//\r
// Now data is in FileBuffer + Offset\r
//\r
Crc32Checksum = 0;\r
CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);\r
\r
- TotalLength = InputLength + sizeof (CRC32_SECTION_HEADER);\r
if (TotalLength >= MAX_SECTION_SIZE) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
- free (FileBuffer);\r
- return STATUS_ERROR;\r
+ Crc32GuidSect2 = (CRC32_SECTION_HEADER2 *) FileBuffer;\r
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) 0xff;\r
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) 0xff;\r
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) 0xff;\r
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.ExtendedSize = TotalLength;\r
+ memcpy (&(Crc32GuidSect2->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
+ Crc32GuidSect2->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+ Crc32GuidSect2->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER2);\r
+ Crc32GuidSect2->CRC32Checksum = Crc32Checksum;\r
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2->GuidSectionHeader.DataOffset);\r
+ } else {\r
+ Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;\r
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+ memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
+ Crc32GuidSect->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+ Crc32GuidSect->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);\r
+ Crc32GuidSect->CRC32Checksum = Crc32Checksum;\r
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
}\r
- \r
- Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;\r
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
- memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
- Crc32GuidSect->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
- Crc32GuidSect->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);\r
- Crc32GuidSect->CRC32Checksum = Crc32Checksum;\r
- DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
-\r
} else {\r
- TotalLength = InputLength + sizeof (EFI_GUID_DEFINED_SECTION);\r
if (TotalLength >= MAX_SECTION_SIZE) {\r
- Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
- free (FileBuffer);\r
- return STATUS_ERROR;\r
+ VendorGuidSect2 = (EFI_GUID_DEFINED_SECTION2 *) FileBuffer;\r
+ VendorGuidSect2->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
+ VendorGuidSect2->CommonHeader.Size[0] = (UINT8) 0xff;\r
+ VendorGuidSect2->CommonHeader.Size[1] = (UINT8) 0xff;\r
+ VendorGuidSect2->CommonHeader.Size[2] = (UINT8) 0xff;\r
+ VendorGuidSect2->CommonHeader.ExtendedSize = InputLength + sizeof (EFI_GUID_DEFINED_SECTION2);\r
+ memcpy (&(VendorGuidSect2->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
+ VendorGuidSect2->Attributes = DataAttribute;\r
+ VendorGuidSect2->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION2) + DataHeaderSize);\r
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2->DataOffset);\r
+ } else {\r
+ VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;\r
+ VendorGuidSect->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
+ VendorGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
+ VendorGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+ VendorGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+ memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
+ VendorGuidSect->Attributes = DataAttribute;\r
+ VendorGuidSect->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);\r
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);\r
}\r
-\r
- VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;\r
- VendorGuidSect->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
- VendorGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
- VendorGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
- VendorGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
- memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
- VendorGuidSect->Attributes = DataAttribute;\r
- VendorGuidSect->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);\r
- DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);\r
}\r
VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
- \r
+\r
//\r
- // Set OutFileBuffer \r
+ // Set OutFileBuffer\r
//\r
*OutFileBuffer = FileBuffer;\r
\r
return EFI_SUCCESS;\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
int VersionNumber;\r
UINT8 SectType;\r
UINT8 SectCompSubType;\r
- UINT16 SectGuidAttribute; \r
+ UINT16 SectGuidAttribute;\r
UINT64 SectGuidHeaderLength;\r
EFI_VERSION_SECTION *VersionSect;\r
EFI_USER_INTERFACE_SECTION *UiSect;\r
UINT64 LogLevel;\r
UINT32 *InputFileAlign;\r
UINT32 InputFileAlignNum;\r
+ EFI_COMMON_SECTION_HEADER *SectionHeader;\r
+ CHAR8 *DummyFileName;\r
+ FILE *DummyFile;\r
+ UINTN DummyFileSize;\r
+ UINT8 *DummyFileBuffer;\r
+ FILE *InFile;\r
+ UINT8 *InFileBuffer;\r
+ UINTN InFileSize;\r
\r
InputFileAlign = NULL;\r
InputFileAlignNum = 0;\r
SectGuidHeaderLength = 0;\r
VersionSect = NULL;\r
UiSect = NULL;\r
- \r
+ DummyFileSize = 0;\r
+ DummyFileName = NULL;\r
+ DummyFile = NULL;\r
+ DummyFileBuffer = NULL;\r
+ InFile = NULL;\r
+ InFileSize = 0;\r
+ InFileBuffer = NULL;\r
+\r
SetUtilityName (UTILITY_NAME);\r
- \r
+\r
if (argc == 1) {\r
Error (NULL, 0, 1001, "Missing options", "No options input");\r
Usage ();\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
}\r
argc -= 2;\r
argv += 2;\r
- continue; \r
+ continue;\r
}\r
\r
if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--compress") == 0)) {\r
argv += 2;\r
continue;\r
}\r
+ if (stricmp (argv[0], "--dummy") == 0) {\r
+ DummyFileName = argv[1];\r
+ if (DummyFileName == NULL) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");\r
+ goto Finish;\r
+ }\r
+ argc -= 2;\r
+ argv += 2;\r
+ continue;\r
+ }\r
\r
if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {\r
+ if (argv[1] == NULL) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");\r
+ goto Finish;\r
+ }\r
if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
} else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\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
- return 1;\r
+ goto Finish;\r
}\r
memset (InputFileAlign, 1, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
} else if (InputFileAlignNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
\r
if (InputFileAlign == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
- return 1;\r
+ goto Finish;\r
}\r
memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));\r
}\r
- \r
- Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
- goto Finish;\r
+ if (stricmp(argv[1], "0") == 0) {\r
+ InputFileAlign[InputFileAlignNum] = 0;\r
+ } else {\r
+ Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+ goto Finish;\r
+ }\r
}\r
argc -= 2;\r
argv += 2;\r
InputFileAlignNum ++;\r
- continue; \r
+ continue;\r
}\r
\r
//\r
InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
if (InputFileName == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
- return 1;\r
+ goto Finish;\r
}\r
memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
} else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
\r
if (InputFileName == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
- return 1;\r
+ goto Finish;\r
}\r
memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
}\r
Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");\r
goto Finish;\r
}\r
+ for (Index = 0; Index < InputFileAlignNum; Index++)\r
+ {\r
+ if (InputFileAlign[Index] == 0) {\r
+ Status = GetAlignmentFromFile(InputFileName[Index], &(InputFileAlign[Index]));\r
+ if (EFI_ERROR(Status)) {\r
+ Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);\r
+ goto Finish;\r
+ }\r
+ }\r
+ }\r
\r
VerboseMsg ("%s tool start.", UTILITY_NAME);\r
\r
+ if (DummyFileName != NULL) {\r
+ //\r
+ // Open file and read contents\r
+ //\r
+ DummyFile = fopen (LongFilePath (DummyFileName), "rb");\r
+ if (DummyFile == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening file", DummyFileName);\r
+ goto Finish;\r
+ }\r
+\r
+ fseek (DummyFile, 0, SEEK_END);\r
+ DummyFileSize = ftell (DummyFile);\r
+ fseek (DummyFile, 0, SEEK_SET);\r
+ DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);\r
+ if (DummyFileBuffer == NULL) {\r
+ fclose(DummyFile);\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+ goto Finish;\r
+ }\r
+\r
+ fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);\r
+ fclose(DummyFile);\r
+ DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);\r
+\r
+ if (InputFileName == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+ goto Finish;\r
+ }\r
+ InFile = fopen(LongFilePath(InputFileName[0]), "rb");\r
+ if (InFile == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
+ goto Finish;\r
+ }\r
+\r
+ fseek (InFile, 0, SEEK_END);\r
+ InFileSize = ftell (InFile);\r
+ fseek (InFile, 0, SEEK_SET);\r
+ InFileBuffer = (UINT8 *) malloc (InFileSize);\r
+ if (InFileBuffer == NULL) {\r
+ fclose(InFile);\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+ goto Finish;\r
+ }\r
+\r
+ fread(InFileBuffer, 1, InFileSize, InFile);\r
+ fclose(InFile);\r
+ DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);\r
+ if (InFileSize > DummyFileSize){\r
+ if (stricmp((CHAR8 *)DummyFileBuffer, (CHAR8 *)(InFileBuffer + (InFileSize - DummyFileSize))) == 0){\r
+ SectGuidHeaderLength = InFileSize - DummyFileSize;\r
+ }\r
+ }\r
+ if (SectGuidHeaderLength == 0) {\r
+ SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
+ }\r
+ if (DummyFileBuffer != NULL) {\r
+ free (DummyFileBuffer);\r
+ DummyFileBuffer = NULL;\r
+ }\r
+ if (InFileBuffer != NULL) {\r
+ free (InFileBuffer);\r
+ }\r
+ }\r
+\r
//\r
// Parse all command line parameters to get the corresponding section type.\r
//\r
VerboseMsg ("Compress method is %s", mCompressionTypeName [SectCompSubType]);\r
} else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
SectType = EFI_SECTION_GUID_DEFINED;\r
- \r
+\r
if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {\r
//\r
// NONE attribute, clear attribute value.\r
//\r
SectGuidAttribute = SectGuidAttribute & ~EFI_GUIDED_SECTION_NONE;\r
}\r
- VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
+ VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",\r
(unsigned) VendorGuid.Data1,\r
VendorGuid.Data2,\r
VendorGuid.Data3,\r
SectType = EFI_SECTION_SMM_DEPEX;\r
} else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_VERSION]) == 0) {\r
SectType = EFI_SECTION_VERSION;\r
- if (VersionNumber < 0 || VersionNumber > 9999) {\r
- Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~9999", VersionNumber);\r
+ if (VersionNumber < 0 || VersionNumber > 65535) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber);\r
goto Finish;\r
}\r
VerboseMsg ("Version section number is %d", VersionNumber);\r
Error (NULL, 0, 1003, "Invalid option value", "SectionType = %s", SectionName);\r
goto Finish;\r
}\r
- \r
+\r
//\r
// GuidValue is only required by Guided section.\r
//\r
- if ((SectType != EFI_SECTION_GUID_DEFINED) && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
+ if ((SectType != EFI_SECTION_GUID_DEFINED) &&\r
+ (SectionName != NULL) &&\r
+ (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
}\r
- \r
+\r
//\r
// Check whether there is input file\r
- // \r
+ //\r
if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {\r
//\r
// The input file are required for other section type.\r
OutFileBuffer,\r
&InputLength\r
);\r
- \r
+\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
OutFileBuffer = (UINT8 *) malloc (InputLength);\r
if (OutFileBuffer == NULL) {\r
);\r
break;\r
}\r
- \r
+\r
if (Status != EFI_SUCCESS || OutFileBuffer == NULL) {\r
Error (NULL, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status);\r
- goto Finish;\r
+ goto Finish;\r
}\r
\r
//\r
// Get output file length\r
//\r
if (SectType != EFI_SECTION_ALL) {\r
- InputLength = SECTION_SIZE (OutFileBuffer);\r
+ SectionHeader = (EFI_COMMON_SECTION_HEADER *)OutFileBuffer;\r
+ InputLength = *(UINT32 *)SectionHeader->Size & 0x00ffffff;\r
+ if (InputLength == 0xffffff) {\r
+ InputLength = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;\r
+ }\r
}\r
- \r
+\r
//\r
// Write the output file\r
//\r
- OutFile = fopen (OutputFileName, "wb");\r
+ OutFile = fopen (LongFilePath (OutputFileName), "wb");\r
if (OutFile == NULL) {\r
Error (NULL, 0, 0001, "Error opening file for writing", OutputFileName);\r
goto Finish;\r
if (OutFile != NULL) {\r
fclose (OutFile);\r
}\r
- \r
+\r
+ if (DummyFileBuffer != NULL) {\r
+ free (DummyFileBuffer);\r
+ }\r
+\r
VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
\r
return GetUtilityStatus ();\r