gensection.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 938 行 · 第 1/2 页
C
938 行
//
// 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 ();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?