+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- GenSection.c\r
-\r
-Abstract:\r
-\r
- Creates output file that is a properly formed section per the FV spec.\r
-\r
---*/\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#include <Common/UefiBaseTypes.h>\r
-#include <Common/FirmwareVolumeImageFormat.h>\r
-#include <Protocol/GuidedSectionExtraction.h>\r
-\r
-#include "CommonLib.h"\r
-#include "Compress.h"\r
-#include "EfiCustomizedCompress.h"\r
-#include "Crc32.h"\r
-#include "EfiUtilityMsgs.h"\r
-#include "GenSection.h"\r
-\r
-\r
-#define UTILITY_NAME "GenSection"\r
-#define UTILITY_MAJOR_VERSION 0\r
-#define UTILITY_MINOR_VERSION 1\r
-\r
-\r
-#define PARAMETER_NOT_SPECIFIED "Parameter not specified"\r
-#define MAXIMUM_INPUT_FILE_NUM 10\r
-\r
-char *SectionTypeName[] = {\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
-};\r
-\r
-char *CompressionTypeName[] = { "NONE", "STANDARD" };\r
-char *GUIDedSectionTypeName[] = { "CRC32" };\r
-EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
-\r
-static\r
-void \r
-Version(\r
- void\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Print out version information for this utility.\r
-\r
-Arguments:\r
-\r
- None\r
- \r
-Returns:\r
-\r
- None\r
- \r
---*/ \r
-{\r
- printf ("%s v%d.%d -Utility to create output file with formed section per the FV spec.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
- printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");\r
-}\r
-\r
-static\r
-VOID\r
-Usage (\r
- VOID\r
- )\r
-{\r
- UINTN SectionType;\r
- UINTN DisplayCount;\r
-\r
- Version();\r
- \r
- printf ("\nUsage: "UTILITY_NAME " -i InputFile -o OutputFile -s SectionType [SectionType params]\n\n");\r
- printf (" Where SectionType is one of the following section types:\n\n");\r
-\r
- DisplayCount = 0;\r
- for (SectionType = 0; SectionType <= EFI_SECTION_LAST_SECTION_TYPE; SectionType++) {\r
- if (SectionTypeName[SectionType] != NULL) {\r
- printf (" %s\n", SectionTypeName[SectionType]);\r
- }\r
- }\r
-\r
- printf ("\n and SectionType dependent parameters are as follows:\n\n");\r
- printf (\r
- " %s: -t < %s | %s >\n",\r
- SectionTypeName[EFI_SECTION_COMPRESSION],\r
- CompressionTypeName[EFI_NOT_COMPRESSED],\r
- CompressionTypeName[EFI_STANDARD_COMPRESSION]\r
- );\r
- printf (\r
- " %s: -t < %s >\n"" // Currently only CRC32 is supported\n\n",\r
- SectionTypeName[EFI_SECTION_GUID_DEFINED],\r
- GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED]\r
- );\r
- printf (\r
- " %s: -v VersionNumber\n"" [-a \"Version string\"]\n\n",\r
- SectionTypeName[EFI_SECTION_VERSION]\r
- );\r
- printf (\r
- " %s: -a \"Human readable name\"\n\n",\r
- SectionTypeName[EFI_SECTION_USER_INTERFACE]\r
- );\r
-}\r
-\r
-VOID\r
-Ascii2UnicodeWriteString (\r
- char *String,\r
- FILE *OutFile,\r
- BOOLEAN WriteLangCode\r
- )\r
-{\r
- UINTN Index;\r
- UINT8 AsciiNull;\r
- //\r
- // BUGBUG need to get correct language code...\r
- //\r
- char *EnglishLangCode = "eng";\r
- AsciiNull = 0;\r
- //\r
- // first write the language code (english only)\r
- //\r
- if (WriteLangCode) {\r
- fwrite (EnglishLangCode, 1, 4, OutFile);\r
- }\r
- //\r
- // Next, write out the string... Convert ASCII to Unicode in the process.\r
- //\r
- Index = 0;\r
- do {\r
- fwrite (&String[Index], 1, 1, OutFile);\r
- fwrite (&AsciiNull, 1, 1, OutFile);\r
- } while (String[Index++] != 0);\r
-}\r
-\r
-STATUS\r
-GenSectionCommonLeafSection (\r
- char **InputFileName,\r
- int InputFileNum,\r
- UINTN SectionType,\r
- FILE *OutFile\r
- )\r
-/*++\r
- \r
-Routine Description:\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
-Arguments:\r
- \r
- InputFileName - Name of the input file.\r
- \r
- InputFileNum - Number of input files. Should be 1 for leaf section.\r
-\r
- SectionType - A valid section type string\r
-\r
- OutFile - Output file handle\r
-\r
-Returns:\r
- \r
- STATUS_ERROR - can't continue\r
- STATUS_SUCCESS - successful return\r
-\r
---*/\r
-{\r
- UINT64 InputFileLength;\r
- FILE *InFile;\r
- UINT8 *Buffer;\r
- INTN TotalLength;\r
- EFI_COMMON_SECTION_HEADER CommonSect;\r
- STATUS Status;\r
-\r
- if (InputFileNum > 1) {\r
- Error (NULL, 0, 0, "invalid parameter", "more than one input file specified");\r
- return STATUS_ERROR;\r
- } else if (InputFileNum < 1) {\r
- Error (NULL, 0, 0, "no input file specified", NULL);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Open the input file\r
- //\r
- InFile = fopen (InputFileName[0], "rb");\r
- if (InFile == NULL) {\r
- Error (NULL, 0, 0, InputFileName[0], "failed to open input file");\r
- return STATUS_ERROR;\r
- }\r
-\r
- Status = STATUS_ERROR;\r
- Buffer = NULL;\r
- //\r
- // Seek to the end of the input file so we can determine its size\r
- //\r
- fseek (InFile, 0, SEEK_END);\r
- fgetpos (InFile, &InputFileLength);\r
- fseek (InFile, 0, SEEK_SET);\r
- //\r
- // Fill in the fields in the local section header structure\r
- //\r
- CommonSect.Type = (EFI_SECTION_TYPE) SectionType;\r
- TotalLength = sizeof (CommonSect) + (INTN) InputFileLength;\r
- //\r
- // Size must fit in 3 bytes\r
- //\r
- if (TotalLength >= 0x1000000) {\r
- Error (NULL, 0, 0, InputFileName[0], "file size (0x%X) exceeds section size limit", TotalLength);\r
- goto Done;\r
- }\r
- //\r
- // Now copy the size into the section header and write out the section header\r
- //\r
- memcpy (&CommonSect.Size, &TotalLength, 3);\r
- fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
- //\r
- // Allocate a buffer to read in the contents of the input file. Then\r
- // read it in as one block and write it to the output file.\r
- //\r
- if (InputFileLength != 0) {\r
- Buffer = (UINT8 *) malloc ((size_t) InputFileLength);\r
- if (Buffer == NULL) {\r
- Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
- goto Done;\r
- }\r
-\r
- if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) {\r
- Error (NULL, 0, 0, InputFileName[0], "failed to read contents of file");\r
- goto Done;\r
- }\r
-\r
- if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) {\r
- Error (NULL, 0, 0, "failed to write to output file", NULL);\r
- goto Done;\r
- }\r
- }\r
-\r
- Status = STATUS_SUCCESS;\r
-Done:\r
- fclose (InFile);\r
- if (Buffer != NULL) {\r
- free (Buffer);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-GetSectionContents (\r
- char **InputFileName,\r
- int InputFileNum,\r
- UINT8 *FileBuffer,\r
- UINTN *BufferLength\r
- )\r
-/*++\r
- \r
-Routine Description:\r
- \r
- Get the contents of all section files specified in InputFileName\r
- into FileBuffer.\r
- \r
-Arguments:\r
- \r
- InputFileName - Name of the input file.\r
- \r
- InputFileNum - Number of input files. Should be at least 1.\r
-\r
- FileBuffer - Output buffer to contain data\r
-\r
- BufferLength - Actual length of the data \r
-\r
-Returns:\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
-\r
---*/\r
-{\r
- UINTN Size;\r
- UINTN FileSize;\r
- INTN Index;\r
- FILE *InFile;\r
-\r
- if (InputFileNum < 1) {\r
- Error (NULL, 0, 0, "must specify at least one input file", NULL);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Size = 0;\r
- //\r
- // Go through our array of file names and copy their contents\r
- // to the output buffer.\r
- //\r
- for (Index = 0; Index < InputFileNum; Index++) {\r
- InFile = fopen (InputFileName[Index], "rb");\r
- if (InFile == NULL) {\r
- Error (NULL, 0, 0, InputFileName[Index], "failed to open input file");\r
- return EFI_ABORTED;\r
- }\r
-\r
- fseek (InFile, 0, SEEK_END);\r
- FileSize = ftell (InFile);\r
- fseek (InFile, 0, SEEK_SET);\r
- //\r
- // Now read the contents of the file into the buffer\r
- //\r
- if (FileSize > 0) {\r
- if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {\r
- Error (NULL, 0, 0, InputFileName[Index], "failed to read contents of input file");\r
- fclose (InFile);\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- fclose (InFile);\r
- Size += (UINTN) FileSize;\r
- //\r
- // make sure section ends on a DWORD boundary\r
- //\r
- while ((Size & 0x03) != 0) {\r
- FileBuffer[Size] = 0;\r
- Size++;\r
- }\r
- }\r
-\r
- *BufferLength = Size;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GenSectionCompressionSection (\r
- char **InputFileName,\r
- int InputFileNum,\r
- UINTN SectionType,\r
- UINTN SectionSubType,\r
- FILE *OutFile\r
- )\r
-/*++\r
- \r
-Routine Description:\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
- with section header.\r
- \r
-Arguments:\r
- \r
- InputFileName - Name of the input file.\r
- \r
- InputFileNum - Number of input files. Should be at least 1.\r
-\r
- SectionType - Section type to generate. Should be \r
- EFI_SECTION_COMPRESSION\r
-\r
- SectionSubType - Specify the compression algorithm requested. \r
- \r
- OutFile - Output file handle\r
-\r
-Returns:\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
- EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
---*/\r
-{\r
- UINTN TotalLength;\r
- UINTN InputLength;\r
- UINTN CompressedLength;\r
- UINT8 *FileBuffer;\r
- UINT8 *OutputBuffer;\r
- EFI_STATUS Status;\r
- EFI_COMPRESSION_SECTION CompressionSect;\r
- COMPRESS_FUNCTION CompressFunction;\r
-\r
- if (SectionType != EFI_SECTION_COMPRESSION) {\r
- Error (NULL, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- InputLength = 0;\r
- FileBuffer = NULL;\r
- OutputBuffer = NULL;\r
- CompressedLength = 0;\r
- FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8));\r
- if (FileBuffer == NULL) {\r
- Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // read all input file contents into a buffer\r
- //\r
- Status = GetSectionContents (\r
- InputFileName,\r
- InputFileNum,\r
- FileBuffer,\r
- &InputLength\r
- );\r
- if (EFI_ERROR (Status)) {\r
- free (FileBuffer);\r
- return Status;\r
- }\r
-\r
- CompressFunction = NULL;\r
-\r
- //\r
- // Now data is in FileBuffer, compress the data\r
- //\r
- switch (SectionSubType) {\r
- case EFI_NOT_COMPRESSED:\r
- CompressedLength = InputLength;\r
- break;\r
-\r
- case EFI_STANDARD_COMPRESSION:\r
- CompressFunction = (COMPRESS_FUNCTION) EfiCompress;\r
- break;\r
-\r
- case EFI_CUSTOMIZED_COMPRESSION:\r
- CompressFunction = (COMPRESS_FUNCTION) CustomizedCompress;\r
- break;\r
-\r
- default:\r
- Error (NULL, 0, 0, "unknown compression type", NULL);\r
- free (FileBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (CompressFunction != NULL) {\r
-\r
- Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- OutputBuffer = malloc (CompressedLength);\r
- if (!OutputBuffer) {\r
- free (FileBuffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
- }\r
-\r
- free (FileBuffer);\r
- FileBuffer = OutputBuffer;\r
-\r
- if (EFI_ERROR (Status)) {\r
- if (FileBuffer != NULL) {\r
- free (FileBuffer);\r
- }\r
-\r
- return Status;\r
- }\r
- }\r
-\r
- TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);\r
- //\r
- // Add the section header for the compressed data\r
- //\r
- CompressionSect.CommonHeader.Type = (EFI_SECTION_TYPE) SectionType;\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 = (UINT8) SectionSubType;\r
- CompressionSect.UncompressedLength = InputLength;\r
-\r
- fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile);\r
- fwrite (FileBuffer, CompressedLength, 1, OutFile);\r
- free (FileBuffer);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GenSectionGuidDefinedSection (\r
- char **InputFileName,\r
- int InputFileNum,\r
- UINTN SectionType,\r
- UINTN SectionSubType,\r
- FILE *OutFile\r
- )\r
-/*++\r
- \r
-Routine Description:\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
- with section header.\r
- \r
-Arguments:\r
- \r
- InputFileName - Name of the input file.\r
- \r
- InputFileNum - Number of input files. Should be at least 1.\r
-\r
- SectionType - Section type to generate. Should be \r
- EFI_SECTION_GUID_DEFINED\r
-\r
- SectionSubType - Specify the authentication algorithm requested. \r
- \r
- OutFile - Output file handle\r
-\r
-Returns:\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
- EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
-\r
---*/\r
-{\r
- INTN TotalLength;\r
- INTN InputLength;\r
- UINT8 *FileBuffer;\r
- UINT32 Crc32Checksum;\r
- EFI_STATUS Status;\r
- CRC32_SECTION_HEADER Crc32GuidSect;\r
-\r
- if (SectionType != EFI_SECTION_GUID_DEFINED) {\r
- Error (NULL, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- InputLength = 0;\r
- FileBuffer = NULL;\r
- FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8));\r
- if (FileBuffer == NULL) {\r
- Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // read all input file contents into a buffer\r
- //\r
- Status = GetSectionContents (\r
- InputFileName,\r
- InputFileNum,\r
- FileBuffer,\r
- &InputLength\r
- );\r
- if (EFI_ERROR (Status)) {\r
- free (FileBuffer);\r
- return Status;\r
- }\r
- //\r
- // Now data is in FileBuffer, compress the data\r
- //\r
- switch (SectionSubType) {\r
- case EFI_SECTION_CRC32_GUID_DEFINED:\r
- Crc32Checksum = 0;\r
- CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum);\r
- if (EFI_ERROR (Status)) {\r
- free (FileBuffer);\r
- return Status;\r
- }\r
-\r
- TotalLength = InputLength + CRC32_SECTION_HEADER_SIZE;\r
- Crc32GuidSect.GuidSectionHeader.CommonHeader.Type = (EFI_SECTION_TYPE) SectionType;\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), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
- Crc32GuidSect.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
- Crc32GuidSect.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE;\r
- Crc32GuidSect.CRC32Checksum = Crc32Checksum;\r
-\r
- break;\r
-\r
- default:\r
- Error (NULL, 0, 0, "invalid parameter", "unknown GUID defined type");\r
- free (FileBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile);\r
- fwrite (FileBuffer, InputLength, 1, OutFile);\r
-\r
- free (FileBuffer);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-int\r
-main (\r
- int argc,\r
- char *argv[]\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Main\r
-\r
-Arguments:\r
-\r
- command line parameters\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Section header successfully generated and section concatenated.\r
- EFI_ABORTED Could not generate the section\r
- EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
-\r
---*/\r
-{\r
- INTN Index;\r
- INTN VersionNumber;\r
- UINTN SectionType;\r
- UINTN SectionSubType;\r
- BOOLEAN InputFileRequired;\r
- BOOLEAN SubTypeRequired;\r
- FILE *InFile;\r
- FILE *OutFile;\r
- INTN InputFileNum;\r
-\r
- char **InputFileName;\r
- char *OutputFileName;\r
- char AuxString[500] = { 0 };\r
-\r
- char *ParamSectionType;\r
- char *ParamSectionSubType;\r
- char *ParamLength;\r
- char *ParamVersion;\r
- char *ParamDigitalSignature;\r
-\r
- EFI_STATUS Status;\r
- EFI_COMMON_SECTION_HEADER CommonSect;\r
-\r
- InputFileName = NULL;\r
- OutputFileName = PARAMETER_NOT_SPECIFIED;\r
- ParamSectionType = PARAMETER_NOT_SPECIFIED;\r
- ParamSectionSubType = PARAMETER_NOT_SPECIFIED;\r
- ParamLength = PARAMETER_NOT_SPECIFIED;\r
- ParamVersion = PARAMETER_NOT_SPECIFIED;\r
- ParamDigitalSignature = PARAMETER_NOT_SPECIFIED;\r
- Status = EFI_SUCCESS;\r
-\r
- VersionNumber = 0;\r
- SectionType = 0;\r
- SectionSubType = 0;\r
- InputFileRequired = TRUE;\r
- SubTypeRequired = FALSE;\r
- InFile = NULL;\r
- OutFile = NULL;\r
- InputFileNum = 0;\r
- Status = EFI_SUCCESS;\r
-\r
- SetUtilityName (UTILITY_NAME);\r
- \r
- if (argc == 1) {\r
- Usage ();\r
- return STATUS_ERROR;\r
- }\r
- \r
- if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
- (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
- Usage();\r
- return STATUS_ERROR;\r
- }\r
- \r
- if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
- Version();\r
- return STATUS_ERROR;\r
- }\r
-\r
- //\r
- // Parse command line\r
- //\r
- Index = 1;\r
- while (Index < argc) {\r
- if (strcmpi (argv[Index], "-i") == 0) {\r
- //\r
- // Input File found\r
- //\r
- Index++;\r
- InputFileName = (char **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (char *));\r
- if (InputFileName == NULL) {\r
- Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)));\r
- InputFileName[InputFileNum] = argv[Index];\r
- InputFileNum++;\r
- Index++;\r
- //\r
- // Parse subsequent parameters until another switch is encountered\r
- //\r
- while ((Index < argc) && (argv[Index][0] != '-')) {\r
- if ((InputFileNum % MAXIMUM_INPUT_FILE_NUM) == 0) {\r
- //\r
- // InputFileName buffer too small, need to realloc\r
- //\r
- InputFileName = (char **) realloc (\r
- InputFileName,\r
- (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (char *)\r
- );\r
- if (InputFileName == NULL) {\r
- Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)));\r
- }\r
-\r
- InputFileName[InputFileNum] = argv[Index];\r
- InputFileNum++;\r
- Index++;\r
- }\r
-\r
- }\r
-\r
- if (strcmpi (argv[Index], "-o") == 0) {\r
- //\r
- // Output file found\r
- //\r
- Index++;\r
- OutputFileName = argv[Index];\r
- } else if (strcmpi (argv[Index], "-s") == 0) {\r
- //\r
- // Section Type found\r
- //\r
- Index++;\r
- ParamSectionType = argv[Index];\r
- } else if (strcmpi (argv[Index], "-t") == 0) {\r
- //\r
- // Compression or Authentication type\r
- //\r
- Index++;\r
- ParamSectionSubType = argv[Index];\r
- } else if (strcmpi (argv[Index], "-l") == 0) {\r
- //\r
- // Length\r
- //\r
- Index++;\r
- ParamLength = argv[Index];\r
- } else if (strcmpi (argv[Index], "-v") == 0) {\r
- //\r
- // VersionNumber\r
- //\r
- Index++;\r
- ParamVersion = argv[Index];\r
- } else if (strcmpi (argv[Index], "-a") == 0) {\r
- //\r
- // Aux string\r
- //\r
- Index++;\r
- //\r
- // Note, the MSVC C-Start parses out and consolidates quoted strings from the command\r
- // line. Quote characters are stripped. If this tool is ported to other environments\r
- // this will need to be taken into account\r
- //\r
- strncpy (AuxString, argv[Index], 499);\r
- } else if (strcmpi (argv[Index], "-d") == 0) {\r
- //\r
- // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)\r
- //\r
- Index++;\r
- ParamDigitalSignature = argv[Index];\r
- } else if (strcmpi (argv[Index], "-?") == 0) {\r
- Usage ();\r
- return STATUS_ERROR;\r
- } else {\r
- Error (NULL, 0, 0, argv[Index], "unknown option");\r
- return GetUtilityStatus ();\r
- }\r
-\r
- Index++;\r
- }\r
- //\r
- // At this point, all command line parameters are verified as not being totally\r
- // bogus. Next verify the command line parameters are complete and make\r
- // sense...\r
- //\r
- if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {\r
- SectionType = EFI_SECTION_COMPRESSION;\r
- SubTypeRequired = TRUE;\r
- if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {\r
- SectionSubType = EFI_NOT_COMPRESSED;\r
- } else if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {\r
- SectionSubType = EFI_STANDARD_COMPRESSION;\r
- } else {\r
- Error (NULL, 0, 0, ParamSectionSubType, "unknown compression type");\r
- Usage ();\r
- return GetUtilityStatus ();\r
- }\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
- SectionType = EFI_SECTION_GUID_DEFINED;\r
- SubTypeRequired = TRUE;\r
- if (stricmp (ParamSectionSubType, GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED]) == 0) {\r
- SectionSubType = EFI_SECTION_CRC32_GUID_DEFINED;\r
- } else {\r
- Error (NULL, 0, 0, ParamSectionSubType, "unknown GUID defined section type", ParamSectionSubType);\r
- Usage ();\r
- return GetUtilityStatus ();\r
- }\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PE32]) == 0) {\r
- SectionType = EFI_SECTION_PE32;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PIC]) == 0) {\r
- SectionType = EFI_SECTION_PIC;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_TE]) == 0) {\r
- SectionType = EFI_SECTION_TE;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {\r
- SectionType = EFI_SECTION_DXE_DEPEX;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_VERSION]) == 0) {\r
- SectionType = EFI_SECTION_VERSION;\r
- InputFileRequired = FALSE;\r
- Index = sscanf (ParamVersion, "%d", &VersionNumber);\r
- if (Index != 1 || VersionNumber < 0 || VersionNumber > 65565) {\r
- Error (NULL, 0, 0, ParamVersion, "illegal version number");\r
- Usage ();\r
- return GetUtilityStatus ();\r
- }\r
-\r
- if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) {\r
- AuxString[0] = 0;\r
- }\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {\r
- SectionType = EFI_SECTION_USER_INTERFACE;\r
- InputFileRequired = FALSE;\r
- if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) {\r
- Error (NULL, 0, 0, "user interface string not specified", NULL);\r
- Usage ();\r
- return GetUtilityStatus ();\r
- }\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {\r
- SectionType = EFI_SECTION_COMPATIBILITY16;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {\r
- SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {\r
- SectionType = EFI_SECTION_FREEFORM_SUBTYPE_GUID;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_RAW]) == 0) {\r
- SectionType = EFI_SECTION_RAW;\r
- } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {\r
- SectionType = EFI_SECTION_PEI_DEPEX;\r
- } else {\r
- Error (NULL, 0, 0, ParamSectionType, "unknown section type");\r
- Usage ();\r
- return GetUtilityStatus ();\r
- }\r
- //\r
- // Open output file\r
- //\r
- OutFile = fopen (OutputFileName, "wb");\r
- if (OutFile == NULL) {\r
- Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");\r
- if (InFile != NULL) {\r
- fclose (InFile);\r
- }\r
-\r
- return GetUtilityStatus ();\r
- }\r
- //\r
- // At this point, we've fully validated the command line, and opened appropriate\r
- // files, so let's go and do what we've been asked to do...\r
- //\r
- //\r
- // Within this switch, build and write out the section header including any\r
- // section type specific pieces. If there's an input file, it's tacked on later\r
- //\r
- switch (SectionType) {\r
- case EFI_SECTION_COMPRESSION:\r
- Status = GenSectionCompressionSection (\r
- InputFileName,\r
- InputFileNum,\r
- SectionType,\r
- SectionSubType,\r
- OutFile\r
- );\r
- break;\r
-\r
- case EFI_SECTION_GUID_DEFINED:\r
- Status = GenSectionGuidDefinedSection (\r
- InputFileName,\r
- InputFileNum,\r
- SectionType,\r
- SectionSubType,\r
- OutFile\r
- );\r
- break;\r
-\r
- case EFI_SECTION_VERSION:\r
- CommonSect.Type = (EFI_SECTION_TYPE) SectionType;\r
-\r
- Index = sizeof (CommonSect);\r
- //\r
- // 2 characters for the build number\r
- //\r
- Index += 2;\r
- //\r
- // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
- //\r
- Index += (strlen (AuxString) * 2) + 2;\r
- memcpy (&CommonSect.Size, &Index, 3);\r
- fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
- fwrite (&VersionNumber, 2, 1, OutFile);\r
- Ascii2UnicodeWriteString (AuxString, OutFile, FALSE);\r
- break;\r
-\r
- case EFI_SECTION_USER_INTERFACE:\r
- CommonSect.Type = (EFI_SECTION_TYPE) SectionType;\r
- Index = sizeof (CommonSect);\r
- //\r
- // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
- //\r
- Index += (strlen (AuxString) * 2) + 2;\r
- memcpy (&CommonSect.Size, &Index, 3);\r
- fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
- Ascii2UnicodeWriteString (AuxString, OutFile, FALSE);\r
- break;\r
-\r
- default:\r
- //\r
- // All other section types are caught by default (they're all the same)\r
- //\r
- Status = GenSectionCommonLeafSection (\r
- InputFileName,\r
- InputFileNum,\r
- SectionType,\r
- OutFile\r
- );\r
- break;\r
- }\r
-\r
- if (InputFileName != NULL) {\r
- free (InputFileName);\r
- }\r
-\r
- fclose (OutFile);\r
- //\r
- // If we had errors, then delete the output file\r
- //\r
- if (GetUtilityStatus () == STATUS_ERROR) {\r
- remove (OutputFileName);\r
- }\r
-\r
- return GetUtilityStatus ();\r
-}\r