2 Creates output file that is a properly formed section per the PI spec.
4 Copyright (c) 2004 - 2014, 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 CompressFunction
= NULL
;
673 // Now data is in FileBuffer, compress the data
675 switch (SectCompSubType
) {
676 case EFI_NOT_COMPRESSED
:
677 CompressedLength
= InputLength
;
678 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
679 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
680 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
682 TotalLength
= CompressedLength
+ HeaderLength
;
684 // Copy file buffer to the none compressed data.
686 OutputBuffer
= malloc (TotalLength
);
687 if (OutputBuffer
== NULL
) {
689 return EFI_OUT_OF_RESOURCES
;
691 memcpy (OutputBuffer
+ HeaderLength
, FileBuffer
, CompressedLength
);
693 FileBuffer
= OutputBuffer
;
696 case EFI_STANDARD_COMPRESSION
:
697 CompressFunction
= (COMPRESS_FUNCTION
) EfiCompress
;
701 Error (NULL
, 0, 2000, "Invalid parameter", "unknown compression type");
706 if (CompressFunction
!= NULL
) {
708 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
709 if (Status
== EFI_BUFFER_TOO_SMALL
) {
710 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION
);
711 if (CompressedLength
+ HeaderLength
>= MAX_SECTION_SIZE
) {
712 HeaderLength
= sizeof (EFI_COMPRESSION_SECTION2
);
714 TotalLength
= CompressedLength
+ HeaderLength
;
715 OutputBuffer
= malloc (TotalLength
);
718 return EFI_OUT_OF_RESOURCES
;
721 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
+ HeaderLength
, &CompressedLength
);
725 FileBuffer
= OutputBuffer
;
727 if (EFI_ERROR (Status
)) {
728 if (FileBuffer
!= NULL
) {
736 DebugMsg (NULL
, 0, 9, "comprss file size",
737 "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength
, (unsigned) CompressedLength
);
739 //if (TotalLength >= MAX_SECTION_SIZE) {
740 // Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
741 // if (FileBuffer != NULL) {
742 // free (FileBuffer);
744 // if (OutputBuffer != NULL) {
745 // free (OutputBuffer);
747 // return STATUS_ERROR;
749 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
752 // Add the section header for the compressed data
754 if (TotalLength
>= MAX_SECTION_SIZE
) {
755 CompressionSect2
= (EFI_COMPRESSION_SECTION2
*)FileBuffer
;
757 memset(CompressionSect2
->CommonHeader
.Size
, 0xff, sizeof(UINT8
) * 3);
758 CompressionSect2
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
759 CompressionSect2
->CommonHeader
.ExtendedSize
= TotalLength
;
760 CompressionSect2
->CompressionType
= SectCompSubType
;
761 CompressionSect2
->UncompressedLength
= InputLength
;
763 CompressionSect
= (EFI_COMPRESSION_SECTION
*) FileBuffer
;
765 CompressionSect
->CommonHeader
.Type
= EFI_SECTION_COMPRESSION
;
766 CompressionSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
767 CompressionSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
768 CompressionSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
769 CompressionSect
->CompressionType
= SectCompSubType
;
770 CompressionSect
->UncompressedLength
= InputLength
;
776 *OutFileBuffer
= FileBuffer
;
782 GenSectionGuidDefinedSection (
783 CHAR8
**InputFileName
,
784 UINT32
*InputFileAlign
,
786 EFI_GUID
*VendorGuid
,
787 UINT16 DataAttribute
,
788 UINT32 DataHeaderSize
,
789 UINT8
**OutFileBuffer
795 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
796 Input file must be already sectioned. The function won't validate
797 the input files' contents. Caller should hand in files already
802 InputFileName - Name of the input file.
804 InputFileAlign - Alignment required by the input file data.
806 InputFileNum - Number of input files. Should be at least 1.
808 VendorGuid - Specify vendor guid value.
810 DataAttribute - Specify attribute for the vendor guid data.
812 DataHeaderSize- Guided Data Header Size
814 OutFileBuffer - Buffer pointer to Output file contents
818 EFI_SUCCESS on successful return
819 EFI_INVALID_PARAMETER if InputFileNum is less than 1
820 EFI_ABORTED if unable to open input file.
821 EFI_OUT_OF_RESOURCES No resource to complete the operation.
829 UINT32 Crc32Checksum
;
831 CRC32_SECTION_HEADER
*Crc32GuidSect
;
832 CRC32_SECTION_HEADER2
*Crc32GuidSect2
;
833 EFI_GUID_DEFINED_SECTION
*VendorGuidSect
;
834 EFI_GUID_DEFINED_SECTION2
*VendorGuidSect2
;
842 // read all input file contents into a buffer
843 // first get the size of all file contents
845 Status
= GetSectionContents (
853 if (Status
== EFI_BUFFER_TOO_SMALL
) {
854 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
855 Offset
= sizeof (CRC32_SECTION_HEADER
);
856 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
857 Offset
= sizeof (CRC32_SECTION_HEADER2
);
860 Offset
= sizeof (EFI_GUID_DEFINED_SECTION
);
861 if (InputLength
+ Offset
>= MAX_SECTION_SIZE
) {
862 Offset
= sizeof (EFI_GUID_DEFINED_SECTION2
);
865 TotalLength
= InputLength
+ Offset
;
867 FileBuffer
= (UINT8
*) malloc (InputLength
+ Offset
);
868 if (FileBuffer
== NULL
) {
869 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
870 return EFI_OUT_OF_RESOURCES
;
873 // read all input file contents into a buffer
875 Status
= GetSectionContents (
884 if (EFI_ERROR (Status
)) {
885 if (FileBuffer
!= NULL
) {
888 Error (NULL
, 0, 0001, "Error opening file for reading", InputFileName
[0]);
892 if (InputLength
== 0) {
893 Error (NULL
, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName
);
894 return EFI_NOT_FOUND
;
898 // Now data is in FileBuffer + Offset
900 if (CompareGuid (VendorGuid
, &mZeroGuid
) == 0) {
902 // Default Guid section is CRC32.
905 CalculateCrc32 (FileBuffer
+ Offset
, InputLength
, &Crc32Checksum
);
907 if (TotalLength
>= MAX_SECTION_SIZE
) {
908 Crc32GuidSect2
= (CRC32_SECTION_HEADER2
*) FileBuffer
;
909 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
910 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) 0xff;
911 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) 0xff;
912 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) 0xff;
913 Crc32GuidSect2
->GuidSectionHeader
.CommonHeader
.ExtendedSize
= TotalLength
;
914 memcpy (&(Crc32GuidSect2
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
915 Crc32GuidSect2
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
916 Crc32GuidSect2
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER2
);
917 Crc32GuidSect2
->CRC32Checksum
= Crc32Checksum
;
918 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2
->GuidSectionHeader
.DataOffset
);
920 Crc32GuidSect
= (CRC32_SECTION_HEADER
*) FileBuffer
;
921 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
922 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
923 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
924 Crc32GuidSect
->GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
925 memcpy (&(Crc32GuidSect
->GuidSectionHeader
.SectionDefinitionGuid
), &mEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
926 Crc32GuidSect
->GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
927 Crc32GuidSect
->GuidSectionHeader
.DataOffset
= sizeof (CRC32_SECTION_HEADER
);
928 Crc32GuidSect
->CRC32Checksum
= Crc32Checksum
;
929 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect
->GuidSectionHeader
.DataOffset
);
932 if (TotalLength
>= MAX_SECTION_SIZE
) {
933 VendorGuidSect2
= (EFI_GUID_DEFINED_SECTION2
*) FileBuffer
;
934 VendorGuidSect2
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
935 VendorGuidSect2
->CommonHeader
.Size
[0] = (UINT8
) 0xff;
936 VendorGuidSect2
->CommonHeader
.Size
[1] = (UINT8
) 0xff;
937 VendorGuidSect2
->CommonHeader
.Size
[2] = (UINT8
) 0xff;
938 VendorGuidSect2
->CommonHeader
.ExtendedSize
= InputLength
+ sizeof (EFI_GUID_DEFINED_SECTION2
);
939 memcpy (&(VendorGuidSect2
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
940 VendorGuidSect2
->Attributes
= DataAttribute
;
941 VendorGuidSect2
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION2
) + DataHeaderSize
);
942 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2
->DataOffset
);
944 VendorGuidSect
= (EFI_GUID_DEFINED_SECTION
*) FileBuffer
;
945 VendorGuidSect
->CommonHeader
.Type
= EFI_SECTION_GUID_DEFINED
;
946 VendorGuidSect
->CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
947 VendorGuidSect
->CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
948 VendorGuidSect
->CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
949 memcpy (&(VendorGuidSect
->SectionDefinitionGuid
), VendorGuid
, sizeof (EFI_GUID
));
950 VendorGuidSect
->Attributes
= DataAttribute
;
951 VendorGuidSect
->DataOffset
= (UINT16
) (sizeof (EFI_GUID_DEFINED_SECTION
) + DataHeaderSize
);
952 DebugMsg (NULL
, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect
->DataOffset
);
955 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength
);
960 *OutFileBuffer
= FileBuffer
;
978 command line parameters
982 EFI_SUCCESS Section header successfully generated and section concatenated.
983 EFI_ABORTED Could not generate the section
984 EFI_OUT_OF_RESOURCES No resource to complete the operation.
991 CHAR8
**InputFileName
;
992 CHAR8
*OutputFileName
;
994 CHAR8
*CompressionName
;
996 EFI_GUID VendorGuid
= mZeroGuid
;
999 UINT8 SectCompSubType
;
1000 UINT16 SectGuidAttribute
;
1001 UINT64 SectGuidHeaderLength
;
1002 EFI_VERSION_SECTION
*VersionSect
;
1003 EFI_USER_INTERFACE_SECTION
*UiSect
;
1005 UINT8
*OutFileBuffer
;
1008 UINT32
*InputFileAlign
;
1009 UINT32 InputFileAlignNum
;
1010 EFI_COMMON_SECTION_HEADER
*SectionHeader
;
1012 InputFileAlign
= NULL
;
1013 InputFileAlignNum
= 0;
1014 InputFileName
= NULL
;
1015 OutputFileName
= NULL
;
1017 CompressionName
= NULL
;
1022 SectType
= EFI_SECTION_ALL
;
1023 SectCompSubType
= 0;
1024 SectGuidAttribute
= EFI_GUIDED_SECTION_NONE
;
1025 OutFileBuffer
= NULL
;
1027 Status
= STATUS_SUCCESS
;
1029 SectGuidHeaderLength
= 0;
1033 SetUtilityName (UTILITY_NAME
);
1036 Error (NULL
, 0, 1001, "Missing options", "No options input");
1038 return STATUS_ERROR
;
1042 // Parse command line
1047 if ((stricmp (argv
[0], "-h") == 0) || (stricmp (argv
[0], "--help") == 0)) {
1050 return STATUS_SUCCESS
;
1053 if (stricmp (argv
[0], "--version") == 0) {
1055 return STATUS_SUCCESS
;
1059 if ((stricmp (argv
[0], "-s") == 0) || (stricmp (argv
[0], "--SectionType") == 0)) {
1060 SectionName
= argv
[1];
1061 if (SectionName
== NULL
) {
1062 Error (NULL
, 0, 1003, "Invalid option value", "Section Type can't be NULL");
1070 if ((stricmp (argv
[0], "-o") == 0) || (stricmp (argv
[0], "--outputfile") == 0)) {
1071 OutputFileName
= argv
[1];
1072 if (OutputFileName
== NULL
) {
1073 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be NULL");
1081 if ((stricmp (argv
[0], "-c") == 0) || (stricmp (argv
[0], "--compress") == 0)) {
1082 CompressionName
= argv
[1];
1083 if (CompressionName
== NULL
) {
1084 Error (NULL
, 0, 1003, "Invalid option value", "Compression Type can't be NULL");
1092 if ((stricmp (argv
[0], "-g") == 0) || (stricmp (argv
[0], "--vendor") == 0)) {
1093 Status
= StringToGuid (argv
[1], &VendorGuid
);
1094 if (EFI_ERROR (Status
)) {
1095 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1103 if ((stricmp (argv
[0], "-r") == 0) || (stricmp (argv
[0], "--attributes") == 0)) {
1104 if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]) == 0) {
1105 SectGuidAttribute
|= EFI_GUIDED_SECTION_PROCESSING_REQUIRED
;
1106 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]) == 0) {
1107 SectGuidAttribute
|= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
1108 } else if (stricmp (argv
[1], mGUIDedSectionAttribue
[0]) == 0) {
1112 SectGuidAttribute
|= EFI_GUIDED_SECTION_NONE
;
1114 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1122 if ((stricmp (argv
[0], "-l") == 0) || (stricmp (argv
[0], "--HeaderLength") == 0)) {
1123 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &SectGuidHeaderLength
);
1124 if (EFI_ERROR (Status
)) {
1125 Error (NULL
, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv
[0], argv
[1]);
1133 if ((stricmp (argv
[0], "-n") == 0) || (stricmp (argv
[0], "--name") == 0)) {
1134 StringBuffer
= argv
[1];
1135 if (StringBuffer
== NULL
) {
1136 Error (NULL
, 0, 1003, "Invalid option value", "Name can't be NULL");
1144 if ((stricmp (argv
[0], "-j") == 0) || (stricmp (argv
[0], "--buildnumber") == 0)) {
1145 if (argv
[1] == NULL
) {
1146 Error (NULL
, 0, 1003, "Invalid option value", "build number can't be NULL");
1150 // Verify string is a integrator number
1152 for (Index
= 0; Index
< strlen (argv
[1]); Index
++) {
1153 if ((argv
[1][Index
] != '-') && (isdigit ((int)argv
[1][Index
]) == 0)) {
1154 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1159 sscanf (argv
[1], "%d", &VersionNumber
);
1165 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
1166 SetPrintLevel (VERBOSE_LOG_LEVEL
);
1167 VerboseMsg ("Verbose output Mode Set!");
1173 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
1174 SetPrintLevel (KEY_LOG_LEVEL
);
1175 KeyMsg ("Quiet output Mode Set!");
1181 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
1182 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
1183 if (EFI_ERROR (Status
)) {
1184 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1188 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0~9, currnt input level is %d", (int) LogLevel
);
1191 SetPrintLevel (LogLevel
);
1192 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
1199 // Section File alignment requirement
1201 if (stricmp (argv
[0], "--sectionalign") == 0) {
1202 if (InputFileAlignNum
== 0) {
1203 InputFileAlign
= (UINT32
*) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1204 if (InputFileAlign
== NULL
) {
1205 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1208 memset (InputFileAlign
, 1, MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
));
1209 } else if (InputFileAlignNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1210 InputFileAlign
= (UINT32
*) realloc (
1212 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (UINT32
)
1215 if (InputFileAlign
== NULL
) {
1216 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1219 memset (&(InputFileAlign
[InputFileNum
]), 1, (MAXIMUM_INPUT_FILE_NUM
* sizeof (UINT32
)));
1222 Status
= StringtoAlignment (argv
[1], &(InputFileAlign
[InputFileAlignNum
]));
1223 if (EFI_ERROR (Status
)) {
1224 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
1229 InputFileAlignNum
++;
1234 // Get Input file name
1236 if ((InputFileNum
== 0) && (InputFileName
== NULL
)) {
1237 InputFileName
= (CHAR8
**) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*));
1238 if (InputFileName
== NULL
) {
1239 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1242 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1243 } else if (InputFileNum
% MAXIMUM_INPUT_FILE_NUM
== 0) {
1245 // InputFileName buffer too small, need to realloc
1247 InputFileName
= (CHAR8
**) realloc (
1249 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (CHAR8
*)
1252 if (InputFileName
== NULL
) {
1253 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1256 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (CHAR8
*)));
1259 InputFileName
[InputFileNum
++] = argv
[0];
1264 if (InputFileAlignNum
> 0 && InputFileAlignNum
!= InputFileNum
) {
1265 Error (NULL
, 0, 1003, "Invalid option", "section alignment must be set for each section");
1269 VerboseMsg ("%s tool start.", UTILITY_NAME
);
1272 // Parse all command line parameters to get the corresponding section type.
1274 VerboseMsg ("Section type is %s", SectionName
);
1275 if (SectionName
== NULL
) {
1277 // No specified Section type, default is SECTION_ALL.
1279 SectType
= EFI_SECTION_ALL
;
1280 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
1281 SectType
= EFI_SECTION_COMPRESSION
;
1282 if (CompressionName
== NULL
) {
1284 // Default is PI_STD compression algorithm.
1286 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1287 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
1288 SectCompSubType
= EFI_NOT_COMPRESSED
;
1289 } else if (stricmp (CompressionName
, mCompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
1290 SectCompSubType
= EFI_STANDARD_COMPRESSION
;
1292 Error (NULL
, 0, 1003, "Invalid option value", "--compress = %s", CompressionName
);
1295 VerboseMsg ("Compress method is %s", mCompressionTypeName
[SectCompSubType
]);
1296 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
1297 SectType
= EFI_SECTION_GUID_DEFINED
;
1299 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_NONE
) != 0) {
1301 // NONE attribute, clear attribute value.
1303 SectGuidAttribute
= SectGuidAttribute
& ~EFI_GUIDED_SECTION_NONE
;
1305 VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
1306 (unsigned) VendorGuid
.Data1
,
1309 VendorGuid
.Data4
[0],
1310 VendorGuid
.Data4
[1],
1311 VendorGuid
.Data4
[2],
1312 VendorGuid
.Data4
[3],
1313 VendorGuid
.Data4
[4],
1314 VendorGuid
.Data4
[5],
1315 VendorGuid
.Data4
[6],
1316 VendorGuid
.Data4
[7]);
1317 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) != 0) {
1318 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_PROCESSING_REQUIRED
]);
1320 if ((SectGuidAttribute
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) != 0) {
1321 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue
[EFI_GUIDED_SECTION_AUTH_STATUS_VALID
]);
1323 if (SectGuidHeaderLength
!= 0) {
1324 VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength
);
1326 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PE32
]) == 0) {
1327 SectType
= EFI_SECTION_PE32
;
1328 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PIC
]) == 0) {
1329 SectType
= EFI_SECTION_PIC
;
1330 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_TE
]) == 0) {
1331 SectType
= EFI_SECTION_TE
;
1332 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
1333 SectType
= EFI_SECTION_DXE_DEPEX
;
1334 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_SMM_DEPEX
]) == 0) {
1335 SectType
= EFI_SECTION_SMM_DEPEX
;
1336 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
1337 SectType
= EFI_SECTION_VERSION
;
1338 if (VersionNumber
< 0 || VersionNumber
> 65535) {
1339 Error (NULL
, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber
);
1342 VerboseMsg ("Version section number is %d", VersionNumber
);
1343 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
1344 SectType
= EFI_SECTION_USER_INTERFACE
;
1345 if (StringBuffer
[0] == '\0') {
1346 Error (NULL
, 0, 1001, "Missing option", "user interface string");
1349 VerboseMsg ("UI section string name is %s", StringBuffer
);
1350 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
1351 SectType
= EFI_SECTION_COMPATIBILITY16
;
1352 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
1353 SectType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
1354 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
1355 SectType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
1356 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_RAW
]) == 0) {
1357 SectType
= EFI_SECTION_RAW
;
1358 } else if (stricmp (SectionName
, mSectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
1359 SectType
= EFI_SECTION_PEI_DEPEX
;
1361 Error (NULL
, 0, 1003, "Invalid option value", "SectionType = %s", SectionName
);
1366 // GuidValue is only required by Guided section.
1368 if ((SectType
!= EFI_SECTION_GUID_DEFINED
) && (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1369 fprintf (stdout
, "Warning: the input guid value is not required for this section type %s\n", SectionName
);
1373 // Check whether there is input file
1375 if ((SectType
!= EFI_SECTION_VERSION
) && (SectType
!= EFI_SECTION_USER_INTERFACE
)) {
1377 // The input file are required for other section type.
1379 if (InputFileNum
== 0) {
1380 Error (NULL
, 0, 1001, "Missing options", "Input files");
1385 // Check whether there is output file
1387 for (Index
= 0; Index
< InputFileNum
; Index
++) {
1388 VerboseMsg ("the %uth input file name is %s", (unsigned) Index
, InputFileName
[Index
]);
1390 if (OutputFileName
== NULL
) {
1391 Error (NULL
, 0, 1001, "Missing options", "Output file");
1393 // OutFile = stdout;
1395 VerboseMsg ("Output file name is %s", OutputFileName
);
1398 // At this point, we've fully validated the command line, and opened appropriate
1399 // files, so let's go and do what we've been asked to do...
1402 // Within this switch, build and write out the section header including any
1403 // section type specific pieces. If there's an input file, it's tacked on later
1406 case EFI_SECTION_COMPRESSION
:
1407 if (InputFileAlign
!= NULL
) {
1408 free (InputFileAlign
);
1409 InputFileAlign
= NULL
;
1411 Status
= GenSectionCompressionSection (
1420 case EFI_SECTION_GUID_DEFINED
:
1421 if (InputFileAlign
!= NULL
&& (CompareGuid (&VendorGuid
, &mZeroGuid
) != 0)) {
1423 // Only process alignment for the default known CRC32 guided section.
1424 // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.
1426 free (InputFileAlign
);
1427 InputFileAlign
= NULL
;
1429 Status
= GenSectionGuidDefinedSection (
1435 (UINT32
) SectGuidHeaderLength
,
1440 case EFI_SECTION_VERSION
:
1441 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
1443 // 2 bytes for the build number UINT16
1447 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
1449 Index
+= (strlen (StringBuffer
) * 2) + 2;
1450 OutFileBuffer
= (UINT8
*) malloc (Index
);
1451 if (OutFileBuffer
== NULL
) {
1452 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1455 VersionSect
= (EFI_VERSION_SECTION
*) OutFileBuffer
;
1456 VersionSect
->CommonHeader
.Type
= SectType
;
1457 VersionSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1458 VersionSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1459 VersionSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1460 VersionSect
->BuildNumber
= (UINT16
) VersionNumber
;
1461 Ascii2UnicodeString (StringBuffer
, VersionSect
->VersionString
);
1462 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1465 case EFI_SECTION_USER_INTERFACE
:
1466 Index
= sizeof (EFI_COMMON_SECTION_HEADER
);
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 UiSect
= (EFI_USER_INTERFACE_SECTION
*) OutFileBuffer
;
1477 UiSect
->CommonHeader
.Type
= SectType
;
1478 UiSect
->CommonHeader
.Size
[0] = (UINT8
) (Index
& 0xff);
1479 UiSect
->CommonHeader
.Size
[1] = (UINT8
) ((Index
& 0xff00) >> 8);
1480 UiSect
->CommonHeader
.Size
[2] = (UINT8
) ((Index
& 0xff0000) >> 16);
1481 Ascii2UnicodeString (StringBuffer
, UiSect
->FileNameString
);
1482 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index
);
1485 case EFI_SECTION_ALL
:
1487 // read all input file contents into a buffer
1488 // first get the size of all file contents
1490 Status
= GetSectionContents (
1498 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1499 OutFileBuffer
= (UINT8
*) malloc (InputLength
);
1500 if (OutFileBuffer
== NULL
) {
1501 Error (NULL
, 0, 4001, "Resource", "memory cannot be allcoated");
1505 // read all input file contents into a buffer
1507 Status
= GetSectionContents (
1515 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength
);
1519 // All other section types are caught by default (they're all the same)
1521 Status
= GenSectionCommonLeafSection (
1530 if (Status
!= EFI_SUCCESS
|| OutFileBuffer
== NULL
) {
1531 Error (NULL
, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status
);
1536 // Get output file length
1538 if (SectType
!= EFI_SECTION_ALL
) {
1539 SectionHeader
= (EFI_COMMON_SECTION_HEADER
*)OutFileBuffer
;
1540 InputLength
= *(UINT32
*)SectionHeader
->Size
& 0x00ffffff;
1541 if (InputLength
== 0xffffff) {
1542 InputLength
= ((EFI_COMMON_SECTION_HEADER2
*)SectionHeader
)->ExtendedSize
;
1547 // Write the output file
1549 OutFile
= fopen (LongFilePath (OutputFileName
), "wb");
1550 if (OutFile
== NULL
) {
1551 Error (NULL
, 0, 0001, "Error opening file for writing", OutputFileName
);
1555 fwrite (OutFileBuffer
, InputLength
, 1, OutFile
);
1558 if (InputFileName
!= NULL
) {
1559 free (InputFileName
);
1562 if (InputFileAlign
!= NULL
) {
1563 free (InputFileAlign
);
1566 if (OutFileBuffer
!= NULL
) {
1567 free (OutFileBuffer
);
1570 if (OutFile
!= NULL
) {
1574 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME
, GetUtilityStatus ());
1576 return GetUtilityStatus ();