3 Copyright (c) 2004 - 2010, 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"
38 #define UTILITY_VERSION "v1.0"
40 #define PARAMETER_NOT_SPECIFIED "Parameter not specified"
41 #define MAXIMUM_INPUT_FILE_NUM 10
42 #define MAX_SECTION_SIZE 0x1000000
44 char *SectionTypeName
[] = {
45 NULL
, // 0x00 - reserved
46 "EFI_SECTION_COMPRESSION", // 0x01
47 "EFI_SECTION_GUID_DEFINED", // 0x02
48 NULL
, // 0x03 - reserved
49 NULL
, // 0x04 - reserved
50 NULL
, // 0x05 - reserved
51 NULL
, // 0x06 - reserved
52 NULL
, // 0x07 - reserved
53 NULL
, // 0x08 - reserved
54 NULL
, // 0x09 - reserved
55 NULL
, // 0x0A - reserved
56 NULL
, // 0x0B - reserved
57 NULL
, // 0x0C - reserved
58 NULL
, // 0x0D - reserved
59 NULL
, // 0x0E - reserved
60 NULL
, // 0x0F - reserved
61 "EFI_SECTION_PE32", // 0x10
62 "EFI_SECTION_PIC", // 0x11
63 "EFI_SECTION_TE", // 0x12
64 "EFI_SECTION_DXE_DEPEX", // 0x13
65 "EFI_SECTION_VERSION", // 0x14
66 "EFI_SECTION_USER_INTERFACE", // 0x15
67 "EFI_SECTION_COMPATIBILITY16", // 0x16
68 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17
69 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18
70 "EFI_SECTION_RAW", // 0x19
72 "EFI_SECTION_PEI_DEPEX" // 0x1B
75 char *CompressionTypeName
[] = { "NONE", "STANDARD" };
76 char *GUIDedSectionTypeName
[] = { "CRC32" };
77 EFI_GUID gEfiCrc32SectionGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
88 UTILITY_NAME
" "UTILITY_VERSION
" - Intel Generate Section Utility",
89 " Copyright (C), 2004 - 2008 Intel Corporation",
91 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
92 " Built from "UTILITY_BUILD
", project of "UTILITY_VENDOR
,
96 " "UTILITY_NAME
" [OPTION]",
98 " -i InputFile Specifies the input file",
99 " -o OutputFile Specifies the output file",
100 " -s SectionType Specifies the type of the section, which can be one of",
104 for (Index
= 0; Str
[Index
] != NULL
; Index
++) {
105 fprintf (stdout
, "%s\n", Str
[Index
]);
108 for (SectionType
= 0; SectionType
<= EFI_SECTION_LAST_SECTION_TYPE
; SectionType
++) {
109 if (SectionTypeName
[SectionType
] != NULL
) {
110 fprintf (stdout
, " %s\n", SectionTypeName
[SectionType
]);
113 fprintf (stdout
, "Section dependent options:\n");
115 " %s: -t < %s | %s >\n",
116 SectionTypeName
[EFI_SECTION_COMPRESSION
],
117 CompressionTypeName
[EFI_NOT_COMPRESSED
],
118 CompressionTypeName
[EFI_STANDARD_COMPRESSION
]
121 " %s: -t < %s > // Only CRC32 is supported\n",
122 SectionTypeName
[EFI_SECTION_GUID_DEFINED
],
123 GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]
126 " %s: -v VersionNumber [-a \"Version string\"]\n",
127 SectionTypeName
[EFI_SECTION_VERSION
]
130 " %s: -a \"Human readable name\"\n",
131 SectionTypeName
[EFI_SECTION_USER_INTERFACE
]
136 Ascii2UnicodeWriteString (
139 BOOLEAN WriteLangCode
145 // BUGBUG need to get correct language code...
147 char *EnglishLangCode
= "eng";
150 // first write the language code (english only)
153 fwrite (EnglishLangCode
, 1, 4, OutFile
);
156 // Next, write out the string... Convert ASCII to Unicode in the process.
160 fwrite (&String
[Index
], 1, 1, OutFile
);
161 fwrite (&AsciiNull
, 1, 1, OutFile
);
162 } while (String
[Index
++] != 0);
166 GenSectionCommonLeafSection (
167 char **InputFileName
,
176 Generate a leaf section of type other than EFI_SECTION_VERSION
177 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
178 The function won't validate the input file's contents. For
179 common leaf sections, the input file may be a binary file.
180 The utility will add section header to the file.
184 InputFileName - Name of the input file.
186 InputFileNum - Number of input files. Should be 1 for leaf section.
188 SectionType - A valid section type string
190 OutFile - Output file handle
194 STATUS_ERROR - can't continue
195 STATUS_SUCCESS - successful return
199 UINT64 InputFileLength
;
203 EFI_COMMON_SECTION_HEADER CommonSect
;
206 if (InputFileNum
> 1) {
207 Error (NULL
, 0, 0, "invalid parameter", "more than one input file specified");
209 } else if (InputFileNum
< 1) {
210 Error (NULL
, 0, 0, "no input file specified", NULL
);
214 // Open the input file
216 InFile
= fopen (InputFileName
[0], "rb");
217 if (InFile
== NULL
) {
218 Error (NULL
, 0, 0, InputFileName
[0], "failed to open input file");
222 Status
= STATUS_ERROR
;
225 // Seek to the end of the input file so we can determine its size
227 fseek (InFile
, 0, SEEK_END
);
228 fgetpos (InFile
, &InputFileLength
);
229 fseek (InFile
, 0, SEEK_SET
);
231 // Fill in the fields in the local section header structure
233 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
234 TotalLength
= sizeof (CommonSect
) + (INTN
) InputFileLength
;
236 // Size must fit in 3 bytes
238 if (TotalLength
>= MAX_SECTION_SIZE
) {
239 Error (NULL
, 0, 0, InputFileName
[0], "file size (0x%X) exceeds section size limit(%dM).", TotalLength
, MAX_SECTION_SIZE
>>20);
243 // Now copy the size into the section header and write out the section header
245 memcpy (&CommonSect
.Size
, &TotalLength
, 3);
246 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
248 // Allocate a buffer to read in the contents of the input file. Then
249 // read it in as one block and write it to the output file.
251 if (InputFileLength
!= 0) {
252 Buffer
= (UINT8
*) malloc ((size_t) InputFileLength
);
253 if (Buffer
== NULL
) {
254 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
258 if (fread (Buffer
, (size_t) InputFileLength
, 1, InFile
) != 1) {
259 Error (NULL
, 0, 0, InputFileName
[0], "failed to read contents of file");
263 if (fwrite (Buffer
, (size_t) InputFileLength
, 1, OutFile
) != 1) {
264 Error (NULL
, 0, 0, "failed to write to output file", NULL
);
269 Status
= STATUS_SUCCESS
;
272 if (Buffer
!= NULL
) {
281 char **InputFileName
,
290 Get the contents of all section files specified in InputFileName
295 InputFileName - Name of the input file.
297 InputFileNum - Number of input files. Should be at least 1.
299 FileBuffer - Output buffer to contain data
301 BufferLength - On input, this is size of the FileBuffer.
302 On output, this is the actual length of the data.
306 EFI_SUCCESS on successful return
307 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
308 EFI_ABORTED if unable to open input file.
309 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
317 if (InputFileNum
< 1) {
318 Error (NULL
, 0, 0, "must specify at least one input file", NULL
);
319 return EFI_INVALID_PARAMETER
;
322 if (BufferLength
== NULL
) {
323 Error (NULL
, 0, 0, "BufferLength can't be NULL", NULL
);
324 return EFI_INVALID_PARAMETER
;
329 // Go through our array of file names and copy their contents
330 // to the output buffer.
332 for (Index
= 0; Index
< InputFileNum
; Index
++) {
333 InFile
= fopen (InputFileName
[Index
], "rb");
334 if (InFile
== NULL
) {
335 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to open input file");
339 fseek (InFile
, 0, SEEK_END
);
340 fgetpos (InFile
, &FileSize
);
341 fseek (InFile
, 0, SEEK_SET
);
343 // Now read the contents of the file into the buffer
344 // Buffer must be enough to contain the file content.
346 if (FileSize
> 0 && FileBuffer
!= NULL
&& (Size
+ (UINTN
) FileSize
) <= *BufferLength
) {
347 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
348 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to read contents of input file");
355 Size
+= (UINTN
) FileSize
;
357 // make sure section ends on a DWORD boundary
359 while ((Size
& 0x03) != 0) {
360 if (FileBuffer
!= NULL
&& Size
< *BufferLength
) {
361 FileBuffer
[Size
] = 0;
367 if (Size
> *BufferLength
) {
368 *BufferLength
= Size
;
369 return EFI_BUFFER_TOO_SMALL
;
371 *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;
433 // read all input file contents into a buffer
434 // first get the size of all file contents
436 Status
= GetSectionContents (
443 if (Status
== EFI_BUFFER_TOO_SMALL
) {
444 FileBuffer
= (UINT8
*) malloc (InputLength
);
445 if (FileBuffer
== NULL
) {
446 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
447 return EFI_OUT_OF_RESOURCES
;
450 // read all input file contents into a buffer
452 Status
= GetSectionContents (
460 if (EFI_ERROR (Status
)) {
461 if (FileBuffer
!= NULL
) {
467 CompressFunction
= NULL
;
470 // Now data is in FileBuffer, compress the data
472 switch (SectionSubType
) {
473 case EFI_NOT_COMPRESSED
:
474 CompressedLength
= InputLength
;
477 case EFI_STANDARD_COMPRESSION
:
478 CompressFunction
= (COMPRESS_FUNCTION
) TianoCompress
;
481 case EFI_CUSTOMIZED_COMPRESSION
:
482 CompressFunction
= (COMPRESS_FUNCTION
) CustomizedCompress
;
486 Error (NULL
, 0, 0, "unknown compression type", NULL
);
491 if (CompressFunction
!= NULL
) {
493 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
494 if (Status
== EFI_BUFFER_TOO_SMALL
) {
495 OutputBuffer
= malloc (CompressedLength
);
498 return EFI_OUT_OF_RESOURCES
;
501 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
505 FileBuffer
= OutputBuffer
;
507 if (EFI_ERROR (Status
)) {
508 if (FileBuffer
!= NULL
) {
516 TotalLength
= CompressedLength
+ sizeof (EFI_COMPRESSION_SECTION
);
517 if (TotalLength
>= MAX_SECTION_SIZE
) {
518 Error (__FILE__
, __LINE__
, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE
>>20);
519 if (FileBuffer
!= NULL
) {
522 if (OutputBuffer
!= NULL
) {
528 // Add the section header for the compressed data
530 CompressionSect
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
531 CompressionSect
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
532 CompressionSect
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
533 CompressionSect
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
534 CompressionSect
.CompressionType
= (UINT8
) SectionSubType
;
535 CompressionSect
.UncompressedLength
= InputLength
;
537 fwrite (&CompressionSect
, sizeof (CompressionSect
), 1, OutFile
);
538 fwrite (FileBuffer
, CompressedLength
, 1, OutFile
);
544 GenSectionGuidDefinedSection (
545 char **InputFileName
,
548 UINTN SectionSubType
,
555 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
556 Input file must be already sectioned. The function won't validate
557 the input files' contents. Caller should hand in files already
562 InputFileName - Name of the input file.
564 InputFileNum - Number of input files. Should be at least 1.
566 SectionType - Section type to generate. Should be
567 EFI_SECTION_GUID_DEFINED
569 SectionSubType - Specify the authentication algorithm requested.
571 OutFile - Output file handle
575 EFI_SUCCESS on successful return
576 EFI_INVALID_PARAMETER if InputFileNum is less than 1
577 EFI_ABORTED if unable to open input file.
578 EFI_OUT_OF_RESOURCES No resource to complete the operation.
585 UINT32 Crc32Checksum
;
587 CRC32_SECTION_HEADER Crc32GuidSect
;
589 if (SectionType
!= EFI_SECTION_GUID_DEFINED
) {
590 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL
);
591 return EFI_INVALID_PARAMETER
;
597 // read all input file contents into a buffer
598 // first get the size of all file contents
600 Status
= GetSectionContents (
607 if (Status
== EFI_BUFFER_TOO_SMALL
) {
608 FileBuffer
= (UINT8
*) malloc (InputLength
);
609 if (FileBuffer
== NULL
) {
610 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
611 return EFI_OUT_OF_RESOURCES
;
614 // read all input file contents into a buffer
616 Status
= GetSectionContents (
624 if (EFI_ERROR (Status
)) {
625 if (FileBuffer
!= NULL
) {
631 // Now data is in FileBuffer
633 switch (SectionSubType
) {
634 case EFI_SECTION_CRC32_GUID_DEFINED
:
636 CalculateCrc32 (FileBuffer
, InputLength
, &Crc32Checksum
);
637 if (EFI_ERROR (Status
)) {
642 TotalLength
= InputLength
+ CRC32_SECTION_HEADER_SIZE
;
643 if (TotalLength
>= MAX_SECTION_SIZE
) {
644 Error (__FILE__
, __LINE__
, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE
>>20);
649 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
650 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
651 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
652 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
653 memcpy (&(Crc32GuidSect
.GuidSectionHeader
.SectionDefinitionGuid
), &gEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
654 Crc32GuidSect
.GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
655 Crc32GuidSect
.GuidSectionHeader
.DataOffset
= CRC32_SECTION_HEADER_SIZE
;
656 Crc32GuidSect
.CRC32Checksum
= Crc32Checksum
;
661 Error (NULL
, 0, 0, "invalid parameter", "unknown GUID defined type");
666 fwrite (&Crc32GuidSect
, sizeof (Crc32GuidSect
), 1, OutFile
);
667 fwrite (FileBuffer
, InputLength
, 1, OutFile
);
687 command line parameters
691 EFI_SUCCESS Section header successfully generated and section concatenated.
692 EFI_ABORTED Could not generate the section
693 EFI_OUT_OF_RESOURCES No resource to complete the operation.
700 UINTN SectionSubType
;
701 BOOLEAN InputFileRequired
;
702 BOOLEAN SubTypeRequired
;
707 char **InputFileName
;
708 char *OutputFileName
;
709 char AuxString
[500] = { 0 };
711 char *ParamSectionType
;
712 char *ParamSectionSubType
;
715 char *ParamDigitalSignature
;
718 EFI_COMMON_SECTION_HEADER CommonSect
;
720 InputFileName
= NULL
;
721 OutputFileName
= PARAMETER_NOT_SPECIFIED
;
722 ParamSectionType
= PARAMETER_NOT_SPECIFIED
;
723 ParamSectionSubType
= PARAMETER_NOT_SPECIFIED
;
724 ParamLength
= PARAMETER_NOT_SPECIFIED
;
725 ParamVersion
= PARAMETER_NOT_SPECIFIED
;
726 ParamDigitalSignature
= PARAMETER_NOT_SPECIFIED
;
727 Status
= EFI_SUCCESS
;
732 InputFileRequired
= TRUE
;
733 SubTypeRequired
= FALSE
;
737 Status
= EFI_SUCCESS
;
739 SetUtilityName (UTILITY_NAME
);
741 PrintUsageMessage ();
745 // Parse command line
748 while (Index
< argc
) {
749 if (_strcmpi (argv
[Index
], "-i") == 0) {
754 InputFileName
= (char **) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *));
755 if (InputFileName
== NULL
) {
756 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
757 return EFI_OUT_OF_RESOURCES
;
760 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
761 InputFileName
[InputFileNum
] = argv
[Index
];
765 // Parse subsequent parameters until another switch is encountered
767 while ((Index
< argc
) && (argv
[Index
][0] != '-')) {
768 if ((InputFileNum
% MAXIMUM_INPUT_FILE_NUM
) == 0) {
770 // InputFileName buffer too small, need to realloc
772 InputFileName
= (char **) realloc (
774 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (char *)
776 if (InputFileName
== NULL
) {
777 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
778 return EFI_OUT_OF_RESOURCES
;
781 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
784 InputFileName
[InputFileNum
] = argv
[Index
];
791 if (_strcmpi (argv
[Index
], "-o") == 0) {
796 OutputFileName
= argv
[Index
];
797 } else if (_strcmpi (argv
[Index
], "-s") == 0) {
799 // Section Type found
802 ParamSectionType
= argv
[Index
];
803 } else if (_strcmpi (argv
[Index
], "-t") == 0) {
805 // Compression or Authentication type
808 ParamSectionSubType
= argv
[Index
];
809 } else if (_strcmpi (argv
[Index
], "-l") == 0) {
814 ParamLength
= argv
[Index
];
815 } else if (_strcmpi (argv
[Index
], "-v") == 0) {
820 ParamVersion
= argv
[Index
];
821 } else if (_strcmpi (argv
[Index
], "-a") == 0) {
827 // Note, the MSVC C-Start parses out and consolidates quoted strings from the command
828 // line. Quote characters are stripped. If this tool is ported to other environments
829 // this will need to be taken into account
831 strncpy (AuxString
, argv
[Index
], 499);
832 } else if (_strcmpi (argv
[Index
], "-d") == 0) {
834 // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)
837 ParamDigitalSignature
= argv
[Index
];
838 } else if (_strcmpi (argv
[Index
], "-?") == 0) {
839 PrintUsageMessage ();
842 Error (NULL
, 0, 0, argv
[Index
], "unknown option");
843 return GetUtilityStatus ();
849 // At this point, all command line parameters are verified as not being totally
850 // bogus. Next verify the command line parameters are complete and make
853 if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
854 SectionType
= EFI_SECTION_COMPRESSION
;
855 SubTypeRequired
= TRUE
;
856 if (_stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
857 SectionSubType
= EFI_NOT_COMPRESSED
;
858 } else if (_stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
859 SectionSubType
= EFI_STANDARD_COMPRESSION
;
861 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown compression type");
862 PrintUsageMessage ();
863 return GetUtilityStatus ();
865 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
866 SectionType
= EFI_SECTION_GUID_DEFINED
;
867 SubTypeRequired
= TRUE
;
868 if (_stricmp (ParamSectionSubType
, GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]) == 0) {
869 SectionSubType
= EFI_SECTION_CRC32_GUID_DEFINED
;
871 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown GUID defined section type", ParamSectionSubType
);
872 PrintUsageMessage ();
873 return GetUtilityStatus ();
875 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PE32
]) == 0) {
876 SectionType
= EFI_SECTION_PE32
;
877 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PIC
]) == 0) {
878 SectionType
= EFI_SECTION_PIC
;
879 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_TE
]) == 0) {
880 SectionType
= EFI_SECTION_TE
;
881 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
882 SectionType
= EFI_SECTION_DXE_DEPEX
;
883 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
884 SectionType
= EFI_SECTION_VERSION
;
885 InputFileRequired
= FALSE
;
886 Index
= sscanf (ParamVersion
, "%d", &VersionNumber
);
887 if (Index
!= 1 || VersionNumber
< 0 || VersionNumber
> 65565) {
888 Error (NULL
, 0, 0, ParamVersion
, "illegal version number");
889 PrintUsageMessage ();
890 return GetUtilityStatus ();
893 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
896 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
897 SectionType
= EFI_SECTION_USER_INTERFACE
;
898 InputFileRequired
= FALSE
;
899 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
900 Error (NULL
, 0, 0, "user interface string not specified", NULL
);
901 PrintUsageMessage ();
902 return GetUtilityStatus ();
904 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
905 SectionType
= EFI_SECTION_COMPATIBILITY16
;
906 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
907 SectionType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
908 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
909 SectionType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
910 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_RAW
]) == 0) {
911 SectionType
= EFI_SECTION_RAW
;
912 } else if (_stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
913 SectionType
= EFI_SECTION_PEI_DEPEX
;
915 Error (NULL
, 0, 0, ParamSectionType
, "unknown section type");
916 PrintUsageMessage ();
917 return GetUtilityStatus ();
922 OutFile
= fopen (OutputFileName
, "wb");
923 if (OutFile
== NULL
) {
924 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
925 if (InFile
!= NULL
) {
929 return GetUtilityStatus ();
932 // At this point, we've fully validated the command line, and opened appropriate
933 // files, so let's go and do what we've been asked to do...
936 // Within this switch, build and write out the section header including any
937 // section type specific pieces. If there's an input file, it's tacked on later
939 switch (SectionType
) {
940 case EFI_SECTION_COMPRESSION
:
941 Status
= GenSectionCompressionSection (
950 case EFI_SECTION_GUID_DEFINED
:
951 Status
= GenSectionGuidDefinedSection (
960 case EFI_SECTION_VERSION
:
961 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
963 Index
= sizeof (CommonSect
);
965 // 2 characters for the build number
969 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
971 Index
+= (strlen (AuxString
) * 2) + 2;
972 memcpy (&CommonSect
.Size
, &Index
, 3);
973 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
974 fwrite (&VersionNumber
, 2, 1, OutFile
);
975 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
978 case EFI_SECTION_USER_INTERFACE
:
979 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
980 Index
= sizeof (CommonSect
);
982 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
984 Index
+= (strlen (AuxString
) * 2) + 2;
985 memcpy (&CommonSect
.Size
, &Index
, 3);
986 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
987 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
992 // All other section types are caught by default (they're all the same)
994 Status
= GenSectionCommonLeafSection (
1003 if (InputFileName
!= NULL
) {
1004 free (InputFileName
);
1009 // If we had errors, then delete the output file
1011 if (GetUtilityStatus () == STATUS_ERROR
) {
1012 remove (OutputFileName
);
1015 return GetUtilityStatus ();