3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Creates output file that is a properly formed section per the FV spec.
26 #include <Common/UefiBaseTypes.h>
27 #include <Common/FirmwareVolumeImageFormat.h>
28 #include <Protocol/GuidedSectionExtraction.h>
30 #include "CommonLib.h"
32 #include "EfiCustomizedCompress.h"
34 #include "EfiUtilityMsgs.h"
35 #include "GenSection.h"
38 #define UTILITY_NAME "GenSection"
39 #define UTILITY_MAJOR_VERSION 0
40 #define UTILITY_MINOR_VERSION 1
43 #define PARAMETER_NOT_SPECIFIED "Parameter not specified"
44 #define MAXIMUM_INPUT_FILE_NUM 10
46 char *SectionTypeName
[] = {
47 NULL
, // 0x00 - reserved
48 "EFI_SECTION_COMPRESSION", // 0x01
49 "EFI_SECTION_GUID_DEFINED", // 0x02
50 NULL
, // 0x03 - reserved
51 NULL
, // 0x04 - reserved
52 NULL
, // 0x05 - reserved
53 NULL
, // 0x06 - reserved
54 NULL
, // 0x07 - reserved
55 NULL
, // 0x08 - reserved
56 NULL
, // 0x09 - reserved
57 NULL
, // 0x0A - reserved
58 NULL
, // 0x0B - reserved
59 NULL
, // 0x0C - reserved
60 NULL
, // 0x0D - reserved
61 NULL
, // 0x0E - reserved
62 NULL
, // 0x0F - reserved
63 "EFI_SECTION_PE32", // 0x10
64 "EFI_SECTION_PIC", // 0x11
65 "EFI_SECTION_TE", // 0x12
66 "EFI_SECTION_DXE_DEPEX", // 0x13
67 "EFI_SECTION_VERSION", // 0x14
68 "EFI_SECTION_USER_INTERFACE", // 0x15
69 "EFI_SECTION_COMPATIBILITY16", // 0x16
70 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17
71 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18
72 "EFI_SECTION_RAW", // 0x19
74 "EFI_SECTION_PEI_DEPEX" // 0x1B
77 char *CompressionTypeName
[] = { "NONE", "STANDARD" };
78 char *GUIDedSectionTypeName
[] = { "CRC32" };
79 EFI_GUID gEfiCrc32SectionGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
90 Print out version information for this utility.
102 printf ("%s v%d.%d -Utility to create output file with formed section per the FV spec.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
);
103 printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");
117 printf ("\nUsage: "UTILITY_NAME
" -i InputFile -o OutputFile -s SectionType [SectionType params]\n\n");
118 printf (" Where SectionType is one of the following section types:\n\n");
121 for (SectionType
= 0; SectionType
<= EFI_SECTION_LAST_SECTION_TYPE
; SectionType
++) {
122 if (SectionTypeName
[SectionType
] != NULL
) {
123 printf (" %s\n", SectionTypeName
[SectionType
]);
127 printf ("\n and SectionType dependent parameters are as follows:\n\n");
129 " %s: -t < %s | %s >\n",
130 SectionTypeName
[EFI_SECTION_COMPRESSION
],
131 CompressionTypeName
[EFI_NOT_COMPRESSED
],
132 CompressionTypeName
[EFI_STANDARD_COMPRESSION
]
135 " %s: -t < %s >\n"" // Currently only CRC32 is supported\n\n",
136 SectionTypeName
[EFI_SECTION_GUID_DEFINED
],
137 GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]
140 " %s: -v VersionNumber\n"" [-a \"Version string\"]\n\n",
141 SectionTypeName
[EFI_SECTION_VERSION
]
144 " %s: -a \"Human readable name\"\n\n",
145 SectionTypeName
[EFI_SECTION_USER_INTERFACE
]
150 Ascii2UnicodeWriteString (
153 BOOLEAN WriteLangCode
159 // BUGBUG need to get correct language code...
161 char *EnglishLangCode
= "eng";
164 // first write the language code (english only)
167 fwrite (EnglishLangCode
, 1, 4, OutFile
);
170 // Next, write out the string... Convert ASCII to Unicode in the process.
174 fwrite (&String
[Index
], 1, 1, OutFile
);
175 fwrite (&AsciiNull
, 1, 1, OutFile
);
176 } while (String
[Index
++] != 0);
180 GenSectionCommonLeafSection (
181 char **InputFileName
,
190 Generate a leaf section of type other than EFI_SECTION_VERSION
191 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
192 The function won't validate the input file's contents. For
193 common leaf sections, the input file may be a binary file.
194 The utility will add section header to the file.
198 InputFileName - Name of the input file.
200 InputFileNum - Number of input files. Should be 1 for leaf section.
202 SectionType - A valid section type string
204 OutFile - Output file handle
208 STATUS_ERROR - can't continue
209 STATUS_SUCCESS - successful return
213 UINT64 InputFileLength
;
217 EFI_COMMON_SECTION_HEADER CommonSect
;
220 if (InputFileNum
> 1) {
221 Error (NULL
, 0, 0, "invalid parameter", "more than one input file specified");
223 } else if (InputFileNum
< 1) {
224 Error (NULL
, 0, 0, "no input file specified", NULL
);
228 // Open the input file
230 InFile
= fopen (InputFileName
[0], "rb");
231 if (InFile
== NULL
) {
232 Error (NULL
, 0, 0, InputFileName
[0], "failed to open input file");
236 Status
= STATUS_ERROR
;
239 // Seek to the end of the input file so we can determine its size
241 fseek (InFile
, 0, SEEK_END
);
242 fgetpos (InFile
, &InputFileLength
);
243 fseek (InFile
, 0, SEEK_SET
);
245 // Fill in the fields in the local section header structure
247 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
248 TotalLength
= sizeof (CommonSect
) + (INTN
) InputFileLength
;
250 // Size must fit in 3 bytes
252 if (TotalLength
>= 0x1000000) {
253 Error (NULL
, 0, 0, InputFileName
[0], "file size (0x%X) exceeds section size limit", TotalLength
);
257 // Now copy the size into the section header and write out the section header
259 memcpy (&CommonSect
.Size
, &TotalLength
, 3);
260 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
262 // Allocate a buffer to read in the contents of the input file. Then
263 // read it in as one block and write it to the output file.
265 if (InputFileLength
!= 0) {
266 Buffer
= (UINT8
*) malloc ((size_t) InputFileLength
);
267 if (Buffer
== NULL
) {
268 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
272 if (fread (Buffer
, (size_t) InputFileLength
, 1, InFile
) != 1) {
273 Error (NULL
, 0, 0, InputFileName
[0], "failed to read contents of file");
277 if (fwrite (Buffer
, (size_t) InputFileLength
, 1, OutFile
) != 1) {
278 Error (NULL
, 0, 0, "failed to write to output file", NULL
);
283 Status
= STATUS_SUCCESS
;
286 if (Buffer
!= NULL
) {
295 char **InputFileName
,
304 Get the contents of all section files specified in InputFileName
309 InputFileName - Name of the input file.
311 InputFileNum - Number of input files. Should be at least 1.
313 FileBuffer - Output buffer to contain data
315 BufferLength - Actual length of the data
319 EFI_SUCCESS on successful return
320 EFI_INVALID_PARAMETER if InputFileNum is less than 1
321 EFI_ABORTED if unable to open input file.
330 if (InputFileNum
< 1) {
331 Error (NULL
, 0, 0, "must specify at least one input file", NULL
);
332 return EFI_INVALID_PARAMETER
;
337 // Go through our array of file names and copy their contents
338 // to the output buffer.
340 for (Index
= 0; Index
< InputFileNum
; Index
++) {
341 InFile
= fopen (InputFileName
[Index
], "rb");
342 if (InFile
== NULL
) {
343 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to open input file");
347 fseek (InFile
, 0, SEEK_END
);
348 FileSize
= ftell (InFile
);
349 fseek (InFile
, 0, SEEK_SET
);
351 // Now read the contents of the file into the buffer
354 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
355 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to read contents of input file");
362 Size
+= (UINTN
) FileSize
;
364 // make sure section ends on a DWORD boundary
366 while ((Size
& 0x03) != 0) {
367 FileBuffer
[Size
] = 0;
372 *BufferLength
= Size
;
377 GenSectionCompressionSection (
378 char **InputFileName
,
381 UINTN SectionSubType
,
388 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
389 Input file must be already sectioned. The function won't validate
390 the input files' contents. Caller should hand in files already
395 InputFileName - Name of the input file.
397 InputFileNum - Number of input files. Should be at least 1.
399 SectionType - Section type to generate. Should be
400 EFI_SECTION_COMPRESSION
402 SectionSubType - Specify the compression algorithm requested.
404 OutFile - Output file handle
408 EFI_SUCCESS on successful return
409 EFI_INVALID_PARAMETER if InputFileNum is less than 1
410 EFI_ABORTED if unable to open input file.
411 EFI_OUT_OF_RESOURCES No resource to complete the operation.
416 UINTN CompressedLength
;
420 EFI_COMPRESSION_SECTION CompressionSect
;
421 COMPRESS_FUNCTION CompressFunction
;
423 if (SectionType
!= EFI_SECTION_COMPRESSION
) {
424 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL
);
425 return EFI_INVALID_PARAMETER
;
431 CompressedLength
= 0;
432 FileBuffer
= (UINT8
*) malloc ((1024 * 1024 * 4) * sizeof (UINT8
));
433 if (FileBuffer
== NULL
) {
434 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
435 return EFI_OUT_OF_RESOURCES
;
438 // read all input file contents into a buffer
440 Status
= GetSectionContents (
446 if (EFI_ERROR (Status
)) {
451 CompressFunction
= NULL
;
454 // Now data is in FileBuffer, compress the data
456 switch (SectionSubType
) {
457 case EFI_NOT_COMPRESSED
:
458 CompressedLength
= InputLength
;
461 case EFI_STANDARD_COMPRESSION
:
462 CompressFunction
= (COMPRESS_FUNCTION
) EfiCompress
;
465 case EFI_CUSTOMIZED_COMPRESSION
:
466 CompressFunction
= (COMPRESS_FUNCTION
) CustomizedCompress
;
470 Error (NULL
, 0, 0, "unknown compression type", NULL
);
475 if (CompressFunction
!= NULL
) {
477 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
478 if (Status
== EFI_BUFFER_TOO_SMALL
) {
479 OutputBuffer
= malloc (CompressedLength
);
482 return EFI_OUT_OF_RESOURCES
;
485 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
489 FileBuffer
= OutputBuffer
;
491 if (EFI_ERROR (Status
)) {
492 if (FileBuffer
!= NULL
) {
500 TotalLength
= CompressedLength
+ sizeof (EFI_COMPRESSION_SECTION
);
502 // Add the section header for the compressed data
504 CompressionSect
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
505 CompressionSect
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
506 CompressionSect
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
507 CompressionSect
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
508 CompressionSect
.CompressionType
= (UINT8
) SectionSubType
;
509 CompressionSect
.UncompressedLength
= InputLength
;
511 fwrite (&CompressionSect
, sizeof (CompressionSect
), 1, OutFile
);
512 fwrite (FileBuffer
, CompressedLength
, 1, OutFile
);
518 GenSectionGuidDefinedSection (
519 char **InputFileName
,
522 UINTN SectionSubType
,
529 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
530 Input file must be already sectioned. The function won't validate
531 the input files' contents. Caller should hand in files already
536 InputFileName - Name of the input file.
538 InputFileNum - Number of input files. Should be at least 1.
540 SectionType - Section type to generate. Should be
541 EFI_SECTION_GUID_DEFINED
543 SectionSubType - Specify the authentication algorithm requested.
545 OutFile - Output file handle
549 EFI_SUCCESS on successful return
550 EFI_INVALID_PARAMETER if InputFileNum is less than 1
551 EFI_ABORTED if unable to open input file.
552 EFI_OUT_OF_RESOURCES No resource to complete the operation.
559 UINT32 Crc32Checksum
;
561 CRC32_SECTION_HEADER Crc32GuidSect
;
563 if (SectionType
!= EFI_SECTION_GUID_DEFINED
) {
564 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL
);
565 return EFI_INVALID_PARAMETER
;
570 FileBuffer
= (UINT8
*) malloc ((1024 * 1024 * 4) * sizeof (UINT8
));
571 if (FileBuffer
== NULL
) {
572 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
573 return EFI_OUT_OF_RESOURCES
;
576 // read all input file contents into a buffer
578 Status
= GetSectionContents (
584 if (EFI_ERROR (Status
)) {
589 // Now data is in FileBuffer, compress the data
591 switch (SectionSubType
) {
592 case EFI_SECTION_CRC32_GUID_DEFINED
:
594 CalculateCrc32 (FileBuffer
, InputLength
, &Crc32Checksum
);
595 if (EFI_ERROR (Status
)) {
600 TotalLength
= InputLength
+ CRC32_SECTION_HEADER_SIZE
;
601 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
602 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
603 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
604 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
605 memcpy (&(Crc32GuidSect
.GuidSectionHeader
.SectionDefinitionGuid
), &gEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
606 Crc32GuidSect
.GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
607 Crc32GuidSect
.GuidSectionHeader
.DataOffset
= CRC32_SECTION_HEADER_SIZE
;
608 Crc32GuidSect
.CRC32Checksum
= Crc32Checksum
;
613 Error (NULL
, 0, 0, "invalid parameter", "unknown GUID defined type");
618 fwrite (&Crc32GuidSect
, sizeof (Crc32GuidSect
), 1, OutFile
);
619 fwrite (FileBuffer
, InputLength
, 1, OutFile
);
639 command line parameters
643 EFI_SUCCESS Section header successfully generated and section concatenated.
644 EFI_ABORTED Could not generate the section
645 EFI_OUT_OF_RESOURCES No resource to complete the operation.
652 UINTN SectionSubType
;
653 BOOLEAN InputFileRequired
;
654 BOOLEAN SubTypeRequired
;
659 char **InputFileName
;
660 char *OutputFileName
;
661 char AuxString
[500] = { 0 };
663 char *ParamSectionType
;
664 char *ParamSectionSubType
;
667 char *ParamDigitalSignature
;
670 EFI_COMMON_SECTION_HEADER CommonSect
;
672 InputFileName
= NULL
;
673 OutputFileName
= PARAMETER_NOT_SPECIFIED
;
674 ParamSectionType
= PARAMETER_NOT_SPECIFIED
;
675 ParamSectionSubType
= PARAMETER_NOT_SPECIFIED
;
676 ParamLength
= PARAMETER_NOT_SPECIFIED
;
677 ParamVersion
= PARAMETER_NOT_SPECIFIED
;
678 ParamDigitalSignature
= PARAMETER_NOT_SPECIFIED
;
679 Status
= EFI_SUCCESS
;
684 InputFileRequired
= TRUE
;
685 SubTypeRequired
= FALSE
;
689 Status
= EFI_SUCCESS
;
691 SetUtilityName (UTILITY_NAME
);
698 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0) ||
699 (strcmp(argv
[1], "-?") == 0) || (strcmp(argv
[1], "/?") == 0)) {
704 if ((strcmp(argv
[1], "-V") == 0) || (strcmp(argv
[1], "--version") == 0)) {
710 // Parse command line
713 while (Index
< argc
) {
714 if (strcmpi (argv
[Index
], "-i") == 0) {
719 InputFileName
= (char **) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *));
720 if (InputFileName
== NULL
) {
721 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
722 return EFI_OUT_OF_RESOURCES
;
725 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
726 InputFileName
[InputFileNum
] = argv
[Index
];
730 // Parse subsequent parameters until another switch is encountered
732 while ((Index
< argc
) && (argv
[Index
][0] != '-')) {
733 if ((InputFileNum
% MAXIMUM_INPUT_FILE_NUM
) == 0) {
735 // InputFileName buffer too small, need to realloc
737 InputFileName
= (char **) realloc (
739 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (char *)
741 if (InputFileName
== NULL
) {
742 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
743 return EFI_OUT_OF_RESOURCES
;
746 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
749 InputFileName
[InputFileNum
] = argv
[Index
];
756 if (strcmpi (argv
[Index
], "-o") == 0) {
761 OutputFileName
= argv
[Index
];
762 } else if (strcmpi (argv
[Index
], "-s") == 0) {
764 // Section Type found
767 ParamSectionType
= argv
[Index
];
768 } else if (strcmpi (argv
[Index
], "-t") == 0) {
770 // Compression or Authentication type
773 ParamSectionSubType
= argv
[Index
];
774 } else if (strcmpi (argv
[Index
], "-l") == 0) {
779 ParamLength
= argv
[Index
];
780 } else if (strcmpi (argv
[Index
], "-v") == 0) {
785 ParamVersion
= argv
[Index
];
786 } else if (strcmpi (argv
[Index
], "-a") == 0) {
792 // Note, the MSVC C-Start parses out and consolidates quoted strings from the command
793 // line. Quote characters are stripped. If this tool is ported to other environments
794 // this will need to be taken into account
796 strncpy (AuxString
, argv
[Index
], 499);
797 } else if (strcmpi (argv
[Index
], "-d") == 0) {
799 // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)
802 ParamDigitalSignature
= argv
[Index
];
803 } else if (strcmpi (argv
[Index
], "-?") == 0) {
807 Error (NULL
, 0, 0, argv
[Index
], "unknown option");
808 return GetUtilityStatus ();
814 // At this point, all command line parameters are verified as not being totally
815 // bogus. Next verify the command line parameters are complete and make
818 if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
819 SectionType
= EFI_SECTION_COMPRESSION
;
820 SubTypeRequired
= TRUE
;
821 if (stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
822 SectionSubType
= EFI_NOT_COMPRESSED
;
823 } else if (stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
824 SectionSubType
= EFI_STANDARD_COMPRESSION
;
826 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown compression type");
828 return GetUtilityStatus ();
830 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
831 SectionType
= EFI_SECTION_GUID_DEFINED
;
832 SubTypeRequired
= TRUE
;
833 if (stricmp (ParamSectionSubType
, GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]) == 0) {
834 SectionSubType
= EFI_SECTION_CRC32_GUID_DEFINED
;
836 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown GUID defined section type", ParamSectionSubType
);
838 return GetUtilityStatus ();
840 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PE32
]) == 0) {
841 SectionType
= EFI_SECTION_PE32
;
842 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PIC
]) == 0) {
843 SectionType
= EFI_SECTION_PIC
;
844 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_TE
]) == 0) {
845 SectionType
= EFI_SECTION_TE
;
846 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
847 SectionType
= EFI_SECTION_DXE_DEPEX
;
848 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
849 SectionType
= EFI_SECTION_VERSION
;
850 InputFileRequired
= FALSE
;
851 Index
= sscanf (ParamVersion
, "%d", &VersionNumber
);
852 if (Index
!= 1 || VersionNumber
< 0 || VersionNumber
> 65565) {
853 Error (NULL
, 0, 0, ParamVersion
, "illegal version number");
855 return GetUtilityStatus ();
858 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
861 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
862 SectionType
= EFI_SECTION_USER_INTERFACE
;
863 InputFileRequired
= FALSE
;
864 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
865 Error (NULL
, 0, 0, "user interface string not specified", NULL
);
867 return GetUtilityStatus ();
869 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
870 SectionType
= EFI_SECTION_COMPATIBILITY16
;
871 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
872 SectionType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
873 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
874 SectionType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
875 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_RAW
]) == 0) {
876 SectionType
= EFI_SECTION_RAW
;
877 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
878 SectionType
= EFI_SECTION_PEI_DEPEX
;
880 Error (NULL
, 0, 0, ParamSectionType
, "unknown section type");
882 return GetUtilityStatus ();
887 OutFile
= fopen (OutputFileName
, "wb");
888 if (OutFile
== NULL
) {
889 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
890 if (InFile
!= NULL
) {
894 return GetUtilityStatus ();
897 // At this point, we've fully validated the command line, and opened appropriate
898 // files, so let's go and do what we've been asked to do...
901 // Within this switch, build and write out the section header including any
902 // section type specific pieces. If there's an input file, it's tacked on later
904 switch (SectionType
) {
905 case EFI_SECTION_COMPRESSION
:
906 Status
= GenSectionCompressionSection (
915 case EFI_SECTION_GUID_DEFINED
:
916 Status
= GenSectionGuidDefinedSection (
925 case EFI_SECTION_VERSION
:
926 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
928 Index
= sizeof (CommonSect
);
930 // 2 characters for the build number
934 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
936 Index
+= (strlen (AuxString
) * 2) + 2;
937 memcpy (&CommonSect
.Size
, &Index
, 3);
938 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
939 fwrite (&VersionNumber
, 2, 1, OutFile
);
940 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
943 case EFI_SECTION_USER_INTERFACE
:
944 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
945 Index
= sizeof (CommonSect
);
947 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
949 Index
+= (strlen (AuxString
) * 2) + 2;
950 memcpy (&CommonSect
.Size
, &Index
, 3);
951 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
952 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
957 // All other section types are caught by default (they're all the same)
959 Status
= GenSectionCommonLeafSection (
968 if (InputFileName
!= NULL
) {
969 free (InputFileName
);
974 // If we had errors, then delete the output file
976 if (GetUtilityStatus () == STATUS_ERROR
) {
977 remove (OutputFileName
);
980 return GetUtilityStatus ();