2 Creates output file that is a properly formed section per the PI spec.
4 Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include <Common/UefiBaseTypes.h>
21 #include <Common/PiFirmwareFile.h>
22 #include <Protocol/GuidedSectionExtraction.h>
23 #include <IndustryStandard/PeImage.h>
25 #include "CommonLib.h"
28 #include "EfiUtilityMsgs.h"
32 // GenSec Tool Information
34 #define UTILITY_NAME "GenSec"
35 #define UTILITY_MAJOR_VERSION 0
36 #define UTILITY_MINOR_VERSION 1
38 STATIC CHAR8
*mSectionTypeName
[] = {
39 NULL
, // 0x00 - reserved
40 "EFI_SECTION_COMPRESSION", // 0x01
41 "EFI_SECTION_GUID_DEFINED", // 0x02
42 NULL
, // 0x03 - reserved
43 NULL
, // 0x04 - reserved
44 NULL
, // 0x05 - reserved
45 NULL
, // 0x06 - reserved
46 NULL
, // 0x07 - reserved
47 NULL
, // 0x08 - reserved
48 NULL
, // 0x09 - reserved
49 NULL
, // 0x0A - reserved
50 NULL
, // 0x0B - reserved
51 NULL
, // 0x0C - reserved
52 NULL
, // 0x0D - reserved
53 NULL
, // 0x0E - reserved
54 NULL
, // 0x0F - reserved
55 "EFI_SECTION_PE32", // 0x10
56 "EFI_SECTION_PIC", // 0x11
57 "EFI_SECTION_TE", // 0x12
58 "EFI_SECTION_DXE_DEPEX", // 0x13
59 "EFI_SECTION_VERSION", // 0x14
60 "EFI_SECTION_USER_INTERFACE", // 0x15
61 "EFI_SECTION_COMPATIBILITY16", // 0x16
62 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17
63 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18
64 "EFI_SECTION_RAW", // 0x19
66 "EFI_SECTION_PEI_DEPEX", // 0x1B
67 "EFI_SECTION_SMM_DEPEX" // 0x1C
70 STATIC CHAR8
*mCompressionTypeName
[] = { "PI_NONE", "PI_STD" };
72 #define EFI_GUIDED_SECTION_NONE 0x80
73 STATIC CHAR8
*mGUIDedSectionAttribue
[] = { "NONE", "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};
75 STATIC CHAR8
*mAlignName
[] = {
76 "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
77 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",
78 "512K", "1M", "2M", "4M", "8M", "16M"
82 // Crc32 GUID section related definitions.
85 EFI_GUID_DEFINED_SECTION GuidSectionHeader
;
87 } CRC32_SECTION_HEADER
;
90 EFI_GUID_DEFINED_SECTION2 GuidSectionHeader
;
92 } CRC32_SECTION_HEADER2
;
94 STATIC EFI_GUID mZeroGuid
= {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
95 STATIC EFI_GUID mEfiCrc32SectionGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
106 Print out version information for this utility.
118 fprintf (stdout
, "%s Version %d.%d %s \n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
145 fprintf (stdout
, "\nUsage: %s [options] [input_file]\n\n", UTILITY_NAME
);
148 // Copyright declaration
150 fprintf (stdout
, "Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.\n\n");
155 fprintf (stdout
, "Options:\n");
156 fprintf (stdout
, " -o FileName, --outputfile FileName\n\
157 File is the SectionFile to be created.\n");
158 fprintf (stdout
, " -s [SectionType], --sectiontype [SectionType]\n\
159 SectionType defined in PI spec is one type of\n\
160 EFI_SECTION_COMPRESSION, EFI_SECTION_GUID_DEFINED,\n\
161 EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE,\n\
162 EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16,\n\
163 EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION,\n\
164 EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW,\n\
165 EFI_SECTION_FREEFORM_SUBTYPE_GUID,\n\
166 EFI_SECTION_PEI_DEPEX, EFI_SECTION_SMM_DEPEX.\n\
167 if -s option is not given, \n\
168 EFI_SECTION_ALL is default section type.\n");
169 fprintf (stdout
, " -c [Type], --compress [Type]\n\
170 Compress method type can be PI_NONE or PI_STD.\n\
171 if -c option is not given, PI_STD is default type.\n");
172 fprintf (stdout
, " -g GuidValue, --vendor GuidValue\n\
173 GuidValue is one specific vendor guid value.\n\
174 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
175 fprintf (stdout
, " -l GuidHeaderLength, --HeaderLength GuidHeaderLength\n\
176 GuidHeaderLength is the size of header of guided data\n");
177 fprintf (stdout
, " -r GuidAttr, --attributes GuidAttr\n\
178 GuidAttr is guid section atttributes, which may be\n\
179 PROCESSING_REQUIRED, AUTH_STATUS_VALID and NONE. \n\
180 if -r option is not given, default PROCESSING_REQUIRED\n");
181 fprintf (stdout
, " -n String, --name String\n\
182 String is a NULL terminated string used in Ui section.\n");
183 fprintf (stdout
, " -j Number, --buildnumber Number\n\
184 Number is an integer value between 0 and 65535\n\
185 used in Ver section.\n");
186 fprintf (stdout
, " --sectionalign SectionAlign\n\
187 SectionAlign points to section alignment, which support\n\
188 the alignment scope 1~16M. It is specified in same\n\
189 order that the section file is input.\n");
190 fprintf (stdout
, " --dummy dummyfile\n\
191 compare dummpyfile with input_file to decide whether\n\
192 need to set PROCESSING_REQUIRED attribute.\n");
193 fprintf (stdout
, " -v, --verbose Turn on verbose output with informational messages.\n");
194 fprintf (stdout
, " -q, --quiet Disable all messages except key message and fatal error\n");
195 fprintf (stdout
, " -d, --debug level Enable debug messages, at input debug level.\n");
196 fprintf (stdout
, " --version Show program's version number and exit.\n");
197 fprintf (stdout
, " -h, --help Show this help message and exit.\n");
201 Ascii2UnicodeString (
209 Write ascii string as unicode string format to FILE
213 String - Pointer to string that is written to FILE.
214 UniString - Pointer to unicode string
222 while (*String
!= '\0') {
223 *(UniString
++) = (CHAR16
) *(String
++);
226 // End the UniString with a NULL.
232 GenSectionCommonLeafSection (
233 CHAR8
**InputFileName
,
236 UINT8
**OutFileBuffer
242 Generate a leaf section of type other than EFI_SECTION_VERSION
243 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
244 The function won't validate the input file's contents. For
245 common leaf sections, the input file may be a binary file.
246 The utility will add section header to the file.
250 InputFileName - Name of the input file.
252 InputFileNum - Number of input files. Should be 1 for leaf section.
254 SectionType - A valid section type string
256 OutFileBuffer - Buffer pointer to Output file contents
260 STATUS_ERROR - can't continue
261 STATUS_SUCCESS - successful return
265 UINT32 InputFileLength
;
270 EFI_COMMON_SECTION_HEADER
*CommonSect
;
273 if (InputFileNum
> 1) {
274 Error (NULL
, 0, 2000, "Invalid parameter", "more than one input file specified");
276 } else if (InputFileNum
< 1) {
277 Error (NULL
, 0, 2000, "Invalid parameter", "no input file specified");
281 // Open the input file
283 InFile
= fopen (LongFilePath (InputFileName
[0]), "rb");
284 if (InFile
== NULL
) {
285 Error (NULL
, 0, 0001, "Error opening file", InputFileName
[0]);
289 Status
= STATUS_ERROR
;
292 // Seek to the end of the input file so we can determine its size
294 fseek (InFile
, 0, SEEK_END
);
295 InputFileLength
= ftell (InFile
);
296 fseek (InFile
, 0, SEEK_SET
);
297 DebugMsg (NULL
, 0, 9, "Input file", "File name is %s and File size is %u bytes", InputFileName
[0], (unsigned) InputFileLength
);
298 TotalLength
= sizeof (EFI_COMMON_SECTION_HEADER
) + InputFileLength
;
300 // Size must fit in 3 bytes
302 //if (TotalLength >= MAX_SECTION_SIZE) {
303 // Error (NULL, 0, 2000, "Invalid parameter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);
306 HeaderLength
= sizeof (EFI_COMMON_SECTION_HEADER
);
307 if (TotalLength
>= MAX_SECTION_SIZE
) {
308 TotalLength
= sizeof (EFI_COMMON_SECTION_HEADER2
) + InputFileLength
;
309 HeaderLength
= sizeof (EFI_COMMON_SECTION_HEADER2
);
311 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
313 // Fill in the fields in the local section header structure
315 Buffer
= (UINT8
*) malloc ((size_t) TotalLength
);
316 if (Buffer
== NULL
) {
317 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
320 CommonSect
= (EFI_COMMON_SECTION_HEADER
*) Buffer
;
321 CommonSect
->Type
= SectionType
;
322 if (TotalLength
< MAX_SECTION_SIZE
) {
323 CommonSect
->Size
[0] = (UINT8
) (TotalLength
& 0xff);
324 CommonSect
->Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
325 CommonSect
->Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
327 memset(CommonSect
->Size
, 0xff, sizeof(UINT8
) * 3);
328 ((EFI_COMMON_SECTION_HEADER2
*)CommonSect
)->ExtendedSize
= TotalLength
;
332 // read data from the input file.
334 if (InputFileLength
!= 0) {
335 if (fread (Buffer
+ HeaderLength
, (size_t) InputFileLength
, 1, InFile
) != 1) {
336 Error (NULL
, 0, 0004, "Error reading file", InputFileName
[0]);
344 *OutFileBuffer
= Buffer
;
345 Status
= STATUS_SUCCESS
;
356 IN CHAR8
*AlignBuffer
,
357 OUT UINT32
*AlignNumber
363 Converts Align String to align value (1~16M).
367 AlignBuffer - Pointer to Align string.
368 AlignNumber - Pointer to Align value.
372 EFI_SUCCESS Successfully convert align string to align value.
373 EFI_INVALID_PARAMETER Align string is invalid or align value is not in scope.
381 if (AlignBuffer
== NULL
) {
382 return EFI_INVALID_PARAMETER
;
384 for (Index
= 0; Index
< sizeof (mAlignName
) / sizeof (CHAR8
*); Index
++) {
385 if (stricmp (AlignBuffer
, mAlignName
[Index
]) == 0) {
386 *AlignNumber
= 1 << Index
;
390 return EFI_INVALID_PARAMETER
;
395 CHAR8
**InputFileName
,
396 UINT32
*InputFileAlign
,
405 Get the contents of all section files specified in InputFileName
410 InputFileName - Name of the input file.
412 InputFileAlign - Alignment required by the input file data.
414 InputFileNum - Number of input files. Should be at least 1.
416 FileBuffer - Output buffer to contain data
418 BufferLength - On input, this is size of the FileBuffer.
419 On output, this is the actual length of the data.
423 EFI_SUCCESS on successful return
424 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
425 EFI_ABORTED if unable to open input file.
426 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
434 EFI_COMMON_SECTION_HEADER
*SectHeader
;
435 EFI_COMMON_SECTION_HEADER2 TempSectHeader
;
436 EFI_TE_IMAGE_HEADER TeHeader
;
438 EFI_GUID_DEFINED_SECTION GuidSectHeader
;
439 EFI_GUID_DEFINED_SECTION2 GuidSectHeader2
;
442 if (InputFileNum
< 1) {
443 Error (NULL
, 0, 2000, "Invalid parameter", "must specify at least one input file");
444 return EFI_INVALID_PARAMETER
;
447 if (BufferLength
== NULL
) {
448 Error (NULL
, 0, 2000, "Invalid parameter", "BufferLength can't be NULL");
449 return EFI_INVALID_PARAMETER
;
456 // Go through our array of file names and copy their contents
457 // to the output buffer.
459 for (Index
= 0; Index
< InputFileNum
; Index
++) {
461 // make sure section ends on a DWORD boundary
463 while ((Size
& 0x03) != 0) {
464 if (FileBuffer
!= NULL
&& Size
< *BufferLength
) {
465 FileBuffer
[Size
] = 0;
471 // Open file and read contents
473 InFile
= fopen (LongFilePath (InputFileName
[Index
]), "rb");
474 if (InFile
== NULL
) {
475 Error (NULL
, 0, 0001, "Error opening file", InputFileName
[Index
]);
479 fseek (InFile
, 0, SEEK_END
);
480 FileSize
= ftell (InFile
);
481 fseek (InFile
, 0, SEEK_SET
);
482 DebugMsg (NULL
, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName
[Index
], (unsigned) FileSize
);
484 // Adjust section buffer when section alignment is required.
486 if (InputFileAlign
!= NULL
) {
488 // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
492 // The section might be EFI_COMMON_SECTION_HEADER2
493 // But only Type needs to be checked
495 if (FileSize
>= MAX_SECTION_SIZE
) {
496 HeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER2
);
498 HeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER
);
500 fread (&TempSectHeader
, 1, HeaderSize
, InFile
);
501 if (TempSectHeader
.Type
== EFI_SECTION_TE
) {
502 fread (&TeHeader
, 1, sizeof (TeHeader
), InFile
);
503 if (TeHeader
.Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
504 TeOffset
= TeHeader
.StrippedSize
- sizeof (TeHeader
);
506 } else if (TempSectHeader
.Type
== EFI_SECTION_GUID_DEFINED
) {
507 fseek (InFile
, 0, SEEK_SET
);
508 if (FileSize
>= MAX_SECTION_SIZE
) {
509 fread (&GuidSectHeader2
, 1, sizeof (GuidSectHeader2
), InFile
);
510 if ((GuidSectHeader2
.Attributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
511 HeaderSize
= GuidSectHeader2
.DataOffset
;
514 fread (&GuidSectHeader
, 1, sizeof (GuidSectHeader
), InFile
);
515 if ((GuidSectHeader
.Attributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
516 HeaderSize
= GuidSectHeader
.DataOffset
;
521 fseek (InFile
, 0, SEEK_SET
);
524 // Revert TeOffset to the converse value relative to Alignment
525 // This is to assure the original PeImage Header at Alignment.
528 TeOffset
= InputFileAlign
[Index
] - (TeOffset
% InputFileAlign
[Index
]);
529 TeOffset
= TeOffset
% InputFileAlign
[Index
];
533 // make sure section data meet its alignment requirement by adding one raw pad section.
535 if ((InputFileAlign
[Index
] != 0) && (((Size
+ HeaderSize
+ TeOffset
) % InputFileAlign
[Index
]) != 0)) {
536 Offset
= (Size
+ sizeof (EFI_COMMON_SECTION_HEADER
) + HeaderSize
+ TeOffset
+ InputFileAlign
[Index
] - 1) & ~(InputFileAlign
[Index
] - 1);
537 Offset
= Offset
- Size
- HeaderSize
- TeOffset
;
539 if (FileBuffer
!= NULL
&& ((Size
+ Offset
) < *BufferLength
)) {
541 // The maximal alignment is 64K, the raw section size must be less than 0xffffff
543 memset (FileBuffer
+ Size
, 0, Offset
);
544 SectHeader
= (EFI_COMMON_SECTION_HEADER
*) (FileBuffer
+ Size
);
545 SectHeader
->Type
= EFI_SECTION_RAW
;
546 SectHeader
->Size
[0] = (UINT8
) (Offset
& 0xff);
547 SectHeader
->Size
[1] = (UINT8
) ((Offset
& 0xff00) >> 8);
548 SectHeader
->Size
[2] = (UINT8
) ((Offset
& 0xff0000) >> 16);
550 DebugMsg (NULL
, 0, 9, "Pad raw section for section data alignment", "Pad Raw section size is %u", (unsigned) Offset
);
552 Size
= Size
+ Offset
;
557 // Now read the contents of the file into the buffer
558 // Buffer must be enough to contain the file content.
560 if ((FileSize
> 0) && (FileBuffer
!= NULL
) && ((Size
+ FileSize
) <= *BufferLength
)) {
561 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
562 Error (NULL
, 0, 0004, "Error reading file", InputFileName
[Index
]);
573 // Set the real required buffer size.
575 if (Size
> *BufferLength
) {
576 *BufferLength
= Size
;
577 return EFI_BUFFER_TOO_SMALL
;
579 *BufferLength
= Size
;
585 GenSectionCompressionSection (
586 CHAR8
**InputFileName
,
587 UINT32
*InputFileAlign
,
589 UINT8 SectCompSubType
,
590 UINT8
**OutFileBuffer
596 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
597 Input file must be already sectioned. The function won't validate
598 the input files' contents. Caller should hand in files already
603 InputFileName - Name of the input file.
605 InputFileAlign - Alignment required by the input file data.
607 InputFileNum - Number of input files. Should be at least 1.
609 SectCompSubType - Specify the compression algorithm requested.
611 OutFileBuffer - Buffer pointer to Output file contents
615 EFI_SUCCESS on successful return
616 EFI_INVALID_PARAMETER if InputFileNum is less than 1
617 EFI_ABORTED if unable to open input file.
618 EFI_OUT_OF_RESOURCES No resource to complete the operation.
623 UINT32 CompressedLength
;
628 EFI_COMPRESSION_SECTION
*CompressionSect
;
629 EFI_COMPRESSION_SECTION2
*CompressionSect2
;
630 COMPRESS_FUNCTION CompressFunction
;
635 CompressedLength
= 0;
638 // read all input file contents into a buffer
639 // first get the size of all file contents
641 Status
= GetSectionContents (
649 if (Status
== EFI_BUFFER_TOO_SMALL
) {
650 FileBuffer
= (UINT8
*) malloc (InputLength
);
651 if (FileBuffer
== NULL
) {
652 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
653 return EFI_OUT_OF_RESOURCES
;
656 // read all input file contents into a buffer
658 Status
= GetSectionContents (
667 if (EFI_ERROR (Status
)) {
668 if (FileBuffer
!= NULL
) {
674 if (FileBuffer
== NULL
) {
675 return EFI_OUT_OF_RESOURCES
;
678 CompressFunction
= NULL
;
681 // Now data is in FileBuffer, compress the data
683 switch (SectCompSubType
) {
684 case EFI_NOT_COMPRESSED
:
685 CompressedLength
= InputLength
;
686 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
687 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
688 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
690 TotalLength
= CompressedLength
+ HeaderLength
;
692 // Copy file buffer to the none compressed data.
694 OutputBuffer
= malloc (TotalLength
);
695 if (OutputBuffer
== NULL
) {
697 return EFI_OUT_OF_RESOURCES
;
699 memcpy (OutputBuffer
+ HeaderLength
, FileBuffer
, CompressedLength
);
701 FileBuffer
= OutputBuffer
;
704 case EFI_STANDARD_COMPRESSION
:
705 CompressFunction
= (COMPRESS_FUNCTION
) EfiCompress
;
709 Error (NULL
, 0, 2000, "Invalid parameter", "unknown compression type");
714 if (CompressFunction
!= NULL
) {
716 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
717 if (Status
== EFI_BUFFER_TOO_SMALL
) {
718 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
719 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
720 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
722 TotalLength
= CompressedLength
+ HeaderLength
;
723 OutputBuffer
= malloc (TotalLength
);
726 return EFI_OUT_OF_RESOURCES
;
729 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
+ HeaderLength
, &CompressedLength
);
733 FileBuffer
= OutputBuffer
;
735 if (EFI_ERROR (Status
)) {
736 if (FileBuffer
!= NULL
) {
743 if (FileBuffer
== NULL
) {
744 return EFI_OUT_OF_RESOURCES
;
748 DebugMsg (NULL
, 0, 9, "comprss file size",
749 "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength
, (unsigned) CompressedLength
);
751 //if (TotalLength >= MAX_SECTION_SIZE) {
752 // Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
753 // if (FileBuffer != NULL) {
754 // free (FileBuffer);
756 // if (OutputBuffer != NULL) {
757 // free (OutputBuffer);
759 // return STATUS_ERROR;
761 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
764 // Add the section header for the compressed data
766 if (TotalLength
>= MAX_SECTION_SIZE
) {
767 CompressionSect2
= (EFI_COMPRESSION_SECTION2
*)FileBuffer
;
769 memset(CompressionSect2
->CommonHeader
.Size
, 0xff, sizeof(UINT8
) * 3);
770 CompressionSect2
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
771 CompressionSect2
->CommonHeader
.ExtendedSize
= TotalLength
;
772 CompressionSect2
->CompressionType
= SectCompSubType
;
773 CompressionSect2
->UncompressedLength
= InputLength
;
775 CompressionSect
= (EFI_COMPRESSION_SECTION
*) FileBuffer
;
777 CompressionSect
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
778 CompressionSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
779 CompressionSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
780 CompressionSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
781 CompressionSect
->CompressionType
= SectCompSubType
;
782 CompressionSect
->UncompressedLength
= InputLength
;
788 *OutFileBuffer
= FileBuffer
;
794 GenSectionGuidDefinedSection (
795 CHAR8
**InputFileName
,
796 UINT32
*InputFileAlign
,
798 EFI_GUID
*VendorGuid
,
799 UINT16 DataAttribute
,
800 UINT32 DataHeaderSize
,
801 UINT8
**OutFileBuffer
807 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
808 Input file must be already sectioned. The function won't validate
809 the input files' contents. Caller should hand in files already
814 InputFileName - Name of the input file.
816 InputFileAlign - Alignment required by the input file data.
818 InputFileNum - Number of input files. Should be at least 1.
820 VendorGuid - Specify vendor guid value.
822 DataAttribute - Specify attribute for the vendor guid data.
824 DataHeaderSize- Guided Data Header Size
826 OutFileBuffer - Buffer pointer to Output file contents
830 EFI_SUCCESS on successful return
831 EFI_INVALID_PARAMETER if InputFileNum is less than 1
832 EFI_ABORTED if unable to open input file.
833 EFI_OUT_OF_RESOURCES No resource to complete the operation.
841 UINT32 Crc32Checksum
;
843 CRC32_SECTION_HEADER
*Crc32GuidSect
;
844 CRC32_SECTION_HEADER2
*Crc32GuidSect2
;
845 EFI_GUID_DEFINED_SECTION
*VendorGuidSect
;
846 EFI_GUID_DEFINED_SECTION2
*VendorGuidSect2
;
854 // read all input file contents into a buffer
855 // first get the size of all file contents
857 Status
= GetSectionContents (
865 if (Status
== EFI_BUFFER_TOO_SMALL
) {
866 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
867 Offset
= sizeof (CRC32_SECTION_HEADER
);
868 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
869 Offset
= sizeof (CRC32_SECTION_HEADER2
);
872 Offset
= sizeof (EFI_GUID_DEFINED_SECTION
);
873 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
874 Offset
= sizeof (EFI_GUID_DEFINED_SECTION2
);
877 TotalLength
= InputLength
+ Offset
;
879 FileBuffer
= (UINT8
*) malloc (InputLength
+ Offset
);
880 if (FileBuffer
== NULL
) {
881 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
882 return EFI_OUT_OF_RESOURCES
;
885 // read all input file contents into a buffer
887 Status
= GetSectionContents (
896 if (EFI_ERROR (Status
)) {
897 if (FileBuffer
!= NULL
) {
900 Error (NULL
, 0, 0001, "Error opening file for reading", InputFileName
[0]);
904 if (InputLength
== 0) {
905 if (FileBuffer
!= NULL
) {
908 Error (NULL
, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName
);
909 return EFI_NOT_FOUND
;
913 // InputLength != 0, but FileBuffer == NULL means out of resources.
915 if (FileBuffer
== NULL
) {
916 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
917 return EFI_OUT_OF_RESOURCES
;
921 // Now data is in FileBuffer + Offset
923 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
925 // Default Guid section is CRC32.
928 CalculateCrc32 (FileBuffer
+ Offset
, InputLength
, &Crc32Checksum
);
930 if (TotalLength
>= MAX_SECTION_SIZE
) {
931 Crc32GuidSect2
= (CRC32_SECTION_HEADER2
*) FileBuffer
;
932 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
933 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) 0xff;
934 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) 0xff;
935 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) 0xff;
936 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.ExtendedSize
= TotalLength
;
937 memcpy (&(Crc32GuidSect2
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
938 Crc32GuidSect2
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
939 Crc32GuidSect2
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER2
);
940 Crc32GuidSect2
->CRC32Checksum
= Crc32Checksum
;
941 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2
->GuidSectionHeader
.DataOffset
);
943 Crc32GuidSect
= (CRC32_SECTION_HEADER
*) FileBuffer
;
944 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
945 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
946 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
947 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
948 memcpy (&(Crc32GuidSect
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
949 Crc32GuidSect
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
950 Crc32GuidSect
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER
);
951 Crc32GuidSect
->CRC32Checksum
= Crc32Checksum
;
952 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect
->GuidSectionHeader
.DataOffset
);
955 if (TotalLength
>= MAX_SECTION_SIZE
) {
956 VendorGuidSect2
= (EFI_GUID_DEFINED_SECTION2
*) FileBuffer
;
957 VendorGuidSect2
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
958 VendorGuidSect2
->CommonHeader
.Size
[0] = (UINT8
) 0xff;
959 VendorGuidSect2
->CommonHeader
.Size
[1] = (UINT8
) 0xff;
960 VendorGuidSect2
->CommonHeader
.Size
[2] = (UINT8
) 0xff;
961 VendorGuidSect2
->CommonHeader
.ExtendedSize
= InputLength
+ sizeof (EFI_GUID_DEFINED_SECTION2
);
962 memcpy (&(VendorGuidSect2
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
963 VendorGuidSect2
->Attributes
= DataAttribute
;
964 VendorGuidSect2
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION2
) + DataHeaderSize
);
965 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2
->DataOffset
);
967 VendorGuidSect
= (EFI_GUID_DEFINED_SECTION
*) FileBuffer
;
968 VendorGuidSect
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
969 VendorGuidSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
970 VendorGuidSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
971 VendorGuidSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
972 memcpy (&(VendorGuidSect
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
973 VendorGuidSect
->Attributes
= DataAttribute
;
974 VendorGuidSect
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION
) + DataHeaderSize
);
975 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect
->DataOffset
);
978 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
983 *OutFileBuffer
= FileBuffer
;
1001 command line parameters
1005 EFI_SUCCESS Section header successfully generated and section concatenated.
1006 EFI_ABORTED Could not generate the section
1007 EFI_OUT_OF_RESOURCES No resource to complete the operation.
1012 UINT32 InputFileNum
;
1014 CHAR8
**InputFileName
;
1015 CHAR8
*OutputFileName
;
1017 CHAR8
*CompressionName
;
1018 CHAR8
*StringBuffer
;
1019 EFI_GUID VendorGuid
= mZeroGuid
;
1022 UINT8 SectCompSubType
;
1023 UINT16 SectGuidAttribute
;
1024 UINT64 SectGuidHeaderLength
;
1025 EFI_VERSION_SECTION
*VersionSect
;
1026 EFI_USER_INTERFACE_SECTION
*UiSect
;
1028 UINT8
*OutFileBuffer
;
1031 UINT32
*InputFileAlign
;
1032 UINT32 InputFileAlignNum
;
1033 EFI_COMMON_SECTION_HEADER
*SectionHeader
;
1034 CHAR8
*DummyFileName
;
1036 UINTN DummyFileSize
;
1037 UINT8
*DummyFileBuffer
;
1039 UINT8
*InFileBuffer
;
1042 InputFileAlign
= NULL
;
1043 InputFileAlignNum
= 0;
1044 InputFileName
= NULL
;
1045 OutputFileName
= NULL
;
1047 CompressionName
= NULL
;
1052 SectType
= EFI_SECTION_ALL
;
1053 SectCompSubType
= 0;
1054 SectGuidAttribute
= EFI_GUIDED_SECTION_NONE
;
1055 OutFileBuffer
= NULL
;
1057 Status
= STATUS_SUCCESS
;
1059 SectGuidHeaderLength
= 0;
1063 DummyFileName
= NULL
;
1065 DummyFileBuffer
= NULL
;
1068 InFileBuffer
= NULL
;
1070 SetUtilityName (UTILITY_NAME
);
1073 Error (NULL
, 0, 1001, "Missing options", "No options input");
1075 return STATUS_ERROR
;
1079 // Parse command line
1084 if ((stricmp (argv
[0], "-h") == 0) || (stricmp (argv
[0], "--help") == 0)) {
1087 return STATUS_SUCCESS
;
1090 if (stricmp (argv
[0], "--version") == 0) {
1092 return STATUS_SUCCESS
;
1096 if ((stricmp (argv
[0], "-s") == 0) || (stricmp (argv
[0], "--SectionType") == 0)) {
1097 SectionName
= argv
[1];
1098 if (SectionName
== NULL
) {
1099 Error (NULL
, 0, 1003, "Invalid option value", "Section Type can't be NULL");
1107 if ((stricmp (argv
[0], "-o") == 0) || (stricmp (argv
[0], "--outputfile") == 0)) {
1108 OutputFileName
= argv
[1];
1109 if (OutputFileName
== NULL
) {
1110 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be NULL");
1118 if ((stricmp (argv
[0], "-c") == 0) || (stricmp (argv
[0], "--compress") == 0)) {
1119 CompressionName
= argv
[1];
1120 if (CompressionName
== NULL
) {
1121 Error (NULL
, 0, 1003, "Invalid option value", "Compression Type can't be NULL");
1129 if ((stricmp (argv
[0], "-g") == 0) || (stricmp (argv
[0], "--vendor") == 0)) {
1130 Status
= StringToGuid (argv
[1], &VendorGuid
);
1131 if (EFI_ERROR (Status
)) {
1132 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1139 if (stricmp (argv
[0], "--dummy") == 0) {
1140 DummyFileName
= argv
[1];
1141 if (DummyFileName
== NULL
) {
1142 Error (NULL
, 0, 1003, "Invalid option value", "Dummy file can't be NULL");
1150 if ((stricmp (argv
[0], "-r") == 0) || (stricmp (argv
[0], "--attributes") == 0)) {
1151 if (argv
[1] == NULL
) {
1152 Error (NULL
, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");
1155 if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]) == 0) {
1156 SectGuidAttribute
|= EFI_GUIDED_SECTION_PROCESSING_REQUIRED
;
1157 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]) == 0) {
1158 SectGuidAttribute
|= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
1159 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[0]) == 0) {
1163 SectGuidAttribute
|= EFI_GUIDED_SECTION_NONE
;
1165 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1173 if ((stricmp (argv
[0], "-l") == 0) || (stricmp (argv
[0], "--HeaderLength") == 0)) {
1174 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &SectGuidHeaderLength
);
1175 if (EFI_ERROR (Status
)) {
1176 Error (NULL
, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv
[0], argv
[1]);
1184 if ((stricmp (argv
[0], "-n") == 0) || (stricmp (argv
[0], "--name") == 0)) {
1185 StringBuffer
= argv
[1];
1186 if (StringBuffer
== NULL
) {
1187 Error (NULL
, 0, 1003, "Invalid option value", "Name can't be NULL");
1195 if ((stricmp (argv
[0], "-j") == 0) || (stricmp (argv
[0], "--buildnumber") == 0)) {
1196 if (argv
[1] == NULL
) {
1197 Error (NULL
, 0, 1003, "Invalid option value", "build number can't be NULL");
1201 // Verify string is a integrator number
1203 for (Index
= 0; Index
< strlen (argv
[1]); Index
++) {
1204 if ((argv
[1][Index
] != '-') && (isdigit ((int)argv
[1][Index
]) == 0)) {
1205 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1210 sscanf (argv
[1], "%d", &VersionNumber
);
1216 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
1217 SetPrintLevel (VERBOSE_LOG_LEVEL
);
1218 VerboseMsg ("Verbose output Mode Set!");
1224 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
1225 SetPrintLevel (KEY_LOG_LEVEL
);
1226 KeyMsg ("Quiet output Mode Set!");
1232 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
1233 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
1234 if (EFI_ERROR (Status
)) {
1235 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1239 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0~9, currnt input level is %d", (int) LogLevel
);
1242 SetPrintLevel (LogLevel
);
1243 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
1250 // Section File alignment requirement
1252 if (stricmp (argv
[0], "--sectionalign") == 0) {
1253 if (InputFileAlignNum
== 0) {
1254 InputFileAlign
= (UINT32
*) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1255 if (InputFileAlign
== NULL
) {
1256 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1259 memset (InputFileAlign
, 1, MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1260 } else if (InputFileAlignNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1261 InputFileAlign
= (UINT32
*) realloc (
1263 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (UINT32
)
1266 if (InputFileAlign
== NULL
) {
1267 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1270 memset (&(InputFileAlign
[InputFileNum
]), 1, (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
)));
1273 Status
= StringtoAlignment (argv
[1], &(InputFileAlign
[InputFileAlignNum
]));
1274 if (EFI_ERROR (Status
)) {
1275 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1280 InputFileAlignNum
++;
1285 // Get Input file name
1287 if ((InputFileNum
== 0) && (InputFileName
== NULL
)) {
1288 InputFileName
= (CHAR8
**) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*));
1289 if (InputFileName
== NULL
) {
1290 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1293 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1294 } else if (InputFileNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1296 // InputFileName buffer too small, need to realloc
1298 InputFileName
= (CHAR8
**) realloc (
1300 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (CHAR8
*)
1303 if (InputFileName
== NULL
) {
1304 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1307 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1310 InputFileName
[InputFileNum
++] = argv
[0];
1315 if (InputFileAlignNum
> 0 && InputFileAlignNum
!= InputFileNum
) {
1316 Error (NULL
, 0, 1003, "Invalid option", "section alignment must be set for each section");
1320 VerboseMsg ("%s tool start.", UTILITY_NAME
);
1322 if (DummyFileName
!= NULL
) {
1324 // Open file and read contents
1326 DummyFile
= fopen (LongFilePath (DummyFileName
), "rb");
1327 if (DummyFile
== NULL
) {
1328 Error (NULL
, 0, 0001, "Error opening file", DummyFileName
);
1332 fseek (DummyFile
, 0, SEEK_END
);
1333 DummyFileSize
= ftell (DummyFile
);
1334 fseek (DummyFile
, 0, SEEK_SET
);
1335 DummyFileBuffer
= (UINT8
*) malloc (DummyFileSize
);
1336 fread(DummyFileBuffer
, 1, DummyFileSize
, DummyFile
);
1338 DebugMsg (NULL
, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName
, (unsigned) DummyFileSize
);
1340 InFile
= fopen(LongFilePath(InputFileName
[0]), "rb");
1341 if (InFile
== NULL
) {
1342 Error (NULL
, 0, 0001, "Error opening file", InputFileName
[0]);
1346 fseek (InFile
, 0, SEEK_END
);
1347 InFileSize
= ftell (InFile
);
1348 fseek (InFile
, 0, SEEK_SET
);
1349 InFileBuffer
= (UINT8
*) malloc (InFileSize
);
1350 fread(InFileBuffer
, 1, InFileSize
, InFile
);
1352 DebugMsg (NULL
, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName
[0], (unsigned) InFileSize
);
1353 if (InFileSize
> DummyFileSize
){
1354 if (stricmp((CHAR8
*)DummyFileBuffer
, (CHAR8
*)(InFileBuffer
+ (InFileSize
- DummyFileSize
))) == 0){
1355 SectGuidHeaderLength
= InFileSize
- DummyFileSize
;
1358 if (SectGuidHeaderLength
== 0) {
1359 SectGuidAttribute
|= EFI_GUIDED_SECTION_PROCESSING_REQUIRED
;
1361 if (DummyFileBuffer
!= NULL
) {
1362 free (DummyFileBuffer
);
1364 if (InFileBuffer
!= NULL
) {
1365 free (InFileBuffer
);
1370 // Parse all command line parameters to get the corresponding section type.
1372 VerboseMsg ("Section type is %s", SectionName
);
1373 if (SectionName
== NULL
) {
1375 // No specified Section type, default is SECTION_ALL.
1377 SectType
= EFI_SECTION_ALL
;
1378 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
1379 SectType
= EFI_SECTION_COMPRESSION
;
1380 if (CompressionName
== NULL
) {
1382 // Default is PI_STD compression algorithm.
1384 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1385 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
1386 SectCompSubType
= EFI_NOT_COMPRESSED
;
1387 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
1388 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1390 Error (NULL
, 0, 1003, "Invalid option value", "--compress = %s", CompressionName
);
1393 VerboseMsg ("Compress method is %s", mCompressionTypeName
[SectCompSubType
]);
1394 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
1395 SectType
= EFI_SECTION_GUID_DEFINED
;
1397 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_NONE
) != 0) {
1399 // NONE attribute, clear attribute value.
1401 SectGuidAttribute
= SectGuidAttribute
& ~EFI_GUIDED_SECTION_NONE
;
1403 VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
1404 (unsigned) VendorGuid
.Data1
,
1407 VendorGuid
.Data4
[0],
1408 VendorGuid
.Data4
[1],
1409 VendorGuid
.Data4
[2],
1410 VendorGuid
.Data4
[3],
1411 VendorGuid
.Data4
[4],
1412 VendorGuid
.Data4
[5],
1413 VendorGuid
.Data4
[6],
1414 VendorGuid
.Data4
[7]);
1415 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) != 0) {
1416 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]);
1418 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) != 0) {
1419 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]);
1421 if (SectGuidHeaderLength
!= 0) {
1422 VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength
);
1424 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PE32
]) == 0) {
1425 SectType
= EFI_SECTION_PE32
;
1426 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PIC
]) == 0) {
1427 SectType
= EFI_SECTION_PIC
;
1428 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_TE
]) == 0) {
1429 SectType
= EFI_SECTION_TE
;
1430 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
1431 SectType
= EFI_SECTION_DXE_DEPEX
;
1432 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_SMM_DEPEX
]) == 0) {
1433 SectType
= EFI_SECTION_SMM_DEPEX
;
1434 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
1435 SectType
= EFI_SECTION_VERSION
;
1436 if (VersionNumber
< 0 || VersionNumber
> 65535) {
1437 Error (NULL
, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber
);
1440 VerboseMsg ("Version section number is %d", VersionNumber
);
1441 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
1442 SectType
= EFI_SECTION_USER_INTERFACE
;
1443 if (StringBuffer
[0] == '\0') {
1444 Error (NULL
, 0, 1001, "Missing option", "user interface string");
1447 VerboseMsg ("UI section string name is %s", StringBuffer
);
1448 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
1449 SectType
= EFI_SECTION_COMPATIBILITY16
;
1450 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
1451 SectType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
1452 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
1453 SectType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
1454 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_RAW
]) == 0) {
1455 SectType
= EFI_SECTION_RAW
;
1456 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
1457 SectType
= EFI_SECTION_PEI_DEPEX
;
1459 Error (NULL
, 0, 1003, "Invalid option value", "SectionType = %s", SectionName
);
1464 // GuidValue is only required by Guided section.
1466 if ((SectType
!= EFI_SECTION_GUID_DEFINED
) &&
1467 (SectionName
!= NULL
) &&
1468 (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1469 fprintf (stdout
, "Warning: the input guid value is not required for this section type %s\n", SectionName
);
1473 // Check whether there is input file
1475 if ((SectType
!= EFI_SECTION_VERSION
) && (SectType
!= EFI_SECTION_USER_INTERFACE
)) {
1477 // The input file are required for other section type.
1479 if (InputFileNum
== 0) {
1480 Error (NULL
, 0, 1001, "Missing options", "Input files");
1485 // Check whether there is output file
1487 for (Index
= 0; Index
< InputFileNum
; Index
++) {
1488 VerboseMsg ("the %uth input file name is %s", (unsigned) Index
, InputFileName
[Index
]);
1490 if (OutputFileName
== NULL
) {
1491 Error (NULL
, 0, 1001, "Missing options", "Output file");
1493 // OutFile = stdout;
1495 VerboseMsg ("Output file name is %s", OutputFileName
);
1498 // At this point, we've fully validated the command line, and opened appropriate
1499 // files, so let's go and do what we've been asked to do...
1502 // Within this switch, build and write out the section header including any
1503 // section type specific pieces. If there's an input file, it's tacked on later
1506 case EFI_SECTION_COMPRESSION
:
1507 if (InputFileAlign
!= NULL
) {
1508 free (InputFileAlign
);
1509 InputFileAlign
= NULL
;
1511 Status
= GenSectionCompressionSection (
1520 case EFI_SECTION_GUID_DEFINED
:
1521 if (InputFileAlign
!= NULL
&& (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1523 // Only process alignment for the default known CRC32 guided section.
1524 // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.
1526 free (InputFileAlign
);
1527 InputFileAlign
= NULL
;
1529 Status
= GenSectionGuidDefinedSection (
1535 (UINT32
) SectGuidHeaderLength
,
1540 case EFI_SECTION_VERSION
:
1541 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
1543 // 2 bytes for the build number UINT16
1547 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
1549 Index
+= (strlen (StringBuffer
) * 2) + 2;
1550 OutFileBuffer
= (UINT8
*) malloc (Index
);
1551 if (OutFileBuffer
== NULL
) {
1552 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1555 VersionSect
= (EFI_VERSION_SECTION
*) OutFileBuffer
;
1556 VersionSect
->CommonHeader
.Type
= SectType
;
1557 VersionSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1558 VersionSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1559 VersionSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1560 VersionSect
->BuildNumber
= (UINT16
) VersionNumber
;
1561 Ascii2UnicodeString (StringBuffer
, VersionSect
->VersionString
);
1562 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1565 case EFI_SECTION_USER_INTERFACE
:
1566 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
1568 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
1570 Index
+= (strlen (StringBuffer
) * 2) + 2;
1571 OutFileBuffer
= (UINT8
*) malloc (Index
);
1572 if (OutFileBuffer
== NULL
) {
1573 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1576 UiSect
= (EFI_USER_INTERFACE_SECTION
*) OutFileBuffer
;
1577 UiSect
->CommonHeader
.Type
= SectType
;
1578 UiSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1579 UiSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1580 UiSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1581 Ascii2UnicodeString (StringBuffer
, UiSect
->FileNameString
);
1582 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1585 case EFI_SECTION_ALL
:
1587 // read all input file contents into a buffer
1588 // first get the size of all file contents
1590 Status
= GetSectionContents (
1598 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1599 OutFileBuffer
= (UINT8
*) malloc (InputLength
);
1600 if (OutFileBuffer
== NULL
) {
1601 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1605 // read all input file contents into a buffer
1607 Status
= GetSectionContents (
1615 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength
);
1619 // All other section types are caught by default (they're all the same)
1621 Status
= GenSectionCommonLeafSection (
1630 if (Status
!= EFI_SUCCESS
|| OutFileBuffer
== NULL
) {
1631 Error (NULL
, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status
);
1636 // Get output file length
1638 if (SectType
!= EFI_SECTION_ALL
) {
1639 SectionHeader
= (EFI_COMMON_SECTION_HEADER
*)OutFileBuffer
;
1640 InputLength
= *(UINT32
*)SectionHeader
->Size
& 0x00ffffff;
1641 if (InputLength
== 0xffffff) {
1642 InputLength
= ((EFI_COMMON_SECTION_HEADER2
*)SectionHeader
)->ExtendedSize
;
1647 // Write the output file
1649 OutFile
= fopen (LongFilePath (OutputFileName
), "wb");
1650 if (OutFile
== NULL
) {
1651 Error (NULL
, 0, 0001, "Error opening file for writing", OutputFileName
);
1655 fwrite (OutFileBuffer
, InputLength
, 1, OutFile
);
1658 if (InputFileName
!= NULL
) {
1659 free (InputFileName
);
1662 if (InputFileAlign
!= NULL
) {
1663 free (InputFileAlign
);
1666 if (OutFileBuffer
!= NULL
) {
1667 free (OutFileBuffer
);
1670 if (OutFile
!= NULL
) {
1674 if (DummyFileBuffer
!= NULL
) {
1675 free (DummyFileBuffer
);
1678 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME
, GetUtilityStatus ());
1680 return GetUtilityStatus ();