2 Creates output file that is a properly formed section per the PI spec.
4 Copyright (c) 2004 - 2016, 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"
81 // Crc32 GUID section related definitions.
84 EFI_GUID_DEFINED_SECTION GuidSectionHeader
;
86 } CRC32_SECTION_HEADER
;
89 EFI_GUID_DEFINED_SECTION2 GuidSectionHeader
;
91 } CRC32_SECTION_HEADER2
;
93 STATIC EFI_GUID mZeroGuid
= {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
94 STATIC EFI_GUID mEfiCrc32SectionGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
105 Print out version information for this utility.
117 fprintf (stdout
, "%s Version %d.%d %s \n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
144 fprintf (stdout
, "\nUsage: %s [options] [input_file]\n\n", UTILITY_NAME
);
147 // Copyright declaration
149 fprintf (stdout
, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
154 fprintf (stdout
, "Options:\n");
155 fprintf (stdout
, " -o FileName, --outputfile FileName\n\
156 File is the SectionFile to be created.\n");
157 fprintf (stdout
, " -s [SectionType], --sectiontype [SectionType]\n\
158 SectionType defined in PI spec is one type of\n\
159 EFI_SECTION_COMPRESSION, EFI_SECTION_GUID_DEFINED,\n\
160 EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE,\n\
161 EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16,\n\
162 EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION,\n\
163 EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW,\n\
164 EFI_SECTION_FREEFORM_SUBTYPE_GUID,\n\
165 EFI_SECTION_PEI_DEPEX, EFI_SECTION_SMM_DEPEX.\n\
166 if -s option is not given, \n\
167 EFI_SECTION_ALL is default section type.\n");
168 fprintf (stdout
, " -c [Type], --compress [Type]\n\
169 Compress method type can be PI_NONE or PI_STD.\n\
170 if -c option is not given, PI_STD is default type.\n");
171 fprintf (stdout
, " -g GuidValue, --vendor GuidValue\n\
172 GuidValue is one specific vendor guid value.\n\
173 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
174 fprintf (stdout
, " -l GuidHeaderLength, --HeaderLength GuidHeaderLength\n\
175 GuidHeaderLength is the size of header of guided data\n");
176 fprintf (stdout
, " -r GuidAttr, --attributes GuidAttr\n\
177 GuidAttr is guid section atttributes, which may be\n\
178 PROCESSING_REQUIRED, AUTH_STATUS_VALID and NONE. \n\
179 if -r option is not given, default PROCESSING_REQUIRED\n");
180 fprintf (stdout
, " -n String, --name String\n\
181 String is a NULL terminated string used in Ui section.\n");
182 fprintf (stdout
, " -j Number, --buildnumber Number\n\
183 Number is an integer value between 0 and 65535\n\
184 used in Ver section.\n");
185 fprintf (stdout
, " --sectionalign SectionAlign\n\
186 SectionAlign points to section alignment, which support\n\
187 the alignment scope 1~64K. It is specified in same\n\
188 order that the section file is input.\n");
189 fprintf (stdout
, " -v, --verbose Turn on verbose output with informational messages.\n");
190 fprintf (stdout
, " -q, --quiet Disable all messages except key message and fatal error\n");
191 fprintf (stdout
, " -d, --debug level Enable debug messages, at input debug level.\n");
192 fprintf (stdout
, " --version Show program's version number and exit.\n");
193 fprintf (stdout
, " -h, --help Show this help message and exit.\n");
197 Ascii2UnicodeString (
205 Write ascii string as unicode string format to FILE
209 String - Pointer to string that is written to FILE.
210 UniString - Pointer to unicode string
218 while (*String
!= '\0') {
219 *(UniString
++) = (CHAR16
) *(String
++);
222 // End the UniString with a NULL.
228 GenSectionCommonLeafSection (
229 CHAR8
**InputFileName
,
232 UINT8
**OutFileBuffer
238 Generate a leaf section of type other than EFI_SECTION_VERSION
239 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
240 The function won't validate the input file's contents. For
241 common leaf sections, the input file may be a binary file.
242 The utility will add section header to the file.
246 InputFileName - Name of the input file.
248 InputFileNum - Number of input files. Should be 1 for leaf section.
250 SectionType - A valid section type string
252 OutFileBuffer - Buffer pointer to Output file contents
256 STATUS_ERROR - can't continue
257 STATUS_SUCCESS - successful return
261 UINT32 InputFileLength
;
266 EFI_COMMON_SECTION_HEADER
*CommonSect
;
269 if (InputFileNum
> 1) {
270 Error (NULL
, 0, 2000, "Invalid parameter", "more than one input file specified");
272 } else if (InputFileNum
< 1) {
273 Error (NULL
, 0, 2000, "Invalid parameter", "no input file specified");
277 // Open the input file
279 InFile
= fopen (LongFilePath (InputFileName
[0]), "rb");
280 if (InFile
== NULL
) {
281 Error (NULL
, 0, 0001, "Error opening file", InputFileName
[0]);
285 Status
= STATUS_ERROR
;
288 // Seek to the end of the input file so we can determine its size
290 fseek (InFile
, 0, SEEK_END
);
291 InputFileLength
= ftell (InFile
);
292 fseek (InFile
, 0, SEEK_SET
);
293 DebugMsg (NULL
, 0, 9, "Input file", "File name is %s and File size is %u bytes", InputFileName
[0], (unsigned) InputFileLength
);
294 TotalLength
= sizeof (EFI_COMMON_SECTION_HEADER
) + InputFileLength
;
296 // Size must fit in 3 bytes
298 //if (TotalLength >= MAX_SECTION_SIZE) {
299 // Error (NULL, 0, 2000, "Invalid parameter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);
302 HeaderLength
= sizeof (EFI_COMMON_SECTION_HEADER
);
303 if (TotalLength
>= MAX_SECTION_SIZE
) {
304 TotalLength
= sizeof (EFI_COMMON_SECTION_HEADER2
) + InputFileLength
;
305 HeaderLength
= sizeof (EFI_COMMON_SECTION_HEADER2
);
307 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
309 // Fill in the fields in the local section header structure
311 Buffer
= (UINT8
*) malloc ((size_t) TotalLength
);
312 if (Buffer
== NULL
) {
313 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
316 CommonSect
= (EFI_COMMON_SECTION_HEADER
*) Buffer
;
317 CommonSect
->Type
= SectionType
;
318 if (TotalLength
< MAX_SECTION_SIZE
) {
319 CommonSect
->Size
[0] = (UINT8
) (TotalLength
& 0xff);
320 CommonSect
->Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
321 CommonSect
->Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
323 memset(CommonSect
->Size
, 0xff, sizeof(UINT8
) * 3);
324 ((EFI_COMMON_SECTION_HEADER2
*)CommonSect
)->ExtendedSize
= TotalLength
;
328 // read data from the input file.
330 if (InputFileLength
!= 0) {
331 if (fread (Buffer
+ HeaderLength
, (size_t) InputFileLength
, 1, InFile
) != 1) {
332 Error (NULL
, 0, 0004, "Error reading file", InputFileName
[0]);
340 *OutFileBuffer
= Buffer
;
341 Status
= STATUS_SUCCESS
;
352 IN CHAR8
*AlignBuffer
,
353 OUT UINT32
*AlignNumber
359 Converts Align String to align value (1~64K).
363 AlignBuffer - Pointer to Align string.
364 AlignNumber - Pointer to Align value.
368 EFI_SUCCESS Successfully convert align string to align value.
369 EFI_INVALID_PARAMETER Align string is invalid or align value is not in scope.
377 if (AlignBuffer
== NULL
) {
378 return EFI_INVALID_PARAMETER
;
380 for (Index
= 0; Index
< sizeof (mAlignName
) / sizeof (CHAR8
*); Index
++) {
381 if (stricmp (AlignBuffer
, mAlignName
[Index
]) == 0) {
382 *AlignNumber
= 1 << Index
;
386 return EFI_INVALID_PARAMETER
;
391 CHAR8
**InputFileName
,
392 UINT32
*InputFileAlign
,
401 Get the contents of all section files specified in InputFileName
406 InputFileName - Name of the input file.
408 InputFileAlign - Alignment required by the input file data.
410 InputFileNum - Number of input files. Should be at least 1.
412 FileBuffer - Output buffer to contain data
414 BufferLength - On input, this is size of the FileBuffer.
415 On output, this is the actual length of the data.
419 EFI_SUCCESS on successful return
420 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
421 EFI_ABORTED if unable to open input file.
422 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
430 EFI_COMMON_SECTION_HEADER
*SectHeader
;
431 EFI_COMMON_SECTION_HEADER2 TempSectHeader
;
432 EFI_TE_IMAGE_HEADER TeHeader
;
434 EFI_GUID_DEFINED_SECTION GuidSectHeader
;
435 EFI_GUID_DEFINED_SECTION2 GuidSectHeader2
;
438 if (InputFileNum
< 1) {
439 Error (NULL
, 0, 2000, "Invalid parameter", "must specify at least one input file");
440 return EFI_INVALID_PARAMETER
;
443 if (BufferLength
== NULL
) {
444 Error (NULL
, 0, 2000, "Invalid parameter", "BufferLength can't be NULL");
445 return EFI_INVALID_PARAMETER
;
452 // Go through our array of file names and copy their contents
453 // to the output buffer.
455 for (Index
= 0; Index
< InputFileNum
; Index
++) {
457 // make sure section ends on a DWORD boundary
459 while ((Size
& 0x03) != 0) {
460 if (FileBuffer
!= NULL
&& Size
< *BufferLength
) {
461 FileBuffer
[Size
] = 0;
467 // Open file and read contents
469 InFile
= fopen (LongFilePath (InputFileName
[Index
]), "rb");
470 if (InFile
== NULL
) {
471 Error (NULL
, 0, 0001, "Error opening file", InputFileName
[Index
]);
475 fseek (InFile
, 0, SEEK_END
);
476 FileSize
= ftell (InFile
);
477 fseek (InFile
, 0, SEEK_SET
);
478 DebugMsg (NULL
, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName
[Index
], (unsigned) FileSize
);
480 // Adjust section buffer when section alignment is required.
482 if (InputFileAlign
!= NULL
) {
484 // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
488 // The section might be EFI_COMMON_SECTION_HEADER2
489 // But only Type needs to be checked
491 if (FileSize
>= MAX_SECTION_SIZE
) {
492 HeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER2
);
494 HeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER
);
496 fread (&TempSectHeader
, 1, HeaderSize
, InFile
);
497 if (TempSectHeader
.Type
== EFI_SECTION_TE
) {
498 fread (&TeHeader
, 1, sizeof (TeHeader
), InFile
);
499 if (TeHeader
.Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
500 TeOffset
= TeHeader
.StrippedSize
- sizeof (TeHeader
);
502 } else if (TempSectHeader
.Type
== EFI_SECTION_GUID_DEFINED
) {
503 fseek (InFile
, 0, SEEK_SET
);
504 if (FileSize
>= MAX_SECTION_SIZE
) {
505 fread (&GuidSectHeader2
, 1, sizeof (GuidSectHeader2
), InFile
);
506 if ((GuidSectHeader2
.Attributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
507 HeaderSize
= GuidSectHeader2
.DataOffset
;
510 fread (&GuidSectHeader
, 1, sizeof (GuidSectHeader
), InFile
);
511 if ((GuidSectHeader
.Attributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
512 HeaderSize
= GuidSectHeader
.DataOffset
;
517 fseek (InFile
, 0, SEEK_SET
);
520 // Revert TeOffset to the converse value relative to Alignment
521 // This is to assure the original PeImage Header at Alignment.
524 TeOffset
= InputFileAlign
[Index
] - (TeOffset
% InputFileAlign
[Index
]);
525 TeOffset
= TeOffset
% InputFileAlign
[Index
];
529 // make sure section data meet its alignment requirement by adding one raw pad section.
531 if ((InputFileAlign
[Index
] != 0) && (((Size
+ HeaderSize
+ TeOffset
) % InputFileAlign
[Index
]) != 0)) {
532 Offset
= (Size
+ sizeof (EFI_COMMON_SECTION_HEADER
) + HeaderSize
+ TeOffset
+ InputFileAlign
[Index
] - 1) & ~(InputFileAlign
[Index
] - 1);
533 Offset
= Offset
- Size
- HeaderSize
- TeOffset
;
535 if (FileBuffer
!= NULL
&& ((Size
+ Offset
) < *BufferLength
)) {
537 // The maximal alignment is 64K, the raw section size must be less than 0xffffff
539 memset (FileBuffer
+ Size
, 0, Offset
);
540 SectHeader
= (EFI_COMMON_SECTION_HEADER
*) (FileBuffer
+ Size
);
541 SectHeader
->Type
= EFI_SECTION_RAW
;
542 SectHeader
->Size
[0] = (UINT8
) (Offset
& 0xff);
543 SectHeader
->Size
[1] = (UINT8
) ((Offset
& 0xff00) >> 8);
544 SectHeader
->Size
[2] = (UINT8
) ((Offset
& 0xff0000) >> 16);
546 DebugMsg (NULL
, 0, 9, "Pad raw section for section data alignment", "Pad Raw section size is %u", (unsigned) Offset
);
548 Size
= Size
+ Offset
;
553 // Now read the contents of the file into the buffer
554 // Buffer must be enough to contain the file content.
556 if ((FileSize
> 0) && (FileBuffer
!= NULL
) && ((Size
+ FileSize
) <= *BufferLength
)) {
557 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
558 Error (NULL
, 0, 0004, "Error reading file", InputFileName
[Index
]);
569 // Set the real required buffer size.
571 if (Size
> *BufferLength
) {
572 *BufferLength
= Size
;
573 return EFI_BUFFER_TOO_SMALL
;
575 *BufferLength
= Size
;
581 GenSectionCompressionSection (
582 CHAR8
**InputFileName
,
583 UINT32
*InputFileAlign
,
585 UINT8 SectCompSubType
,
586 UINT8
**OutFileBuffer
592 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
593 Input file must be already sectioned. The function won't validate
594 the input files' contents. Caller should hand in files already
599 InputFileName - Name of the input file.
601 InputFileAlign - Alignment required by the input file data.
603 InputFileNum - Number of input files. Should be at least 1.
605 SectCompSubType - Specify the compression algorithm requested.
607 OutFileBuffer - Buffer pointer to Output file contents
611 EFI_SUCCESS on successful return
612 EFI_INVALID_PARAMETER if InputFileNum is less than 1
613 EFI_ABORTED if unable to open input file.
614 EFI_OUT_OF_RESOURCES No resource to complete the operation.
619 UINT32 CompressedLength
;
624 EFI_COMPRESSION_SECTION
*CompressionSect
;
625 EFI_COMPRESSION_SECTION2
*CompressionSect2
;
626 COMPRESS_FUNCTION CompressFunction
;
631 CompressedLength
= 0;
634 // read all input file contents into a buffer
635 // first get the size of all file contents
637 Status
= GetSectionContents (
645 if (Status
== EFI_BUFFER_TOO_SMALL
) {
646 FileBuffer
= (UINT8
*) malloc (InputLength
);
647 if (FileBuffer
== NULL
) {
648 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
649 return EFI_OUT_OF_RESOURCES
;
652 // read all input file contents into a buffer
654 Status
= GetSectionContents (
663 if (EFI_ERROR (Status
)) {
664 if (FileBuffer
!= NULL
) {
670 if (FileBuffer
== NULL
) {
671 return EFI_OUT_OF_RESOURCES
;
674 CompressFunction
= NULL
;
677 // Now data is in FileBuffer, compress the data
679 switch (SectCompSubType
) {
680 case EFI_NOT_COMPRESSED
:
681 CompressedLength
= InputLength
;
682 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
683 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
684 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
686 TotalLength
= CompressedLength
+ HeaderLength
;
688 // Copy file buffer to the none compressed data.
690 OutputBuffer
= malloc (TotalLength
);
691 if (OutputBuffer
== NULL
) {
693 return EFI_OUT_OF_RESOURCES
;
695 memcpy (OutputBuffer
+ HeaderLength
, FileBuffer
, CompressedLength
);
697 FileBuffer
= OutputBuffer
;
700 case EFI_STANDARD_COMPRESSION
:
701 CompressFunction
= (COMPRESS_FUNCTION
) EfiCompress
;
705 Error (NULL
, 0, 2000, "Invalid parameter", "unknown compression type");
710 if (CompressFunction
!= NULL
) {
712 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
713 if (Status
== EFI_BUFFER_TOO_SMALL
) {
714 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
715 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
716 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
718 TotalLength
= CompressedLength
+ HeaderLength
;
719 OutputBuffer
= malloc (TotalLength
);
722 return EFI_OUT_OF_RESOURCES
;
725 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
+ HeaderLength
, &CompressedLength
);
729 FileBuffer
= OutputBuffer
;
731 if (EFI_ERROR (Status
)) {
732 if (FileBuffer
!= NULL
) {
739 if (FileBuffer
== NULL
) {
740 return EFI_OUT_OF_RESOURCES
;
744 DebugMsg (NULL
, 0, 9, "comprss file size",
745 "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength
, (unsigned) CompressedLength
);
747 //if (TotalLength >= MAX_SECTION_SIZE) {
748 // Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
749 // if (FileBuffer != NULL) {
750 // free (FileBuffer);
752 // if (OutputBuffer != NULL) {
753 // free (OutputBuffer);
755 // return STATUS_ERROR;
757 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
760 // Add the section header for the compressed data
762 if (TotalLength
>= MAX_SECTION_SIZE
) {
763 CompressionSect2
= (EFI_COMPRESSION_SECTION2
*)FileBuffer
;
765 memset(CompressionSect2
->CommonHeader
.Size
, 0xff, sizeof(UINT8
) * 3);
766 CompressionSect2
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
767 CompressionSect2
->CommonHeader
.ExtendedSize
= TotalLength
;
768 CompressionSect2
->CompressionType
= SectCompSubType
;
769 CompressionSect2
->UncompressedLength
= InputLength
;
771 CompressionSect
= (EFI_COMPRESSION_SECTION
*) FileBuffer
;
773 CompressionSect
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
774 CompressionSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
775 CompressionSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
776 CompressionSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
777 CompressionSect
->CompressionType
= SectCompSubType
;
778 CompressionSect
->UncompressedLength
= InputLength
;
784 *OutFileBuffer
= FileBuffer
;
790 GenSectionGuidDefinedSection (
791 CHAR8
**InputFileName
,
792 UINT32
*InputFileAlign
,
794 EFI_GUID
*VendorGuid
,
795 UINT16 DataAttribute
,
796 UINT32 DataHeaderSize
,
797 UINT8
**OutFileBuffer
803 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
804 Input file must be already sectioned. The function won't validate
805 the input files' contents. Caller should hand in files already
810 InputFileName - Name of the input file.
812 InputFileAlign - Alignment required by the input file data.
814 InputFileNum - Number of input files. Should be at least 1.
816 VendorGuid - Specify vendor guid value.
818 DataAttribute - Specify attribute for the vendor guid data.
820 DataHeaderSize- Guided Data Header Size
822 OutFileBuffer - Buffer pointer to Output file contents
826 EFI_SUCCESS on successful return
827 EFI_INVALID_PARAMETER if InputFileNum is less than 1
828 EFI_ABORTED if unable to open input file.
829 EFI_OUT_OF_RESOURCES No resource to complete the operation.
837 UINT32 Crc32Checksum
;
839 CRC32_SECTION_HEADER
*Crc32GuidSect
;
840 CRC32_SECTION_HEADER2
*Crc32GuidSect2
;
841 EFI_GUID_DEFINED_SECTION
*VendorGuidSect
;
842 EFI_GUID_DEFINED_SECTION2
*VendorGuidSect2
;
850 // read all input file contents into a buffer
851 // first get the size of all file contents
853 Status
= GetSectionContents (
861 if (Status
== EFI_BUFFER_TOO_SMALL
) {
862 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
863 Offset
= sizeof (CRC32_SECTION_HEADER
);
864 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
865 Offset
= sizeof (CRC32_SECTION_HEADER2
);
868 Offset
= sizeof (EFI_GUID_DEFINED_SECTION
);
869 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
870 Offset
= sizeof (EFI_GUID_DEFINED_SECTION2
);
873 TotalLength
= InputLength
+ Offset
;
875 FileBuffer
= (UINT8
*) malloc (InputLength
+ Offset
);
876 if (FileBuffer
== NULL
) {
877 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
878 return EFI_OUT_OF_RESOURCES
;
881 // read all input file contents into a buffer
883 Status
= GetSectionContents (
892 if (EFI_ERROR (Status
)) {
893 if (FileBuffer
!= NULL
) {
896 Error (NULL
, 0, 0001, "Error opening file for reading", InputFileName
[0]);
900 if (InputLength
== 0) {
901 if (FileBuffer
!= NULL
) {
904 Error (NULL
, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName
);
905 return EFI_NOT_FOUND
;
909 // InputLength != 0, but FileBuffer == NULL means out of resources.
911 if (FileBuffer
== NULL
) {
912 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
913 return EFI_OUT_OF_RESOURCES
;
917 // Now data is in FileBuffer + Offset
919 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
921 // Default Guid section is CRC32.
924 CalculateCrc32 (FileBuffer
+ Offset
, InputLength
, &Crc32Checksum
);
926 if (TotalLength
>= MAX_SECTION_SIZE
) {
927 Crc32GuidSect2
= (CRC32_SECTION_HEADER2
*) FileBuffer
;
928 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
929 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) 0xff;
930 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) 0xff;
931 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) 0xff;
932 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.ExtendedSize
= TotalLength
;
933 memcpy (&(Crc32GuidSect2
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
934 Crc32GuidSect2
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
935 Crc32GuidSect2
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER2
);
936 Crc32GuidSect2
->CRC32Checksum
= Crc32Checksum
;
937 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2
->GuidSectionHeader
.DataOffset
);
939 Crc32GuidSect
= (CRC32_SECTION_HEADER
*) FileBuffer
;
940 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
941 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
942 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
943 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
944 memcpy (&(Crc32GuidSect
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
945 Crc32GuidSect
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
946 Crc32GuidSect
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER
);
947 Crc32GuidSect
->CRC32Checksum
= Crc32Checksum
;
948 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect
->GuidSectionHeader
.DataOffset
);
951 if (TotalLength
>= MAX_SECTION_SIZE
) {
952 VendorGuidSect2
= (EFI_GUID_DEFINED_SECTION2
*) FileBuffer
;
953 VendorGuidSect2
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
954 VendorGuidSect2
->CommonHeader
.Size
[0] = (UINT8
) 0xff;
955 VendorGuidSect2
->CommonHeader
.Size
[1] = (UINT8
) 0xff;
956 VendorGuidSect2
->CommonHeader
.Size
[2] = (UINT8
) 0xff;
957 VendorGuidSect2
->CommonHeader
.ExtendedSize
= InputLength
+ sizeof (EFI_GUID_DEFINED_SECTION2
);
958 memcpy (&(VendorGuidSect2
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
959 VendorGuidSect2
->Attributes
= DataAttribute
;
960 VendorGuidSect2
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION2
) + DataHeaderSize
);
961 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2
->DataOffset
);
963 VendorGuidSect
= (EFI_GUID_DEFINED_SECTION
*) FileBuffer
;
964 VendorGuidSect
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
965 VendorGuidSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
966 VendorGuidSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
967 VendorGuidSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
968 memcpy (&(VendorGuidSect
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
969 VendorGuidSect
->Attributes
= DataAttribute
;
970 VendorGuidSect
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION
) + DataHeaderSize
);
971 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect
->DataOffset
);
974 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
979 *OutFileBuffer
= FileBuffer
;
997 command line parameters
1001 EFI_SUCCESS Section header successfully generated and section concatenated.
1002 EFI_ABORTED Could not generate the section
1003 EFI_OUT_OF_RESOURCES No resource to complete the operation.
1008 UINT32 InputFileNum
;
1010 CHAR8
**InputFileName
;
1011 CHAR8
*OutputFileName
;
1013 CHAR8
*CompressionName
;
1014 CHAR8
*StringBuffer
;
1015 EFI_GUID VendorGuid
= mZeroGuid
;
1018 UINT8 SectCompSubType
;
1019 UINT16 SectGuidAttribute
;
1020 UINT64 SectGuidHeaderLength
;
1021 EFI_VERSION_SECTION
*VersionSect
;
1022 EFI_USER_INTERFACE_SECTION
*UiSect
;
1024 UINT8
*OutFileBuffer
;
1027 UINT32
*InputFileAlign
;
1028 UINT32 InputFileAlignNum
;
1029 EFI_COMMON_SECTION_HEADER
*SectionHeader
;
1031 InputFileAlign
= NULL
;
1032 InputFileAlignNum
= 0;
1033 InputFileName
= NULL
;
1034 OutputFileName
= NULL
;
1036 CompressionName
= NULL
;
1041 SectType
= EFI_SECTION_ALL
;
1042 SectCompSubType
= 0;
1043 SectGuidAttribute
= EFI_GUIDED_SECTION_NONE
;
1044 OutFileBuffer
= NULL
;
1046 Status
= STATUS_SUCCESS
;
1048 SectGuidHeaderLength
= 0;
1052 SetUtilityName (UTILITY_NAME
);
1055 Error (NULL
, 0, 1001, "Missing options", "No options input");
1057 return STATUS_ERROR
;
1061 // Parse command line
1066 if ((stricmp (argv
[0], "-h") == 0) || (stricmp (argv
[0], "--help") == 0)) {
1069 return STATUS_SUCCESS
;
1072 if (stricmp (argv
[0], "--version") == 0) {
1074 return STATUS_SUCCESS
;
1078 if ((stricmp (argv
[0], "-s") == 0) || (stricmp (argv
[0], "--SectionType") == 0)) {
1079 SectionName
= argv
[1];
1080 if (SectionName
== NULL
) {
1081 Error (NULL
, 0, 1003, "Invalid option value", "Section Type can't be NULL");
1089 if ((stricmp (argv
[0], "-o") == 0) || (stricmp (argv
[0], "--outputfile") == 0)) {
1090 OutputFileName
= argv
[1];
1091 if (OutputFileName
== NULL
) {
1092 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be NULL");
1100 if ((stricmp (argv
[0], "-c") == 0) || (stricmp (argv
[0], "--compress") == 0)) {
1101 CompressionName
= argv
[1];
1102 if (CompressionName
== NULL
) {
1103 Error (NULL
, 0, 1003, "Invalid option value", "Compression Type can't be NULL");
1111 if ((stricmp (argv
[0], "-g") == 0) || (stricmp (argv
[0], "--vendor") == 0)) {
1112 Status
= StringToGuid (argv
[1], &VendorGuid
);
1113 if (EFI_ERROR (Status
)) {
1114 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1122 if ((stricmp (argv
[0], "-r") == 0) || (stricmp (argv
[0], "--attributes") == 0)) {
1123 if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]) == 0) {
1124 SectGuidAttribute
|= EFI_GUIDED_SECTION_PROCESSING_REQUIRED
;
1125 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]) == 0) {
1126 SectGuidAttribute
|= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
1127 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[0]) == 0) {
1131 SectGuidAttribute
|= EFI_GUIDED_SECTION_NONE
;
1133 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1141 if ((stricmp (argv
[0], "-l") == 0) || (stricmp (argv
[0], "--HeaderLength") == 0)) {
1142 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &SectGuidHeaderLength
);
1143 if (EFI_ERROR (Status
)) {
1144 Error (NULL
, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv
[0], argv
[1]);
1152 if ((stricmp (argv
[0], "-n") == 0) || (stricmp (argv
[0], "--name") == 0)) {
1153 StringBuffer
= argv
[1];
1154 if (StringBuffer
== NULL
) {
1155 Error (NULL
, 0, 1003, "Invalid option value", "Name can't be NULL");
1163 if ((stricmp (argv
[0], "-j") == 0) || (stricmp (argv
[0], "--buildnumber") == 0)) {
1164 if (argv
[1] == NULL
) {
1165 Error (NULL
, 0, 1003, "Invalid option value", "build number can't be NULL");
1169 // Verify string is a integrator number
1171 for (Index
= 0; Index
< strlen (argv
[1]); Index
++) {
1172 if ((argv
[1][Index
] != '-') && (isdigit ((int)argv
[1][Index
]) == 0)) {
1173 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1178 sscanf (argv
[1], "%d", &VersionNumber
);
1184 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
1185 SetPrintLevel (VERBOSE_LOG_LEVEL
);
1186 VerboseMsg ("Verbose output Mode Set!");
1192 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
1193 SetPrintLevel (KEY_LOG_LEVEL
);
1194 KeyMsg ("Quiet output Mode Set!");
1200 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
1201 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
1202 if (EFI_ERROR (Status
)) {
1203 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1207 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0~9, currnt input level is %d", (int) LogLevel
);
1210 SetPrintLevel (LogLevel
);
1211 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
1218 // Section File alignment requirement
1220 if (stricmp (argv
[0], "--sectionalign") == 0) {
1221 if (InputFileAlignNum
== 0) {
1222 InputFileAlign
= (UINT32
*) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1223 if (InputFileAlign
== NULL
) {
1224 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1227 memset (InputFileAlign
, 1, MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1228 } else if (InputFileAlignNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1229 InputFileAlign
= (UINT32
*) realloc (
1231 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (UINT32
)
1234 if (InputFileAlign
== NULL
) {
1235 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1238 memset (&(InputFileAlign
[InputFileNum
]), 1, (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
)));
1241 Status
= StringtoAlignment (argv
[1], &(InputFileAlign
[InputFileAlignNum
]));
1242 if (EFI_ERROR (Status
)) {
1243 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1248 InputFileAlignNum
++;
1253 // Get Input file name
1255 if ((InputFileNum
== 0) && (InputFileName
== NULL
)) {
1256 InputFileName
= (CHAR8
**) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*));
1257 if (InputFileName
== NULL
) {
1258 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1261 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1262 } else if (InputFileNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1264 // InputFileName buffer too small, need to realloc
1266 InputFileName
= (CHAR8
**) realloc (
1268 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (CHAR8
*)
1271 if (InputFileName
== NULL
) {
1272 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1275 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1278 InputFileName
[InputFileNum
++] = argv
[0];
1283 if (InputFileAlignNum
> 0 && InputFileAlignNum
!= InputFileNum
) {
1284 Error (NULL
, 0, 1003, "Invalid option", "section alignment must be set for each section");
1288 VerboseMsg ("%s tool start.", UTILITY_NAME
);
1291 // Parse all command line parameters to get the corresponding section type.
1293 VerboseMsg ("Section type is %s", SectionName
);
1294 if (SectionName
== NULL
) {
1296 // No specified Section type, default is SECTION_ALL.
1298 SectType
= EFI_SECTION_ALL
;
1299 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
1300 SectType
= EFI_SECTION_COMPRESSION
;
1301 if (CompressionName
== NULL
) {
1303 // Default is PI_STD compression algorithm.
1305 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1306 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
1307 SectCompSubType
= EFI_NOT_COMPRESSED
;
1308 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
1309 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1311 Error (NULL
, 0, 1003, "Invalid option value", "--compress = %s", CompressionName
);
1314 VerboseMsg ("Compress method is %s", mCompressionTypeName
[SectCompSubType
]);
1315 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
1316 SectType
= EFI_SECTION_GUID_DEFINED
;
1318 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_NONE
) != 0) {
1320 // NONE attribute, clear attribute value.
1322 SectGuidAttribute
= SectGuidAttribute
& ~EFI_GUIDED_SECTION_NONE
;
1324 VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
1325 (unsigned) VendorGuid
.Data1
,
1328 VendorGuid
.Data4
[0],
1329 VendorGuid
.Data4
[1],
1330 VendorGuid
.Data4
[2],
1331 VendorGuid
.Data4
[3],
1332 VendorGuid
.Data4
[4],
1333 VendorGuid
.Data4
[5],
1334 VendorGuid
.Data4
[6],
1335 VendorGuid
.Data4
[7]);
1336 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) != 0) {
1337 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]);
1339 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) != 0) {
1340 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]);
1342 if (SectGuidHeaderLength
!= 0) {
1343 VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength
);
1345 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PE32
]) == 0) {
1346 SectType
= EFI_SECTION_PE32
;
1347 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PIC
]) == 0) {
1348 SectType
= EFI_SECTION_PIC
;
1349 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_TE
]) == 0) {
1350 SectType
= EFI_SECTION_TE
;
1351 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
1352 SectType
= EFI_SECTION_DXE_DEPEX
;
1353 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_SMM_DEPEX
]) == 0) {
1354 SectType
= EFI_SECTION_SMM_DEPEX
;
1355 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
1356 SectType
= EFI_SECTION_VERSION
;
1357 if (VersionNumber
< 0 || VersionNumber
> 65535) {
1358 Error (NULL
, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber
);
1361 VerboseMsg ("Version section number is %d", VersionNumber
);
1362 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
1363 SectType
= EFI_SECTION_USER_INTERFACE
;
1364 if (StringBuffer
[0] == '\0') {
1365 Error (NULL
, 0, 1001, "Missing option", "user interface string");
1368 VerboseMsg ("UI section string name is %s", StringBuffer
);
1369 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
1370 SectType
= EFI_SECTION_COMPATIBILITY16
;
1371 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
1372 SectType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
1373 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
1374 SectType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
1375 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_RAW
]) == 0) {
1376 SectType
= EFI_SECTION_RAW
;
1377 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
1378 SectType
= EFI_SECTION_PEI_DEPEX
;
1380 Error (NULL
, 0, 1003, "Invalid option value", "SectionType = %s", SectionName
);
1385 // GuidValue is only required by Guided section.
1387 if ((SectType
!= EFI_SECTION_GUID_DEFINED
) &&
1388 (SectionName
!= NULL
) &&
1389 (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1390 fprintf (stdout
, "Warning: the input guid value is not required for this section type %s\n", SectionName
);
1394 // Check whether there is input file
1396 if ((SectType
!= EFI_SECTION_VERSION
) && (SectType
!= EFI_SECTION_USER_INTERFACE
)) {
1398 // The input file are required for other section type.
1400 if (InputFileNum
== 0) {
1401 Error (NULL
, 0, 1001, "Missing options", "Input files");
1406 // Check whether there is output file
1408 for (Index
= 0; Index
< InputFileNum
; Index
++) {
1409 VerboseMsg ("the %uth input file name is %s", (unsigned) Index
, InputFileName
[Index
]);
1411 if (OutputFileName
== NULL
) {
1412 Error (NULL
, 0, 1001, "Missing options", "Output file");
1414 // OutFile = stdout;
1416 VerboseMsg ("Output file name is %s", OutputFileName
);
1419 // At this point, we've fully validated the command line, and opened appropriate
1420 // files, so let's go and do what we've been asked to do...
1423 // Within this switch, build and write out the section header including any
1424 // section type specific pieces. If there's an input file, it's tacked on later
1427 case EFI_SECTION_COMPRESSION
:
1428 if (InputFileAlign
!= NULL
) {
1429 free (InputFileAlign
);
1430 InputFileAlign
= NULL
;
1432 Status
= GenSectionCompressionSection (
1441 case EFI_SECTION_GUID_DEFINED
:
1442 if (InputFileAlign
!= NULL
&& (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1444 // Only process alignment for the default known CRC32 guided section.
1445 // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.
1447 free (InputFileAlign
);
1448 InputFileAlign
= NULL
;
1450 Status
= GenSectionGuidDefinedSection (
1456 (UINT32
) SectGuidHeaderLength
,
1461 case EFI_SECTION_VERSION
:
1462 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
1464 // 2 bytes for the build number UINT16
1468 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
1470 Index
+= (strlen (StringBuffer
) * 2) + 2;
1471 OutFileBuffer
= (UINT8
*) malloc (Index
);
1472 if (OutFileBuffer
== NULL
) {
1473 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1476 VersionSect
= (EFI_VERSION_SECTION
*) OutFileBuffer
;
1477 VersionSect
->CommonHeader
.Type
= SectType
;
1478 VersionSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1479 VersionSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1480 VersionSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1481 VersionSect
->BuildNumber
= (UINT16
) VersionNumber
;
1482 Ascii2UnicodeString (StringBuffer
, VersionSect
->VersionString
);
1483 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1486 case EFI_SECTION_USER_INTERFACE
:
1487 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
1489 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
1491 Index
+= (strlen (StringBuffer
) * 2) + 2;
1492 OutFileBuffer
= (UINT8
*) malloc (Index
);
1493 if (OutFileBuffer
== NULL
) {
1494 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1497 UiSect
= (EFI_USER_INTERFACE_SECTION
*) OutFileBuffer
;
1498 UiSect
->CommonHeader
.Type
= SectType
;
1499 UiSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1500 UiSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1501 UiSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1502 Ascii2UnicodeString (StringBuffer
, UiSect
->FileNameString
);
1503 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1506 case EFI_SECTION_ALL
:
1508 // read all input file contents into a buffer
1509 // first get the size of all file contents
1511 Status
= GetSectionContents (
1519 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1520 OutFileBuffer
= (UINT8
*) malloc (InputLength
);
1521 if (OutFileBuffer
== NULL
) {
1522 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1526 // read all input file contents into a buffer
1528 Status
= GetSectionContents (
1536 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength
);
1540 // All other section types are caught by default (they're all the same)
1542 Status
= GenSectionCommonLeafSection (
1551 if (Status
!= EFI_SUCCESS
|| OutFileBuffer
== NULL
) {
1552 Error (NULL
, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status
);
1557 // Get output file length
1559 if (SectType
!= EFI_SECTION_ALL
) {
1560 SectionHeader
= (EFI_COMMON_SECTION_HEADER
*)OutFileBuffer
;
1561 InputLength
= *(UINT32
*)SectionHeader
->Size
& 0x00ffffff;
1562 if (InputLength
== 0xffffff) {
1563 InputLength
= ((EFI_COMMON_SECTION_HEADER2
*)SectionHeader
)->ExtendedSize
;
1568 // Write the output file
1570 OutFile
= fopen (LongFilePath (OutputFileName
), "wb");
1571 if (OutFile
== NULL
) {
1572 Error (NULL
, 0, 0001, "Error opening file for writing", OutputFileName
);
1576 fwrite (OutFileBuffer
, InputLength
, 1, OutFile
);
1579 if (InputFileName
!= NULL
) {
1580 free (InputFileName
);
1583 if (InputFileAlign
!= NULL
) {
1584 free (InputFileAlign
);
1587 if (OutFileBuffer
!= NULL
) {
1588 free (OutFileBuffer
);
1591 if (OutFile
!= NULL
) {
1595 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME
, GetUtilityStatus ());
1597 return GetUtilityStatus ();