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.
23 #include <UefiBaseTypes.h>
24 #include "FirmwareVolumeImageFormat.h"
25 #include "CommonLib.h"
26 #include "EfiCompress.h"
27 #include "EfiCustomizedCompress.h"
29 #include "EfiUtilityMsgs.h"
35 #include "GenSection.h"
37 #include <GuidedSectionExtraction.h>
39 #define UTILITY_NAME "GenSection"
41 #define PARAMETER_NOT_SPECIFIED "Parameter not specified"
42 #define MAXIMUM_INPUT_FILE_NUM 10
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 printf ("Usage: "UTILITY_NAME
" -i InputFile -o OutputFile -s SectionType [SectionType params]\n\n");
89 printf (" Where SectionType is one of the following section types:\n\n");
92 for (SectionType
= 0; SectionType
<= EFI_SECTION_LAST_SECTION_TYPE
; SectionType
++) {
93 if (SectionTypeName
[SectionType
] != NULL
) {
94 printf (" %s\n", SectionTypeName
[SectionType
]);
98 printf ("\n and SectionType dependent parameters are as follows:\n\n");
100 " %s: -t < %s | %s >\n",
101 SectionTypeName
[EFI_SECTION_COMPRESSION
],
102 CompressionTypeName
[EFI_NOT_COMPRESSED
],
103 CompressionTypeName
[EFI_STANDARD_COMPRESSION
]
106 " %s: -t < %s >\n"" // Currently only CRC32 is supported\n\n",
107 SectionTypeName
[EFI_SECTION_GUID_DEFINED
],
108 GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]
111 " %s: -v VersionNumber\n"" [-a \"Version string\"]\n\n",
112 SectionTypeName
[EFI_SECTION_VERSION
]
115 " %s: -a \"Human readable name\"\n\n",
116 SectionTypeName
[EFI_SECTION_USER_INTERFACE
]
121 Ascii2UnicodeWriteString (
124 BOOLEAN WriteLangCode
130 // BUGBUG need to get correct language code...
132 char *EnglishLangCode
= "eng";
135 // first write the language code (english only)
138 fwrite (EnglishLangCode
, 1, 4, OutFile
);
141 // Next, write out the string... Convert ASCII to Unicode in the process.
145 fwrite (&String
[Index
], 1, 1, OutFile
);
146 fwrite (&AsciiNull
, 1, 1, OutFile
);
147 } while (String
[Index
++] != 0);
151 GenSectionCommonLeafSection (
152 char **InputFileName
,
161 Generate a leaf section of type other than EFI_SECTION_VERSION
162 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
163 The function won't validate the input file's contents. For
164 common leaf sections, the input file may be a binary file.
165 The utility will add section header to the file.
169 InputFileName - Name of the input file.
171 InputFileNum - Number of input files. Should be 1 for leaf section.
173 SectionType - A valid section type string
175 OutFile - Output file handle
179 STATUS_ERROR - can't continue
180 STATUS_SUCCESS - successful return
184 UINT64 InputFileLength
;
188 EFI_COMMON_SECTION_HEADER CommonSect
;
191 if (InputFileNum
> 1) {
192 Error (NULL
, 0, 0, "invalid parameter", "more than one input file specified");
194 } else if (InputFileNum
< 1) {
195 Error (NULL
, 0, 0, "no input file specified", NULL
);
199 // Open the input file
201 InFile
= fopen (InputFileName
[0], "rb");
202 if (InFile
== NULL
) {
203 Error (NULL
, 0, 0, InputFileName
[0], "failed to open input file");
207 Status
= STATUS_ERROR
;
210 // Seek to the end of the input file so we can determine its size
212 fseek (InFile
, 0, SEEK_END
);
213 fgetpos (InFile
, &InputFileLength
);
214 fseek (InFile
, 0, SEEK_SET
);
216 // Fill in the fields in the local section header structure
218 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
219 TotalLength
= sizeof (CommonSect
) + (INTN
) InputFileLength
;
221 // Size must fit in 3 bytes
223 if (TotalLength
>= 0x1000000) {
224 Error (NULL
, 0, 0, InputFileName
[0], "file size (0x%X) exceeds section size limit", TotalLength
);
228 // Now copy the size into the section header and write out the section header
230 memcpy (&CommonSect
.Size
, &TotalLength
, 3);
231 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
233 // Allocate a buffer to read in the contents of the input file. Then
234 // read it in as one block and write it to the output file.
236 if (InputFileLength
!= 0) {
237 Buffer
= (UINT8
*) malloc ((size_t) InputFileLength
);
238 if (Buffer
== NULL
) {
239 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
243 if (fread (Buffer
, (size_t) InputFileLength
, 1, InFile
) != 1) {
244 Error (NULL
, 0, 0, InputFileName
[0], "failed to read contents of file");
248 if (fwrite (Buffer
, (size_t) InputFileLength
, 1, OutFile
) != 1) {
249 Error (NULL
, 0, 0, "failed to write to output file", NULL
);
254 Status
= STATUS_SUCCESS
;
257 if (Buffer
!= NULL
) {
266 char **InputFileName
,
275 Get the contents of all section files specified in InputFileName
280 InputFileName - Name of the input file.
282 InputFileNum - Number of input files. Should be at least 1.
284 FileBuffer - Output buffer to contain data
286 BufferLength - Actual length of the data
290 EFI_SUCCESS on successful return
291 EFI_INVALID_PARAMETER if InputFileNum is less than 1
292 EFI_ABORTED if unable to open input file.
301 if (InputFileNum
< 1) {
302 Error (NULL
, 0, 0, "must specify at least one input file", NULL
);
303 return EFI_INVALID_PARAMETER
;
308 // Go through our array of file names and copy their contents
309 // to the output buffer.
311 for (Index
= 0; Index
< InputFileNum
; Index
++) {
312 InFile
= fopen (InputFileName
[Index
], "rb");
313 if (InFile
== NULL
) {
314 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to open input file");
318 fseek (InFile
, 0, SEEK_END
);
319 FileSize
= ftell (InFile
);
320 fseek (InFile
, 0, SEEK_SET
);
322 // Now read the contents of the file into the buffer
325 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
326 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to read contents of input file");
333 Size
+= (UINTN
) FileSize
;
335 // make sure section ends on a DWORD boundary
337 while ((Size
& 0x03) != 0) {
338 FileBuffer
[Size
] = 0;
343 *BufferLength
= Size
;
348 GenSectionCompressionSection (
349 char **InputFileName
,
352 UINTN SectionSubType
,
359 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
360 Input file must be already sectioned. The function won't validate
361 the input files' contents. Caller should hand in files already
366 InputFileName - Name of the input file.
368 InputFileNum - Number of input files. Should be at least 1.
370 SectionType - Section type to generate. Should be
371 EFI_SECTION_COMPRESSION
373 SectionSubType - Specify the compression algorithm requested.
375 OutFile - Output file handle
379 EFI_SUCCESS on successful return
380 EFI_INVALID_PARAMETER if InputFileNum is less than 1
381 EFI_ABORTED if unable to open input file.
382 EFI_OUT_OF_RESOURCES No resource to complete the operation.
387 UINTN CompressedLength
;
391 EFI_COMPRESSION_SECTION CompressionSect
;
392 COMPRESS_FUNCTION CompressFunction
;
394 if (SectionType
!= EFI_SECTION_COMPRESSION
) {
395 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL
);
396 return EFI_INVALID_PARAMETER
;
402 CompressedLength
= 0;
403 FileBuffer
= (UINT8
*) malloc ((1024 * 1024 * 4) * sizeof (UINT8
));
404 if (FileBuffer
== NULL
) {
405 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
406 return EFI_OUT_OF_RESOURCES
;
409 // read all input file contents into a buffer
411 Status
= GetSectionContents (
417 if (EFI_ERROR (Status
)) {
422 CompressFunction
= NULL
;
425 // Now data is in FileBuffer, compress the data
427 switch (SectionSubType
) {
428 case EFI_NOT_COMPRESSED
:
429 CompressedLength
= InputLength
;
432 case EFI_STANDARD_COMPRESSION
:
433 CompressFunction
= (COMPRESS_FUNCTION
) Compress
;
436 case EFI_CUSTOMIZED_COMPRESSION
:
437 CompressFunction
= (COMPRESS_FUNCTION
) CustomizedCompress
;
441 Error (NULL
, 0, 0, "unknown compression type", NULL
);
446 if (CompressFunction
!= NULL
) {
448 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
449 if (Status
== EFI_BUFFER_TOO_SMALL
) {
450 OutputBuffer
= malloc (CompressedLength
);
453 return EFI_OUT_OF_RESOURCES
;
456 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
460 FileBuffer
= OutputBuffer
;
462 if (EFI_ERROR (Status
)) {
463 if (FileBuffer
!= NULL
) {
471 TotalLength
= CompressedLength
+ sizeof (EFI_COMPRESSION_SECTION
);
473 // Add the section header for the compressed data
475 CompressionSect
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
476 CompressionSect
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
477 CompressionSect
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
478 CompressionSect
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
479 CompressionSect
.CompressionType
= (UINT8
) SectionSubType
;
480 CompressionSect
.UncompressedLength
= InputLength
;
482 fwrite (&CompressionSect
, sizeof (CompressionSect
), 1, OutFile
);
483 fwrite (FileBuffer
, CompressedLength
, 1, OutFile
);
489 GenSectionGuidDefinedSection (
490 char **InputFileName
,
493 UINTN SectionSubType
,
500 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
501 Input file must be already sectioned. The function won't validate
502 the input files' contents. Caller should hand in files already
507 InputFileName - Name of the input file.
509 InputFileNum - Number of input files. Should be at least 1.
511 SectionType - Section type to generate. Should be
512 EFI_SECTION_GUID_DEFINED
514 SectionSubType - Specify the authentication algorithm requested.
516 OutFile - Output file handle
520 EFI_SUCCESS on successful return
521 EFI_INVALID_PARAMETER if InputFileNum is less than 1
522 EFI_ABORTED if unable to open input file.
523 EFI_OUT_OF_RESOURCES No resource to complete the operation.
530 UINT32 Crc32Checksum
;
532 CRC32_SECTION_HEADER Crc32GuidSect
;
534 if (SectionType
!= EFI_SECTION_GUID_DEFINED
) {
535 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL
);
536 return EFI_INVALID_PARAMETER
;
541 FileBuffer
= (UINT8
*) malloc ((1024 * 1024 * 4) * sizeof (UINT8
));
542 if (FileBuffer
== NULL
) {
543 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
544 return EFI_OUT_OF_RESOURCES
;
547 // read all input file contents into a buffer
549 Status
= GetSectionContents (
555 if (EFI_ERROR (Status
)) {
560 // Now data is in FileBuffer, compress the data
562 switch (SectionSubType
) {
563 case EFI_SECTION_CRC32_GUID_DEFINED
:
565 CalculateCrc32 (FileBuffer
, InputLength
, &Crc32Checksum
);
566 if (EFI_ERROR (Status
)) {
571 TotalLength
= InputLength
+ CRC32_SECTION_HEADER_SIZE
;
572 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
573 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
574 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
575 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
576 memcpy (&(Crc32GuidSect
.GuidSectionHeader
.SectionDefinitionGuid
), &gEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
577 Crc32GuidSect
.GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
578 Crc32GuidSect
.GuidSectionHeader
.DataOffset
= CRC32_SECTION_HEADER_SIZE
;
579 Crc32GuidSect
.CRC32Checksum
= Crc32Checksum
;
584 Error (NULL
, 0, 0, "invalid parameter", "unknown GUID defined type");
589 fwrite (&Crc32GuidSect
, sizeof (Crc32GuidSect
), 1, OutFile
);
590 fwrite (FileBuffer
, InputLength
, 1, OutFile
);
610 command line parameters
614 EFI_SUCCESS Section header successfully generated and section concatenated.
615 EFI_ABORTED Could not generate the section
616 EFI_OUT_OF_RESOURCES No resource to complete the operation.
623 UINTN SectionSubType
;
624 BOOLEAN InputFileRequired
;
625 BOOLEAN SubTypeRequired
;
630 char **InputFileName
;
631 char *OutputFileName
;
632 char AuxString
[500] = { 0 };
634 char *ParamSectionType
;
635 char *ParamSectionSubType
;
638 char *ParamDigitalSignature
;
641 EFI_COMMON_SECTION_HEADER CommonSect
;
643 InputFileName
= NULL
;
644 OutputFileName
= PARAMETER_NOT_SPECIFIED
;
645 ParamSectionType
= PARAMETER_NOT_SPECIFIED
;
646 ParamSectionSubType
= PARAMETER_NOT_SPECIFIED
;
647 ParamLength
= PARAMETER_NOT_SPECIFIED
;
648 ParamVersion
= PARAMETER_NOT_SPECIFIED
;
649 ParamDigitalSignature
= PARAMETER_NOT_SPECIFIED
;
650 Status
= EFI_SUCCESS
;
655 InputFileRequired
= TRUE
;
656 SubTypeRequired
= FALSE
;
660 Status
= EFI_SUCCESS
;
662 SetUtilityName (UTILITY_NAME
);
664 PrintUsageMessage ();
668 // Parse command line
671 while (Index
< argc
) {
672 if (strcmpi (argv
[Index
], "-i") == 0) {
677 InputFileName
= (char **) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *));
678 if (InputFileName
== NULL
) {
679 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
680 return EFI_OUT_OF_RESOURCES
;
683 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
684 InputFileName
[InputFileNum
] = argv
[Index
];
688 // Parse subsequent parameters until another switch is encountered
690 while ((Index
< argc
) && (argv
[Index
][0] != '-')) {
691 if ((InputFileNum
% MAXIMUM_INPUT_FILE_NUM
) == 0) {
693 // InputFileName buffer too small, need to realloc
695 InputFileName
= (char **) realloc (
697 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (char *)
699 if (InputFileName
== NULL
) {
700 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
701 return EFI_OUT_OF_RESOURCES
;
704 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
707 InputFileName
[InputFileNum
] = argv
[Index
];
714 if (strcmpi (argv
[Index
], "-o") == 0) {
719 OutputFileName
= argv
[Index
];
720 } else if (strcmpi (argv
[Index
], "-s") == 0) {
722 // Section Type found
725 ParamSectionType
= argv
[Index
];
726 } else if (strcmpi (argv
[Index
], "-t") == 0) {
728 // Compression or Authentication type
731 ParamSectionSubType
= argv
[Index
];
732 } else if (strcmpi (argv
[Index
], "-l") == 0) {
737 ParamLength
= argv
[Index
];
738 } else if (strcmpi (argv
[Index
], "-v") == 0) {
743 ParamVersion
= argv
[Index
];
744 } else if (strcmpi (argv
[Index
], "-a") == 0) {
750 // Note, the MSVC C-Start parses out and consolidates quoted strings from the command
751 // line. Quote characters are stripped. If this tool is ported to other environments
752 // this will need to be taken into account
754 strncpy (AuxString
, argv
[Index
], 499);
755 } else if (strcmpi (argv
[Index
], "-d") == 0) {
757 // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)
760 ParamDigitalSignature
= argv
[Index
];
761 } else if (strcmpi (argv
[Index
], "-?") == 0) {
762 PrintUsageMessage ();
765 Error (NULL
, 0, 0, argv
[Index
], "unknown option");
766 return GetUtilityStatus ();
772 // At this point, all command line parameters are verified as not being totally
773 // bogus. Next verify the command line parameters are complete and make
776 if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
777 SectionType
= EFI_SECTION_COMPRESSION
;
778 SubTypeRequired
= TRUE
;
779 if (stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
780 SectionSubType
= EFI_NOT_COMPRESSED
;
781 } else if (stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
782 SectionSubType
= EFI_STANDARD_COMPRESSION
;
784 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown compression type");
785 PrintUsageMessage ();
786 return GetUtilityStatus ();
788 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
789 SectionType
= EFI_SECTION_GUID_DEFINED
;
790 SubTypeRequired
= TRUE
;
791 if (stricmp (ParamSectionSubType
, GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]) == 0) {
792 SectionSubType
= EFI_SECTION_CRC32_GUID_DEFINED
;
794 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown GUID defined section type", ParamSectionSubType
);
795 PrintUsageMessage ();
796 return GetUtilityStatus ();
798 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PE32
]) == 0) {
799 SectionType
= EFI_SECTION_PE32
;
800 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PIC
]) == 0) {
801 SectionType
= EFI_SECTION_PIC
;
802 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_TE
]) == 0) {
803 SectionType
= EFI_SECTION_TE
;
804 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
805 SectionType
= EFI_SECTION_DXE_DEPEX
;
806 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
807 SectionType
= EFI_SECTION_VERSION
;
808 InputFileRequired
= FALSE
;
809 Index
= sscanf (ParamVersion
, "%d", &VersionNumber
);
810 if (Index
!= 1 || VersionNumber
< 0 || VersionNumber
> 65565) {
811 Error (NULL
, 0, 0, ParamVersion
, "illegal version number");
812 PrintUsageMessage ();
813 return GetUtilityStatus ();
816 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
819 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
820 SectionType
= EFI_SECTION_USER_INTERFACE
;
821 InputFileRequired
= FALSE
;
822 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
823 Error (NULL
, 0, 0, "user interface string not specified", NULL
);
824 PrintUsageMessage ();
825 return GetUtilityStatus ();
827 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
828 SectionType
= EFI_SECTION_COMPATIBILITY16
;
829 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
830 SectionType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
831 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
832 SectionType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
833 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_RAW
]) == 0) {
834 SectionType
= EFI_SECTION_RAW
;
835 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
836 SectionType
= EFI_SECTION_PEI_DEPEX
;
838 Error (NULL
, 0, 0, ParamSectionType
, "unknown section type");
839 PrintUsageMessage ();
840 return GetUtilityStatus ();
845 OutFile
= fopen (OutputFileName
, "wb");
846 if (OutFile
== NULL
) {
847 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
848 if (InFile
!= NULL
) {
852 return GetUtilityStatus ();
855 // At this point, we've fully validated the command line, and opened appropriate
856 // files, so let's go and do what we've been asked to do...
859 // Within this switch, build and write out the section header including any
860 // section type specific pieces. If there's an input file, it's tacked on later
862 switch (SectionType
) {
863 case EFI_SECTION_COMPRESSION
:
864 Status
= GenSectionCompressionSection (
873 case EFI_SECTION_GUID_DEFINED
:
874 Status
= GenSectionGuidDefinedSection (
883 case EFI_SECTION_VERSION
:
884 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
886 Index
= sizeof (CommonSect
);
888 // 2 characters for the build number
892 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
894 Index
+= (strlen (AuxString
) * 2) + 2;
895 memcpy (&CommonSect
.Size
, &Index
, 3);
896 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
897 fwrite (&VersionNumber
, 2, 1, OutFile
);
898 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
901 case EFI_SECTION_USER_INTERFACE
:
902 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
903 Index
= sizeof (CommonSect
);
905 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
907 Index
+= (strlen (AuxString
) * 2) + 2;
908 memcpy (&CommonSect
.Size
, &Index
, 3);
909 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
910 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
915 // All other section types are caught by default (they're all the same)
917 Status
= GenSectionCommonLeafSection (
926 if (InputFileName
!= NULL
) {
927 free (InputFileName
);
932 // If we had errors, then delete the output file
934 if (GetUtilityStatus () == STATUS_ERROR
) {
935 remove (OutputFileName
);
938 return GetUtilityStatus ();