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