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
, " -v, --verbose Turn on verbose output with informational messages.\n");
191 fprintf (stdout
, " -q, --quiet Disable all messages except key message and fatal error\n");
192 fprintf (stdout
, " -d, --debug level Enable debug messages, at input debug level.\n");
193 fprintf (stdout
, " --version Show program's version number and exit.\n");
194 fprintf (stdout
, " -h, --help Show this help message and exit.\n");
198 Ascii2UnicodeString (
206 Write ascii string as unicode string format to FILE
210 String - Pointer to string that is written to FILE.
211 UniString - Pointer to unicode string
219 while (*String
!= '\0') {
220 *(UniString
++) = (CHAR16
) *(String
++);
223 // End the UniString with a NULL.
229 GenSectionCommonLeafSection (
230 CHAR8
**InputFileName
,
233 UINT8
**OutFileBuffer
239 Generate a leaf section of type other than EFI_SECTION_VERSION
240 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
241 The function won't validate the input file's contents. For
242 common leaf sections, the input file may be a binary file.
243 The utility will add section header to the file.
247 InputFileName - Name of the input file.
249 InputFileNum - Number of input files. Should be 1 for leaf section.
251 SectionType - A valid section type string
253 OutFileBuffer - Buffer pointer to Output file contents
257 STATUS_ERROR - can't continue
258 STATUS_SUCCESS - successful return
262 UINT32 InputFileLength
;
267 EFI_COMMON_SECTION_HEADER
*CommonSect
;
270 if (InputFileNum
> 1) {
271 Error (NULL
, 0, 2000, "Invalid parameter", "more than one input file specified");
273 } else if (InputFileNum
< 1) {
274 Error (NULL
, 0, 2000, "Invalid parameter", "no input file specified");
278 // Open the input file
280 InFile
= fopen (LongFilePath (InputFileName
[0]), "rb");
281 if (InFile
== NULL
) {
282 Error (NULL
, 0, 0001, "Error opening file", InputFileName
[0]);
286 Status
= STATUS_ERROR
;
289 // Seek to the end of the input file so we can determine its size
291 fseek (InFile
, 0, SEEK_END
);
292 InputFileLength
= ftell (InFile
);
293 fseek (InFile
, 0, SEEK_SET
);
294 DebugMsg (NULL
, 0, 9, "Input file", "File name is %s and File size is %u bytes", InputFileName
[0], (unsigned) InputFileLength
);
295 TotalLength
= sizeof (EFI_COMMON_SECTION_HEADER
) + InputFileLength
;
297 // Size must fit in 3 bytes
299 //if (TotalLength >= MAX_SECTION_SIZE) {
300 // Error (NULL, 0, 2000, "Invalid parameter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);
303 HeaderLength
= sizeof (EFI_COMMON_SECTION_HEADER
);
304 if (TotalLength
>= MAX_SECTION_SIZE
) {
305 TotalLength
= sizeof (EFI_COMMON_SECTION_HEADER2
) + InputFileLength
;
306 HeaderLength
= sizeof (EFI_COMMON_SECTION_HEADER2
);
308 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
310 // Fill in the fields in the local section header structure
312 Buffer
= (UINT8
*) malloc ((size_t) TotalLength
);
313 if (Buffer
== NULL
) {
314 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
317 CommonSect
= (EFI_COMMON_SECTION_HEADER
*) Buffer
;
318 CommonSect
->Type
= SectionType
;
319 if (TotalLength
< MAX_SECTION_SIZE
) {
320 CommonSect
->Size
[0] = (UINT8
) (TotalLength
& 0xff);
321 CommonSect
->Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
322 CommonSect
->Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
324 memset(CommonSect
->Size
, 0xff, sizeof(UINT8
) * 3);
325 ((EFI_COMMON_SECTION_HEADER2
*)CommonSect
)->ExtendedSize
= TotalLength
;
329 // read data from the input file.
331 if (InputFileLength
!= 0) {
332 if (fread (Buffer
+ HeaderLength
, (size_t) InputFileLength
, 1, InFile
) != 1) {
333 Error (NULL
, 0, 0004, "Error reading file", InputFileName
[0]);
341 *OutFileBuffer
= Buffer
;
342 Status
= STATUS_SUCCESS
;
353 IN CHAR8
*AlignBuffer
,
354 OUT UINT32
*AlignNumber
360 Converts Align String to align value (1~16M).
364 AlignBuffer - Pointer to Align string.
365 AlignNumber - Pointer to Align value.
369 EFI_SUCCESS Successfully convert align string to align value.
370 EFI_INVALID_PARAMETER Align string is invalid or align value is not in scope.
378 if (AlignBuffer
== NULL
) {
379 return EFI_INVALID_PARAMETER
;
381 for (Index
= 0; Index
< sizeof (mAlignName
) / sizeof (CHAR8
*); Index
++) {
382 if (stricmp (AlignBuffer
, mAlignName
[Index
]) == 0) {
383 *AlignNumber
= 1 << Index
;
387 return EFI_INVALID_PARAMETER
;
392 CHAR8
**InputFileName
,
393 UINT32
*InputFileAlign
,
402 Get the contents of all section files specified in InputFileName
407 InputFileName - Name of the input file.
409 InputFileAlign - Alignment required by the input file data.
411 InputFileNum - Number of input files. Should be at least 1.
413 FileBuffer - Output buffer to contain data
415 BufferLength - On input, this is size of the FileBuffer.
416 On output, this is the actual length of the data.
420 EFI_SUCCESS on successful return
421 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
422 EFI_ABORTED if unable to open input file.
423 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
431 EFI_COMMON_SECTION_HEADER
*SectHeader
;
432 EFI_COMMON_SECTION_HEADER2 TempSectHeader
;
433 EFI_TE_IMAGE_HEADER TeHeader
;
435 EFI_GUID_DEFINED_SECTION GuidSectHeader
;
436 EFI_GUID_DEFINED_SECTION2 GuidSectHeader2
;
439 if (InputFileNum
< 1) {
440 Error (NULL
, 0, 2000, "Invalid parameter", "must specify at least one input file");
441 return EFI_INVALID_PARAMETER
;
444 if (BufferLength
== NULL
) {
445 Error (NULL
, 0, 2000, "Invalid parameter", "BufferLength can't be NULL");
446 return EFI_INVALID_PARAMETER
;
453 // Go through our array of file names and copy their contents
454 // to the output buffer.
456 for (Index
= 0; Index
< InputFileNum
; Index
++) {
458 // make sure section ends on a DWORD boundary
460 while ((Size
& 0x03) != 0) {
461 if (FileBuffer
!= NULL
&& Size
< *BufferLength
) {
462 FileBuffer
[Size
] = 0;
468 // Open file and read contents
470 InFile
= fopen (LongFilePath (InputFileName
[Index
]), "rb");
471 if (InFile
== NULL
) {
472 Error (NULL
, 0, 0001, "Error opening file", InputFileName
[Index
]);
476 fseek (InFile
, 0, SEEK_END
);
477 FileSize
= ftell (InFile
);
478 fseek (InFile
, 0, SEEK_SET
);
479 DebugMsg (NULL
, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName
[Index
], (unsigned) FileSize
);
481 // Adjust section buffer when section alignment is required.
483 if (InputFileAlign
!= NULL
) {
485 // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
489 // The section might be EFI_COMMON_SECTION_HEADER2
490 // But only Type needs to be checked
492 if (FileSize
>= MAX_SECTION_SIZE
) {
493 HeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER2
);
495 HeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER
);
497 fread (&TempSectHeader
, 1, HeaderSize
, InFile
);
498 if (TempSectHeader
.Type
== EFI_SECTION_TE
) {
499 fread (&TeHeader
, 1, sizeof (TeHeader
), InFile
);
500 if (TeHeader
.Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
501 TeOffset
= TeHeader
.StrippedSize
- sizeof (TeHeader
);
503 } else if (TempSectHeader
.Type
== EFI_SECTION_GUID_DEFINED
) {
504 fseek (InFile
, 0, SEEK_SET
);
505 if (FileSize
>= MAX_SECTION_SIZE
) {
506 fread (&GuidSectHeader2
, 1, sizeof (GuidSectHeader2
), InFile
);
507 if ((GuidSectHeader2
.Attributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
508 HeaderSize
= GuidSectHeader2
.DataOffset
;
511 fread (&GuidSectHeader
, 1, sizeof (GuidSectHeader
), InFile
);
512 if ((GuidSectHeader
.Attributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
513 HeaderSize
= GuidSectHeader
.DataOffset
;
518 fseek (InFile
, 0, SEEK_SET
);
521 // Revert TeOffset to the converse value relative to Alignment
522 // This is to assure the original PeImage Header at Alignment.
525 TeOffset
= InputFileAlign
[Index
] - (TeOffset
% InputFileAlign
[Index
]);
526 TeOffset
= TeOffset
% InputFileAlign
[Index
];
530 // make sure section data meet its alignment requirement by adding one raw pad section.
532 if ((InputFileAlign
[Index
] != 0) && (((Size
+ HeaderSize
+ TeOffset
) % InputFileAlign
[Index
]) != 0)) {
533 Offset
= (Size
+ sizeof (EFI_COMMON_SECTION_HEADER
) + HeaderSize
+ TeOffset
+ InputFileAlign
[Index
] - 1) & ~(InputFileAlign
[Index
] - 1);
534 Offset
= Offset
- Size
- HeaderSize
- TeOffset
;
536 if (FileBuffer
!= NULL
&& ((Size
+ Offset
) < *BufferLength
)) {
538 // The maximal alignment is 64K, the raw section size must be less than 0xffffff
540 memset (FileBuffer
+ Size
, 0, Offset
);
541 SectHeader
= (EFI_COMMON_SECTION_HEADER
*) (FileBuffer
+ Size
);
542 SectHeader
->Type
= EFI_SECTION_RAW
;
543 SectHeader
->Size
[0] = (UINT8
) (Offset
& 0xff);
544 SectHeader
->Size
[1] = (UINT8
) ((Offset
& 0xff00) >> 8);
545 SectHeader
->Size
[2] = (UINT8
) ((Offset
& 0xff0000) >> 16);
547 DebugMsg (NULL
, 0, 9, "Pad raw section for section data alignment", "Pad Raw section size is %u", (unsigned) Offset
);
549 Size
= Size
+ Offset
;
554 // Now read the contents of the file into the buffer
555 // Buffer must be enough to contain the file content.
557 if ((FileSize
> 0) && (FileBuffer
!= NULL
) && ((Size
+ FileSize
) <= *BufferLength
)) {
558 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
559 Error (NULL
, 0, 0004, "Error reading file", InputFileName
[Index
]);
570 // Set the real required buffer size.
572 if (Size
> *BufferLength
) {
573 *BufferLength
= Size
;
574 return EFI_BUFFER_TOO_SMALL
;
576 *BufferLength
= Size
;
582 GenSectionCompressionSection (
583 CHAR8
**InputFileName
,
584 UINT32
*InputFileAlign
,
586 UINT8 SectCompSubType
,
587 UINT8
**OutFileBuffer
593 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
594 Input file must be already sectioned. The function won't validate
595 the input files' contents. Caller should hand in files already
600 InputFileName - Name of the input file.
602 InputFileAlign - Alignment required by the input file data.
604 InputFileNum - Number of input files. Should be at least 1.
606 SectCompSubType - Specify the compression algorithm requested.
608 OutFileBuffer - Buffer pointer to Output file contents
612 EFI_SUCCESS on successful return
613 EFI_INVALID_PARAMETER if InputFileNum is less than 1
614 EFI_ABORTED if unable to open input file.
615 EFI_OUT_OF_RESOURCES No resource to complete the operation.
620 UINT32 CompressedLength
;
625 EFI_COMPRESSION_SECTION
*CompressionSect
;
626 EFI_COMPRESSION_SECTION2
*CompressionSect2
;
627 COMPRESS_FUNCTION CompressFunction
;
632 CompressedLength
= 0;
635 // read all input file contents into a buffer
636 // first get the size of all file contents
638 Status
= GetSectionContents (
646 if (Status
== EFI_BUFFER_TOO_SMALL
) {
647 FileBuffer
= (UINT8
*) malloc (InputLength
);
648 if (FileBuffer
== NULL
) {
649 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
650 return EFI_OUT_OF_RESOURCES
;
653 // read all input file contents into a buffer
655 Status
= GetSectionContents (
664 if (EFI_ERROR (Status
)) {
665 if (FileBuffer
!= NULL
) {
671 if (FileBuffer
== NULL
) {
672 return EFI_OUT_OF_RESOURCES
;
675 CompressFunction
= NULL
;
678 // Now data is in FileBuffer, compress the data
680 switch (SectCompSubType
) {
681 case EFI_NOT_COMPRESSED
:
682 CompressedLength
= InputLength
;
683 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
684 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
685 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
687 TotalLength
= CompressedLength
+ HeaderLength
;
689 // Copy file buffer to the none compressed data.
691 OutputBuffer
= malloc (TotalLength
);
692 if (OutputBuffer
== NULL
) {
694 return EFI_OUT_OF_RESOURCES
;
696 memcpy (OutputBuffer
+ HeaderLength
, FileBuffer
, CompressedLength
);
698 FileBuffer
= OutputBuffer
;
701 case EFI_STANDARD_COMPRESSION
:
702 CompressFunction
= (COMPRESS_FUNCTION
) EfiCompress
;
706 Error (NULL
, 0, 2000, "Invalid parameter", "unknown compression type");
711 if (CompressFunction
!= NULL
) {
713 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
714 if (Status
== EFI_BUFFER_TOO_SMALL
) {
715 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
716 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
717 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
719 TotalLength
= CompressedLength
+ HeaderLength
;
720 OutputBuffer
= malloc (TotalLength
);
723 return EFI_OUT_OF_RESOURCES
;
726 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
+ HeaderLength
, &CompressedLength
);
730 FileBuffer
= OutputBuffer
;
732 if (EFI_ERROR (Status
)) {
733 if (FileBuffer
!= NULL
) {
740 if (FileBuffer
== NULL
) {
741 return EFI_OUT_OF_RESOURCES
;
745 DebugMsg (NULL
, 0, 9, "comprss file size",
746 "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength
, (unsigned) CompressedLength
);
748 //if (TotalLength >= MAX_SECTION_SIZE) {
749 // Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
750 // if (FileBuffer != NULL) {
751 // free (FileBuffer);
753 // if (OutputBuffer != NULL) {
754 // free (OutputBuffer);
756 // return STATUS_ERROR;
758 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
761 // Add the section header for the compressed data
763 if (TotalLength
>= MAX_SECTION_SIZE
) {
764 CompressionSect2
= (EFI_COMPRESSION_SECTION2
*)FileBuffer
;
766 memset(CompressionSect2
->CommonHeader
.Size
, 0xff, sizeof(UINT8
) * 3);
767 CompressionSect2
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
768 CompressionSect2
->CommonHeader
.ExtendedSize
= TotalLength
;
769 CompressionSect2
->CompressionType
= SectCompSubType
;
770 CompressionSect2
->UncompressedLength
= InputLength
;
772 CompressionSect
= (EFI_COMPRESSION_SECTION
*) FileBuffer
;
774 CompressionSect
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
775 CompressionSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
776 CompressionSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
777 CompressionSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
778 CompressionSect
->CompressionType
= SectCompSubType
;
779 CompressionSect
->UncompressedLength
= InputLength
;
785 *OutFileBuffer
= FileBuffer
;
791 GenSectionGuidDefinedSection (
792 CHAR8
**InputFileName
,
793 UINT32
*InputFileAlign
,
795 EFI_GUID
*VendorGuid
,
796 UINT16 DataAttribute
,
797 UINT32 DataHeaderSize
,
798 UINT8
**OutFileBuffer
804 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
805 Input file must be already sectioned. The function won't validate
806 the input files' contents. Caller should hand in files already
811 InputFileName - Name of the input file.
813 InputFileAlign - Alignment required by the input file data.
815 InputFileNum - Number of input files. Should be at least 1.
817 VendorGuid - Specify vendor guid value.
819 DataAttribute - Specify attribute for the vendor guid data.
821 DataHeaderSize- Guided Data Header Size
823 OutFileBuffer - Buffer pointer to Output file contents
827 EFI_SUCCESS on successful return
828 EFI_INVALID_PARAMETER if InputFileNum is less than 1
829 EFI_ABORTED if unable to open input file.
830 EFI_OUT_OF_RESOURCES No resource to complete the operation.
838 UINT32 Crc32Checksum
;
840 CRC32_SECTION_HEADER
*Crc32GuidSect
;
841 CRC32_SECTION_HEADER2
*Crc32GuidSect2
;
842 EFI_GUID_DEFINED_SECTION
*VendorGuidSect
;
843 EFI_GUID_DEFINED_SECTION2
*VendorGuidSect2
;
851 // read all input file contents into a buffer
852 // first get the size of all file contents
854 Status
= GetSectionContents (
862 if (Status
== EFI_BUFFER_TOO_SMALL
) {
863 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
864 Offset
= sizeof (CRC32_SECTION_HEADER
);
865 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
866 Offset
= sizeof (CRC32_SECTION_HEADER2
);
869 Offset
= sizeof (EFI_GUID_DEFINED_SECTION
);
870 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
871 Offset
= sizeof (EFI_GUID_DEFINED_SECTION2
);
874 TotalLength
= InputLength
+ Offset
;
876 FileBuffer
= (UINT8
*) malloc (InputLength
+ Offset
);
877 if (FileBuffer
== NULL
) {
878 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
879 return EFI_OUT_OF_RESOURCES
;
882 // read all input file contents into a buffer
884 Status
= GetSectionContents (
893 if (EFI_ERROR (Status
)) {
894 if (FileBuffer
!= NULL
) {
897 Error (NULL
, 0, 0001, "Error opening file for reading", InputFileName
[0]);
901 if (InputLength
== 0) {
902 if (FileBuffer
!= NULL
) {
905 Error (NULL
, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName
);
906 return EFI_NOT_FOUND
;
910 // InputLength != 0, but FileBuffer == NULL means out of resources.
912 if (FileBuffer
== NULL
) {
913 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
914 return EFI_OUT_OF_RESOURCES
;
918 // Now data is in FileBuffer + Offset
920 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
922 // Default Guid section is CRC32.
925 CalculateCrc32 (FileBuffer
+ Offset
, InputLength
, &Crc32Checksum
);
927 if (TotalLength
>= MAX_SECTION_SIZE
) {
928 Crc32GuidSect2
= (CRC32_SECTION_HEADER2
*) FileBuffer
;
929 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
930 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) 0xff;
931 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) 0xff;
932 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) 0xff;
933 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.ExtendedSize
= TotalLength
;
934 memcpy (&(Crc32GuidSect2
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
935 Crc32GuidSect2
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
936 Crc32GuidSect2
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER2
);
937 Crc32GuidSect2
->CRC32Checksum
= Crc32Checksum
;
938 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2
->GuidSectionHeader
.DataOffset
);
940 Crc32GuidSect
= (CRC32_SECTION_HEADER
*) FileBuffer
;
941 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
942 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
943 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
944 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
945 memcpy (&(Crc32GuidSect
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
946 Crc32GuidSect
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
947 Crc32GuidSect
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER
);
948 Crc32GuidSect
->CRC32Checksum
= Crc32Checksum
;
949 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect
->GuidSectionHeader
.DataOffset
);
952 if (TotalLength
>= MAX_SECTION_SIZE
) {
953 VendorGuidSect2
= (EFI_GUID_DEFINED_SECTION2
*) FileBuffer
;
954 VendorGuidSect2
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
955 VendorGuidSect2
->CommonHeader
.Size
[0] = (UINT8
) 0xff;
956 VendorGuidSect2
->CommonHeader
.Size
[1] = (UINT8
) 0xff;
957 VendorGuidSect2
->CommonHeader
.Size
[2] = (UINT8
) 0xff;
958 VendorGuidSect2
->CommonHeader
.ExtendedSize
= InputLength
+ sizeof (EFI_GUID_DEFINED_SECTION2
);
959 memcpy (&(VendorGuidSect2
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
960 VendorGuidSect2
->Attributes
= DataAttribute
;
961 VendorGuidSect2
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION2
) + DataHeaderSize
);
962 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2
->DataOffset
);
964 VendorGuidSect
= (EFI_GUID_DEFINED_SECTION
*) FileBuffer
;
965 VendorGuidSect
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
966 VendorGuidSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
967 VendorGuidSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
968 VendorGuidSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
969 memcpy (&(VendorGuidSect
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
970 VendorGuidSect
->Attributes
= DataAttribute
;
971 VendorGuidSect
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION
) + DataHeaderSize
);
972 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect
->DataOffset
);
975 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
980 *OutFileBuffer
= FileBuffer
;
998 command line parameters
1002 EFI_SUCCESS Section header successfully generated and section concatenated.
1003 EFI_ABORTED Could not generate the section
1004 EFI_OUT_OF_RESOURCES No resource to complete the operation.
1009 UINT32 InputFileNum
;
1011 CHAR8
**InputFileName
;
1012 CHAR8
*OutputFileName
;
1014 CHAR8
*CompressionName
;
1015 CHAR8
*StringBuffer
;
1016 EFI_GUID VendorGuid
= mZeroGuid
;
1019 UINT8 SectCompSubType
;
1020 UINT16 SectGuidAttribute
;
1021 UINT64 SectGuidHeaderLength
;
1022 EFI_VERSION_SECTION
*VersionSect
;
1023 EFI_USER_INTERFACE_SECTION
*UiSect
;
1025 UINT8
*OutFileBuffer
;
1028 UINT32
*InputFileAlign
;
1029 UINT32 InputFileAlignNum
;
1030 EFI_COMMON_SECTION_HEADER
*SectionHeader
;
1032 InputFileAlign
= NULL
;
1033 InputFileAlignNum
= 0;
1034 InputFileName
= NULL
;
1035 OutputFileName
= NULL
;
1037 CompressionName
= NULL
;
1042 SectType
= EFI_SECTION_ALL
;
1043 SectCompSubType
= 0;
1044 SectGuidAttribute
= EFI_GUIDED_SECTION_NONE
;
1045 OutFileBuffer
= NULL
;
1047 Status
= STATUS_SUCCESS
;
1049 SectGuidHeaderLength
= 0;
1053 SetUtilityName (UTILITY_NAME
);
1056 Error (NULL
, 0, 1001, "Missing options", "No options input");
1058 return STATUS_ERROR
;
1062 // Parse command line
1067 if ((stricmp (argv
[0], "-h") == 0) || (stricmp (argv
[0], "--help") == 0)) {
1070 return STATUS_SUCCESS
;
1073 if (stricmp (argv
[0], "--version") == 0) {
1075 return STATUS_SUCCESS
;
1079 if ((stricmp (argv
[0], "-s") == 0) || (stricmp (argv
[0], "--SectionType") == 0)) {
1080 SectionName
= argv
[1];
1081 if (SectionName
== NULL
) {
1082 Error (NULL
, 0, 1003, "Invalid option value", "Section Type can't be NULL");
1090 if ((stricmp (argv
[0], "-o") == 0) || (stricmp (argv
[0], "--outputfile") == 0)) {
1091 OutputFileName
= argv
[1];
1092 if (OutputFileName
== NULL
) {
1093 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be NULL");
1101 if ((stricmp (argv
[0], "-c") == 0) || (stricmp (argv
[0], "--compress") == 0)) {
1102 CompressionName
= argv
[1];
1103 if (CompressionName
== NULL
) {
1104 Error (NULL
, 0, 1003, "Invalid option value", "Compression Type can't be NULL");
1112 if ((stricmp (argv
[0], "-g") == 0) || (stricmp (argv
[0], "--vendor") == 0)) {
1113 Status
= StringToGuid (argv
[1], &VendorGuid
);
1114 if (EFI_ERROR (Status
)) {
1115 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1123 if ((stricmp (argv
[0], "-r") == 0) || (stricmp (argv
[0], "--attributes") == 0)) {
1124 if (argv
[1] == NULL
) {
1125 Error (NULL
, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");
1128 if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]) == 0) {
1129 SectGuidAttribute
|= EFI_GUIDED_SECTION_PROCESSING_REQUIRED
;
1130 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]) == 0) {
1131 SectGuidAttribute
|= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
1132 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[0]) == 0) {
1136 SectGuidAttribute
|= EFI_GUIDED_SECTION_NONE
;
1138 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1146 if ((stricmp (argv
[0], "-l") == 0) || (stricmp (argv
[0], "--HeaderLength") == 0)) {
1147 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &SectGuidHeaderLength
);
1148 if (EFI_ERROR (Status
)) {
1149 Error (NULL
, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv
[0], argv
[1]);
1157 if ((stricmp (argv
[0], "-n") == 0) || (stricmp (argv
[0], "--name") == 0)) {
1158 StringBuffer
= argv
[1];
1159 if (StringBuffer
== NULL
) {
1160 Error (NULL
, 0, 1003, "Invalid option value", "Name can't be NULL");
1168 if ((stricmp (argv
[0], "-j") == 0) || (stricmp (argv
[0], "--buildnumber") == 0)) {
1169 if (argv
[1] == NULL
) {
1170 Error (NULL
, 0, 1003, "Invalid option value", "build number can't be NULL");
1174 // Verify string is a integrator number
1176 for (Index
= 0; Index
< strlen (argv
[1]); Index
++) {
1177 if ((argv
[1][Index
] != '-') && (isdigit ((int)argv
[1][Index
]) == 0)) {
1178 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1183 sscanf (argv
[1], "%d", &VersionNumber
);
1189 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
1190 SetPrintLevel (VERBOSE_LOG_LEVEL
);
1191 VerboseMsg ("Verbose output Mode Set!");
1197 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
1198 SetPrintLevel (KEY_LOG_LEVEL
);
1199 KeyMsg ("Quiet output Mode Set!");
1205 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
1206 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
1207 if (EFI_ERROR (Status
)) {
1208 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1212 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0~9, currnt input level is %d", (int) LogLevel
);
1215 SetPrintLevel (LogLevel
);
1216 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
1223 // Section File alignment requirement
1225 if (stricmp (argv
[0], "--sectionalign") == 0) {
1226 if (InputFileAlignNum
== 0) {
1227 InputFileAlign
= (UINT32
*) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1228 if (InputFileAlign
== NULL
) {
1229 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1232 memset (InputFileAlign
, 1, MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1233 } else if (InputFileAlignNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1234 InputFileAlign
= (UINT32
*) realloc (
1236 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (UINT32
)
1239 if (InputFileAlign
== NULL
) {
1240 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1243 memset (&(InputFileAlign
[InputFileNum
]), 1, (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
)));
1246 Status
= StringtoAlignment (argv
[1], &(InputFileAlign
[InputFileAlignNum
]));
1247 if (EFI_ERROR (Status
)) {
1248 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1253 InputFileAlignNum
++;
1258 // Get Input file name
1260 if ((InputFileNum
== 0) && (InputFileName
== NULL
)) {
1261 InputFileName
= (CHAR8
**) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*));
1262 if (InputFileName
== NULL
) {
1263 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1266 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1267 } else if (InputFileNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1269 // InputFileName buffer too small, need to realloc
1271 InputFileName
= (CHAR8
**) realloc (
1273 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (CHAR8
*)
1276 if (InputFileName
== NULL
) {
1277 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1280 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1283 InputFileName
[InputFileNum
++] = argv
[0];
1288 if (InputFileAlignNum
> 0 && InputFileAlignNum
!= InputFileNum
) {
1289 Error (NULL
, 0, 1003, "Invalid option", "section alignment must be set for each section");
1293 VerboseMsg ("%s tool start.", UTILITY_NAME
);
1296 // Parse all command line parameters to get the corresponding section type.
1298 VerboseMsg ("Section type is %s", SectionName
);
1299 if (SectionName
== NULL
) {
1301 // No specified Section type, default is SECTION_ALL.
1303 SectType
= EFI_SECTION_ALL
;
1304 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
1305 SectType
= EFI_SECTION_COMPRESSION
;
1306 if (CompressionName
== NULL
) {
1308 // Default is PI_STD compression algorithm.
1310 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1311 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
1312 SectCompSubType
= EFI_NOT_COMPRESSED
;
1313 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
1314 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1316 Error (NULL
, 0, 1003, "Invalid option value", "--compress = %s", CompressionName
);
1319 VerboseMsg ("Compress method is %s", mCompressionTypeName
[SectCompSubType
]);
1320 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
1321 SectType
= EFI_SECTION_GUID_DEFINED
;
1323 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_NONE
) != 0) {
1325 // NONE attribute, clear attribute value.
1327 SectGuidAttribute
= SectGuidAttribute
& ~EFI_GUIDED_SECTION_NONE
;
1329 VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
1330 (unsigned) VendorGuid
.Data1
,
1333 VendorGuid
.Data4
[0],
1334 VendorGuid
.Data4
[1],
1335 VendorGuid
.Data4
[2],
1336 VendorGuid
.Data4
[3],
1337 VendorGuid
.Data4
[4],
1338 VendorGuid
.Data4
[5],
1339 VendorGuid
.Data4
[6],
1340 VendorGuid
.Data4
[7]);
1341 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) != 0) {
1342 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]);
1344 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) != 0) {
1345 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]);
1347 if (SectGuidHeaderLength
!= 0) {
1348 VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength
);
1350 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PE32
]) == 0) {
1351 SectType
= EFI_SECTION_PE32
;
1352 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PIC
]) == 0) {
1353 SectType
= EFI_SECTION_PIC
;
1354 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_TE
]) == 0) {
1355 SectType
= EFI_SECTION_TE
;
1356 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
1357 SectType
= EFI_SECTION_DXE_DEPEX
;
1358 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_SMM_DEPEX
]) == 0) {
1359 SectType
= EFI_SECTION_SMM_DEPEX
;
1360 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
1361 SectType
= EFI_SECTION_VERSION
;
1362 if (VersionNumber
< 0 || VersionNumber
> 65535) {
1363 Error (NULL
, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber
);
1366 VerboseMsg ("Version section number is %d", VersionNumber
);
1367 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
1368 SectType
= EFI_SECTION_USER_INTERFACE
;
1369 if (StringBuffer
[0] == '\0') {
1370 Error (NULL
, 0, 1001, "Missing option", "user interface string");
1373 VerboseMsg ("UI section string name is %s", StringBuffer
);
1374 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
1375 SectType
= EFI_SECTION_COMPATIBILITY16
;
1376 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
1377 SectType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
1378 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
1379 SectType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
1380 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_RAW
]) == 0) {
1381 SectType
= EFI_SECTION_RAW
;
1382 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
1383 SectType
= EFI_SECTION_PEI_DEPEX
;
1385 Error (NULL
, 0, 1003, "Invalid option value", "SectionType = %s", SectionName
);
1390 // GuidValue is only required by Guided section.
1392 if ((SectType
!= EFI_SECTION_GUID_DEFINED
) &&
1393 (SectionName
!= NULL
) &&
1394 (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1395 fprintf (stdout
, "Warning: the input guid value is not required for this section type %s\n", SectionName
);
1399 // Check whether there is input file
1401 if ((SectType
!= EFI_SECTION_VERSION
) && (SectType
!= EFI_SECTION_USER_INTERFACE
)) {
1403 // The input file are required for other section type.
1405 if (InputFileNum
== 0) {
1406 Error (NULL
, 0, 1001, "Missing options", "Input files");
1411 // Check whether there is output file
1413 for (Index
= 0; Index
< InputFileNum
; Index
++) {
1414 VerboseMsg ("the %uth input file name is %s", (unsigned) Index
, InputFileName
[Index
]);
1416 if (OutputFileName
== NULL
) {
1417 Error (NULL
, 0, 1001, "Missing options", "Output file");
1419 // OutFile = stdout;
1421 VerboseMsg ("Output file name is %s", OutputFileName
);
1424 // At this point, we've fully validated the command line, and opened appropriate
1425 // files, so let's go and do what we've been asked to do...
1428 // Within this switch, build and write out the section header including any
1429 // section type specific pieces. If there's an input file, it's tacked on later
1432 case EFI_SECTION_COMPRESSION
:
1433 if (InputFileAlign
!= NULL
) {
1434 free (InputFileAlign
);
1435 InputFileAlign
= NULL
;
1437 Status
= GenSectionCompressionSection (
1446 case EFI_SECTION_GUID_DEFINED
:
1447 if (InputFileAlign
!= NULL
&& (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1449 // Only process alignment for the default known CRC32 guided section.
1450 // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.
1452 free (InputFileAlign
);
1453 InputFileAlign
= NULL
;
1455 Status
= GenSectionGuidDefinedSection (
1461 (UINT32
) SectGuidHeaderLength
,
1466 case EFI_SECTION_VERSION
:
1467 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
1469 // 2 bytes for the build number UINT16
1473 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
1475 Index
+= (strlen (StringBuffer
) * 2) + 2;
1476 OutFileBuffer
= (UINT8
*) malloc (Index
);
1477 if (OutFileBuffer
== NULL
) {
1478 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1481 VersionSect
= (EFI_VERSION_SECTION
*) OutFileBuffer
;
1482 VersionSect
->CommonHeader
.Type
= SectType
;
1483 VersionSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1484 VersionSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1485 VersionSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1486 VersionSect
->BuildNumber
= (UINT16
) VersionNumber
;
1487 Ascii2UnicodeString (StringBuffer
, VersionSect
->VersionString
);
1488 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1491 case EFI_SECTION_USER_INTERFACE
:
1492 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
1494 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
1496 Index
+= (strlen (StringBuffer
) * 2) + 2;
1497 OutFileBuffer
= (UINT8
*) malloc (Index
);
1498 if (OutFileBuffer
== NULL
) {
1499 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1502 UiSect
= (EFI_USER_INTERFACE_SECTION
*) OutFileBuffer
;
1503 UiSect
->CommonHeader
.Type
= SectType
;
1504 UiSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1505 UiSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1506 UiSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1507 Ascii2UnicodeString (StringBuffer
, UiSect
->FileNameString
);
1508 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1511 case EFI_SECTION_ALL
:
1513 // read all input file contents into a buffer
1514 // first get the size of all file contents
1516 Status
= GetSectionContents (
1524 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1525 OutFileBuffer
= (UINT8
*) malloc (InputLength
);
1526 if (OutFileBuffer
== NULL
) {
1527 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1531 // read all input file contents into a buffer
1533 Status
= GetSectionContents (
1541 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength
);
1545 // All other section types are caught by default (they're all the same)
1547 Status
= GenSectionCommonLeafSection (
1556 if (Status
!= EFI_SUCCESS
|| OutFileBuffer
== NULL
) {
1557 Error (NULL
, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status
);
1562 // Get output file length
1564 if (SectType
!= EFI_SECTION_ALL
) {
1565 SectionHeader
= (EFI_COMMON_SECTION_HEADER
*)OutFileBuffer
;
1566 InputLength
= *(UINT32
*)SectionHeader
->Size
& 0x00ffffff;
1567 if (InputLength
== 0xffffff) {
1568 InputLength
= ((EFI_COMMON_SECTION_HEADER2
*)SectionHeader
)->ExtendedSize
;
1573 // Write the output file
1575 OutFile
= fopen (LongFilePath (OutputFileName
), "wb");
1576 if (OutFile
== NULL
) {
1577 Error (NULL
, 0, 0001, "Error opening file for writing", OutputFileName
);
1581 fwrite (OutFileBuffer
, InputLength
, 1, OutFile
);
1584 if (InputFileName
!= NULL
) {
1585 free (InputFileName
);
1588 if (InputFileAlign
!= NULL
) {
1589 free (InputFileAlign
);
1592 if (OutFileBuffer
!= NULL
) {
1593 free (OutFileBuffer
);
1596 if (OutFile
!= NULL
) {
1600 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME
, GetUtilityStatus ());
1602 return GetUtilityStatus ();