3 Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
4 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.
22 #include "TianoCommon.h"
23 #include "EfiImageFormat.h"
25 #include "EfiCustomizedCompress.h"
27 #include "EfiUtilityMsgs.h"
33 #include "GenSection.h"
35 #include EFI_PROTOCOL_DEFINITION (GuidedSectionExtraction)
37 #define UTILITY_NAME "GenSection"
39 #define PARAMETER_NOT_SPECIFIED "Parameter not specified"
40 #define MAXIMUM_INPUT_FILE_NUM 10
41 #define MAX_SECTION_SIZE 0x1000000
43 char *SectionTypeName
[] = {
44 NULL
, // 0x00 - reserved
45 "EFI_SECTION_COMPRESSION", // 0x01
46 "EFI_SECTION_GUID_DEFINED", // 0x02
47 NULL
, // 0x03 - reserved
48 NULL
, // 0x04 - reserved
49 NULL
, // 0x05 - reserved
50 NULL
, // 0x06 - reserved
51 NULL
, // 0x07 - reserved
52 NULL
, // 0x08 - reserved
53 NULL
, // 0x09 - reserved
54 NULL
, // 0x0A - reserved
55 NULL
, // 0x0B - reserved
56 NULL
, // 0x0C - reserved
57 NULL
, // 0x0D - reserved
58 NULL
, // 0x0E - reserved
59 NULL
, // 0x0F - reserved
60 "EFI_SECTION_PE32", // 0x10
61 "EFI_SECTION_PIC", // 0x11
62 "EFI_SECTION_TE", // 0x12
63 "EFI_SECTION_DXE_DEPEX", // 0x13
64 "EFI_SECTION_VERSION", // 0x14
65 "EFI_SECTION_USER_INTERFACE", // 0x15
66 "EFI_SECTION_COMPATIBILITY16", // 0x16
67 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17
68 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18
69 "EFI_SECTION_RAW", // 0x19
71 "EFI_SECTION_PEI_DEPEX" // 0x1B
74 char *CompressionTypeName
[] = { "NONE", "STANDARD" };
75 char *GUIDedSectionTypeName
[] = { "CRC32" };
76 EFI_GUID gEfiCrc32SectionGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
87 printf ("Usage: "UTILITY_NAME
" -i InputFile -o OutputFile -s SectionType [SectionType params]\n\n");
88 printf (" Where SectionType is one of the following section types:\n\n");
91 for (SectionType
= 0; SectionType
<= EFI_SECTION_LAST_SECTION_TYPE
; SectionType
++) {
92 if (SectionTypeName
[SectionType
] != NULL
) {
93 printf (" %s\n", SectionTypeName
[SectionType
]);
97 printf ("\n and SectionType dependent parameters are as follows:\n\n");
99 " %s: -t < %s | %s >\n",
100 SectionTypeName
[EFI_SECTION_COMPRESSION
],
101 CompressionTypeName
[EFI_NOT_COMPRESSED
],
102 CompressionTypeName
[EFI_STANDARD_COMPRESSION
]
105 " %s: -t < %s >\n"" // Currently only CRC32 is supported\n\n",
106 SectionTypeName
[EFI_SECTION_GUID_DEFINED
],
107 GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]
110 " %s: -v VersionNumber\n"" [-a \"Version string\"]\n\n",
111 SectionTypeName
[EFI_SECTION_VERSION
]
114 " %s: -a \"Human readable name\"\n\n",
115 SectionTypeName
[EFI_SECTION_USER_INTERFACE
]
120 Ascii2UnicodeWriteString (
123 BOOLEAN WriteLangCode
129 // BUGBUG need to get correct language code...
131 char *EnglishLangCode
= "eng";
134 // first write the language code (english only)
137 fwrite (EnglishLangCode
, 1, 4, OutFile
);
140 // Next, write out the string... Convert ASCII to Unicode in the process.
144 fwrite (&String
[Index
], 1, 1, OutFile
);
145 fwrite (&AsciiNull
, 1, 1, OutFile
);
146 } while (String
[Index
++] != 0);
150 GenSectionCommonLeafSection (
151 char **InputFileName
,
160 Generate a leaf section of type other than EFI_SECTION_VERSION
161 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
162 The function won't validate the input file's contents. For
163 common leaf sections, the input file may be a binary file.
164 The utility will add section header to the file.
168 InputFileName - Name of the input file.
170 InputFileNum - Number of input files. Should be 1 for leaf section.
172 SectionType - A valid section type string
174 OutFile - Output file handle
178 STATUS_ERROR - can't continue
179 STATUS_SUCCESS - successful return
183 UINT64 InputFileLength
;
187 EFI_COMMON_SECTION_HEADER CommonSect
;
190 if (InputFileNum
> 1) {
191 Error (NULL
, 0, 0, "invalid parameter", "more than one input file specified");
193 } else if (InputFileNum
< 1) {
194 Error (NULL
, 0, 0, "no input file specified", NULL
);
198 // Open the input file
200 InFile
= fopen (InputFileName
[0], "rb");
201 if (InFile
== NULL
) {
202 Error (NULL
, 0, 0, InputFileName
[0], "failed to open input file");
206 Status
= STATUS_ERROR
;
209 // Seek to the end of the input file so we can determine its size
211 fseek (InFile
, 0, SEEK_END
);
212 fgetpos (InFile
, &InputFileLength
);
213 fseek (InFile
, 0, SEEK_SET
);
215 // Fill in the fields in the local section header structure
217 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
218 TotalLength
= sizeof (CommonSect
) + (INTN
) InputFileLength
;
220 // Size must fit in 3 bytes
222 if (TotalLength
>= MAX_SECTION_SIZE
) {
223 Error (NULL
, 0, 0, InputFileName
[0], "file size (0x%X) exceeds section size limit(%dM).", TotalLength
, MAX_SECTION_SIZE
>>20);
227 // Now copy the size into the section header and write out the section header
229 memcpy (&CommonSect
.Size
, &TotalLength
, 3);
230 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
232 // Allocate a buffer to read in the contents of the input file. Then
233 // read it in as one block and write it to the output file.
235 if (InputFileLength
!= 0) {
236 Buffer
= (UINT8
*) malloc ((size_t) InputFileLength
);
237 if (Buffer
== NULL
) {
238 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
242 if (fread (Buffer
, (size_t) InputFileLength
, 1, InFile
) != 1) {
243 Error (NULL
, 0, 0, InputFileName
[0], "failed to read contents of file");
247 if (fwrite (Buffer
, (size_t) InputFileLength
, 1, OutFile
) != 1) {
248 Error (NULL
, 0, 0, "failed to write to output file", NULL
);
253 Status
= STATUS_SUCCESS
;
256 if (Buffer
!= NULL
) {
265 char **InputFileName
,
274 Get the contents of all section files specified in InputFileName
279 InputFileName - Name of the input file.
281 InputFileNum - Number of input files. Should be at least 1.
283 FileBuffer - Output buffer to contain data
285 BufferLength - On input, this is size of the FileBuffer.
286 On output, this is the actual length of the data.
290 EFI_SUCCESS on successful return
291 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
292 EFI_ABORTED if unable to open input file.
293 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
301 if (InputFileNum
< 1) {
302 Error (NULL
, 0, 0, "must specify at least one input file", NULL
);
303 return EFI_INVALID_PARAMETER
;
306 if (BufferLength
== NULL
) {
307 Error (NULL
, 0, 0, "BufferLength can't be NULL", NULL
);
308 return EFI_INVALID_PARAMETER
;
313 // Go through our array of file names and copy their contents
314 // to the output buffer.
316 for (Index
= 0; Index
< InputFileNum
; Index
++) {
317 InFile
= fopen (InputFileName
[Index
], "rb");
318 if (InFile
== NULL
) {
319 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to open input file");
323 fseek (InFile
, 0, SEEK_END
);
324 fgetpos (InFile
, &FileSize
);
325 fseek (InFile
, 0, SEEK_SET
);
327 // Now read the contents of the file into the buffer
328 // Buffer must be enough to contain the file content.
330 if (FileSize
> 0 && FileBuffer
!= NULL
&& (Size
+ (UINTN
) FileSize
) <= *BufferLength
) {
331 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
332 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to read contents of input file");
339 Size
+= (UINTN
) FileSize
;
341 // make sure section ends on a DWORD boundary
343 while ((Size
& 0x03) != 0) {
344 if (FileBuffer
!= NULL
&& Size
< *BufferLength
) {
345 FileBuffer
[Size
] = 0;
351 if (Size
> *BufferLength
) {
352 *BufferLength
= Size
;
353 return EFI_BUFFER_TOO_SMALL
;
355 *BufferLength
= Size
;
361 GenSectionCompressionSection (
362 char **InputFileName
,
365 UINTN SectionSubType
,
372 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
373 Input file must be already sectioned. The function won't validate
374 the input files' contents. Caller should hand in files already
379 InputFileName - Name of the input file.
381 InputFileNum - Number of input files. Should be at least 1.
383 SectionType - Section type to generate. Should be
384 EFI_SECTION_COMPRESSION
386 SectionSubType - Specify the compression algorithm requested.
388 OutFile - Output file handle
392 EFI_SUCCESS on successful return
393 EFI_INVALID_PARAMETER if InputFileNum is less than 1
394 EFI_ABORTED if unable to open input file.
395 EFI_OUT_OF_RESOURCES No resource to complete the operation.
400 UINTN CompressedLength
;
404 EFI_COMPRESSION_SECTION CompressionSect
;
405 COMPRESS_FUNCTION CompressFunction
;
407 if (SectionType
!= EFI_SECTION_COMPRESSION
) {
408 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL
);
409 return EFI_INVALID_PARAMETER
;
415 CompressedLength
= 0;
417 // read all input file contents into a buffer
418 // first get the size of all file contents
420 Status
= GetSectionContents (
427 if (Status
== EFI_BUFFER_TOO_SMALL
) {
428 FileBuffer
= (UINT8
*) malloc (InputLength
);
429 if (FileBuffer
== NULL
) {
430 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
431 return EFI_OUT_OF_RESOURCES
;
434 // read all input file contents into a buffer
436 Status
= GetSectionContents (
444 if (EFI_ERROR (Status
)) {
445 if (FileBuffer
!= NULL
) {
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
) TianoCompress
;
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
);
501 if (TotalLength
>= MAX_SECTION_SIZE
) {
502 Error (__FILE__
, __LINE__
, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE
>>20);
503 if (FileBuffer
!= NULL
) {
506 if (OutputBuffer
!= NULL
) {
512 // Add the section header for the compressed data
514 CompressionSect
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
515 CompressionSect
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
516 CompressionSect
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
517 CompressionSect
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
518 CompressionSect
.CompressionType
= (UINT8
) SectionSubType
;
519 CompressionSect
.UncompressedLength
= InputLength
;
521 fwrite (&CompressionSect
, sizeof (CompressionSect
), 1, OutFile
);
522 fwrite (FileBuffer
, CompressedLength
, 1, OutFile
);
528 GenSectionGuidDefinedSection (
529 char **InputFileName
,
532 UINTN SectionSubType
,
539 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
540 Input file must be already sectioned. The function won't validate
541 the input files' contents. Caller should hand in files already
546 InputFileName - Name of the input file.
548 InputFileNum - Number of input files. Should be at least 1.
550 SectionType - Section type to generate. Should be
551 EFI_SECTION_GUID_DEFINED
553 SectionSubType - Specify the authentication algorithm requested.
555 OutFile - Output file handle
559 EFI_SUCCESS on successful return
560 EFI_INVALID_PARAMETER if InputFileNum is less than 1
561 EFI_ABORTED if unable to open input file.
562 EFI_OUT_OF_RESOURCES No resource to complete the operation.
569 UINT32 Crc32Checksum
;
571 CRC32_SECTION_HEADER Crc32GuidSect
;
573 if (SectionType
!= EFI_SECTION_GUID_DEFINED
) {
574 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL
);
575 return EFI_INVALID_PARAMETER
;
581 // read all input file contents into a buffer
582 // first get the size of all file contents
584 Status
= GetSectionContents (
591 if (Status
== EFI_BUFFER_TOO_SMALL
) {
592 FileBuffer
= (UINT8
*) malloc (InputLength
);
593 if (FileBuffer
== NULL
) {
594 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
595 return EFI_OUT_OF_RESOURCES
;
598 // read all input file contents into a buffer
600 Status
= GetSectionContents (
608 if (EFI_ERROR (Status
)) {
609 if (FileBuffer
!= NULL
) {
615 // Now data is in FileBuffer
617 switch (SectionSubType
) {
618 case EFI_SECTION_CRC32_GUID_DEFINED
:
620 CalculateCrc32 (FileBuffer
, InputLength
, &Crc32Checksum
);
621 if (EFI_ERROR (Status
)) {
626 TotalLength
= InputLength
+ CRC32_SECTION_HEADER_SIZE
;
627 if (TotalLength
>= MAX_SECTION_SIZE
) {
628 Error (__FILE__
, __LINE__
, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE
>>20);
633 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
634 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
635 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
636 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
637 memcpy (&(Crc32GuidSect
.GuidSectionHeader
.SectionDefinitionGuid
), &gEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
638 Crc32GuidSect
.GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
639 Crc32GuidSect
.GuidSectionHeader
.DataOffset
= CRC32_SECTION_HEADER_SIZE
;
640 Crc32GuidSect
.CRC32Checksum
= Crc32Checksum
;
645 Error (NULL
, 0, 0, "invalid parameter", "unknown GUID defined type");
650 fwrite (&Crc32GuidSect
, sizeof (Crc32GuidSect
), 1, OutFile
);
651 fwrite (FileBuffer
, InputLength
, 1, OutFile
);
671 command line parameters
675 EFI_SUCCESS Section header successfully generated and section concatenated.
676 EFI_ABORTED Could not generate the section
677 EFI_OUT_OF_RESOURCES No resource to complete the operation.
684 UINTN SectionSubType
;
685 BOOLEAN InputFileRequired
;
686 BOOLEAN SubTypeRequired
;
691 char **InputFileName
;
692 char *OutputFileName
;
693 char AuxString
[500] = { 0 };
695 char *ParamSectionType
;
696 char *ParamSectionSubType
;
699 char *ParamDigitalSignature
;
702 EFI_COMMON_SECTION_HEADER CommonSect
;
704 InputFileName
= NULL
;
705 OutputFileName
= PARAMETER_NOT_SPECIFIED
;
706 ParamSectionType
= PARAMETER_NOT_SPECIFIED
;
707 ParamSectionSubType
= PARAMETER_NOT_SPECIFIED
;
708 ParamLength
= PARAMETER_NOT_SPECIFIED
;
709 ParamVersion
= PARAMETER_NOT_SPECIFIED
;
710 ParamDigitalSignature
= PARAMETER_NOT_SPECIFIED
;
711 Status
= EFI_SUCCESS
;
716 InputFileRequired
= TRUE
;
717 SubTypeRequired
= FALSE
;
721 Status
= EFI_SUCCESS
;
723 SetUtilityName (UTILITY_NAME
);
725 PrintUsageMessage ();
729 // Parse command line
732 while (Index
< argc
) {
733 if (_strcmpi (argv
[Index
], "-i") == 0) {
738 InputFileName
= (char **) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *));
739 if (InputFileName
== NULL
) {
740 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
741 return EFI_OUT_OF_RESOURCES
;
744 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
745 InputFileName
[InputFileNum
] = argv
[Index
];
749 // Parse subsequent parameters until another switch is encountered
751 while ((Index
< argc
) && (argv
[Index
][0] != '-')) {
752 if ((InputFileNum
% MAXIMUM_INPUT_FILE_NUM
) == 0) {
754 // InputFileName buffer too small, need to realloc
756 InputFileName
= (char **) realloc (
758 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (char *)
760 if (InputFileName
== NULL
) {
761 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
762 return EFI_OUT_OF_RESOURCES
;
765 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
768 InputFileName
[InputFileNum
] = argv
[Index
];
775 if (_strcmpi (argv
[Index
], "-o") == 0) {
780 OutputFileName
= argv
[Index
];
781 } else if (_strcmpi (argv
[Index
], "-s") == 0) {
783 // Section Type found
786 ParamSectionType
= argv
[Index
];
787 } else if (_strcmpi (argv
[Index
], "-t") == 0) {
789 // Compression or Authentication type
792 ParamSectionSubType
= argv
[Index
];
793 } else if (_strcmpi (argv
[Index
], "-l") == 0) {
798 ParamLength
= argv
[Index
];
799 } else if (_strcmpi (argv
[Index
], "-v") == 0) {
804 ParamVersion
= argv
[Index
];
805 } else if (_strcmpi (argv
[Index
], "-a") == 0) {
811 // Note, the MSVC C-Start parses out and consolidates quoted strings from the command
812 // line. Quote characters are stripped. If this tool is ported to other environments
813 // this will need to be taken into account
815 strncpy (AuxString
, argv
[Index
], 499);
816 } else if (_strcmpi (argv
[Index
], "-d") == 0) {
818 // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)
821 ParamDigitalSignature
= argv
[Index
];
822 } else if (_strcmpi (argv
[Index
], "-?") == 0) {
823 PrintUsageMessage ();
826 Error (NULL
, 0, 0, argv
[Index
], "unknown option");
827 return GetUtilityStatus ();
833 // At this point, all command line parameters are verified as not being totally
834 // bogus. Next verify the command line parameters are complete and make
837 if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
838 SectionType
= EFI_SECTION_COMPRESSION
;
839 SubTypeRequired
= TRUE
;
840 if (_stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
841 SectionSubType
= EFI_NOT_COMPRESSED
;
842 } else if (_stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
843 SectionSubType
= EFI_STANDARD_COMPRESSION
;
845 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown compression type");
846 PrintUsageMessage ();
847 return GetUtilityStatus ();
849 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
850 SectionType
= EFI_SECTION_GUID_DEFINED
;
851 SubTypeRequired
= TRUE
;
852 if (_stricmp (ParamSectionSubType
, GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]) == 0) {
853 SectionSubType
= EFI_SECTION_CRC32_GUID_DEFINED
;
855 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown GUID defined section type", ParamSectionSubType
);
856 PrintUsageMessage ();
857 return GetUtilityStatus ();
859 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PE32
]) == 0) {
860 SectionType
= EFI_SECTION_PE32
;
861 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PIC
]) == 0) {
862 SectionType
= EFI_SECTION_PIC
;
863 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_TE
]) == 0) {
864 SectionType
= EFI_SECTION_TE
;
865 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
866 SectionType
= EFI_SECTION_DXE_DEPEX
;
867 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
868 SectionType
= EFI_SECTION_VERSION
;
869 InputFileRequired
= FALSE
;
870 Index
= sscanf (ParamVersion
, "%d", &VersionNumber
);
871 if (Index
!= 1 || VersionNumber
< 0 || VersionNumber
> 65565) {
872 Error (NULL
, 0, 0, ParamVersion
, "illegal version number");
873 PrintUsageMessage ();
874 return GetUtilityStatus ();
877 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
880 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
881 SectionType
= EFI_SECTION_USER_INTERFACE
;
882 InputFileRequired
= FALSE
;
883 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
884 Error (NULL
, 0, 0, "user interface string not specified", NULL
);
885 PrintUsageMessage ();
886 return GetUtilityStatus ();
888 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
889 SectionType
= EFI_SECTION_COMPATIBILITY16
;
890 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
891 SectionType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
892 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
893 SectionType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
894 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_RAW
]) == 0) {
895 SectionType
= EFI_SECTION_RAW
;
896 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
897 SectionType
= EFI_SECTION_PEI_DEPEX
;
899 Error (NULL
, 0, 0, ParamSectionType
, "unknown section type");
900 PrintUsageMessage ();
901 return GetUtilityStatus ();
906 OutFile
= fopen (OutputFileName
, "wb");
907 if (OutFile
== NULL
) {
908 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
909 if (InFile
!= NULL
) {
913 return GetUtilityStatus ();
916 // At this point, we've fully validated the command line, and opened appropriate
917 // files, so let's go and do what we've been asked to do...
920 // Within this switch, build and write out the section header including any
921 // section type specific pieces. If there's an input file, it's tacked on later
923 switch (SectionType
) {
924 case EFI_SECTION_COMPRESSION
:
925 Status
= GenSectionCompressionSection (
934 case EFI_SECTION_GUID_DEFINED
:
935 Status
= GenSectionGuidDefinedSection (
944 case EFI_SECTION_VERSION
:
945 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
947 Index
= sizeof (CommonSect
);
949 // 2 characters for the build number
953 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
955 Index
+= (strlen (AuxString
) * 2) + 2;
956 memcpy (&CommonSect
.Size
, &Index
, 3);
957 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
958 fwrite (&VersionNumber
, 2, 1, OutFile
);
959 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
962 case EFI_SECTION_USER_INTERFACE
:
963 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
964 Index
= sizeof (CommonSect
);
966 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
968 Index
+= (strlen (AuxString
) * 2) + 2;
969 memcpy (&CommonSect
.Size
, &Index
, 3);
970 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
971 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
976 // All other section types are caught by default (they're all the same)
978 Status
= GenSectionCommonLeafSection (
987 if (InputFileName
!= NULL
) {
988 free (InputFileName
);
993 // If we had errors, then delete the output file
995 if (GetUtilityStatus () == STATUS_ERROR
) {
996 remove (OutputFileName
);
999 return GetUtilityStatus ();