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"
31 #include "EfiCompress.h"
32 #include "EfiCustomizedCompress.h"
34 #include "EfiUtilityMsgs.h"
35 #include "GenSection.h"
38 #define UTILITY_NAME "GenSection"
40 #define PARAMETER_NOT_SPECIFIED "Parameter not specified"
41 #define MAXIMUM_INPUT_FILE_NUM 10
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
>= 0x1000000) {
223 Error (NULL
, 0, 0, InputFileName
[0], "file size (0x%X) exceeds section size limit", TotalLength
);
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 - Actual length of the data
289 EFI_SUCCESS on successful return
290 EFI_INVALID_PARAMETER if InputFileNum is less than 1
291 EFI_ABORTED if unable to open input file.
300 if (InputFileNum
< 1) {
301 Error (NULL
, 0, 0, "must specify at least one input file", NULL
);
302 return EFI_INVALID_PARAMETER
;
307 // Go through our array of file names and copy their contents
308 // to the output buffer.
310 for (Index
= 0; Index
< InputFileNum
; Index
++) {
311 InFile
= fopen (InputFileName
[Index
], "rb");
312 if (InFile
== NULL
) {
313 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to open input file");
317 fseek (InFile
, 0, SEEK_END
);
318 FileSize
= ftell (InFile
);
319 fseek (InFile
, 0, SEEK_SET
);
321 // Now read the contents of the file into the buffer
324 if (fread (FileBuffer
+ Size
, (size_t) FileSize
, 1, InFile
) != 1) {
325 Error (NULL
, 0, 0, InputFileName
[Index
], "failed to read contents of input file");
332 Size
+= (UINTN
) FileSize
;
334 // make sure section ends on a DWORD boundary
336 while ((Size
& 0x03) != 0) {
337 FileBuffer
[Size
] = 0;
342 *BufferLength
= Size
;
347 GenSectionCompressionSection (
348 char **InputFileName
,
351 UINTN SectionSubType
,
358 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
359 Input file must be already sectioned. The function won't validate
360 the input files' contents. Caller should hand in files already
365 InputFileName - Name of the input file.
367 InputFileNum - Number of input files. Should be at least 1.
369 SectionType - Section type to generate. Should be
370 EFI_SECTION_COMPRESSION
372 SectionSubType - Specify the compression algorithm requested.
374 OutFile - Output file handle
378 EFI_SUCCESS on successful return
379 EFI_INVALID_PARAMETER if InputFileNum is less than 1
380 EFI_ABORTED if unable to open input file.
381 EFI_OUT_OF_RESOURCES No resource to complete the operation.
386 UINTN CompressedLength
;
390 EFI_COMPRESSION_SECTION CompressionSect
;
391 COMPRESS_FUNCTION CompressFunction
;
393 if (SectionType
!= EFI_SECTION_COMPRESSION
) {
394 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL
);
395 return EFI_INVALID_PARAMETER
;
401 CompressedLength
= 0;
402 FileBuffer
= (UINT8
*) malloc ((1024 * 1024 * 4) * sizeof (UINT8
));
403 if (FileBuffer
== NULL
) {
404 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
405 return EFI_OUT_OF_RESOURCES
;
408 // read all input file contents into a buffer
410 Status
= GetSectionContents (
416 if (EFI_ERROR (Status
)) {
421 CompressFunction
= NULL
;
424 // Now data is in FileBuffer, compress the data
426 switch (SectionSubType
) {
427 case EFI_NOT_COMPRESSED
:
428 CompressedLength
= InputLength
;
431 case EFI_STANDARD_COMPRESSION
:
432 CompressFunction
= (COMPRESS_FUNCTION
) Compress
;
435 case EFI_CUSTOMIZED_COMPRESSION
:
436 CompressFunction
= (COMPRESS_FUNCTION
) CustomizedCompress
;
440 Error (NULL
, 0, 0, "unknown compression type", NULL
);
445 if (CompressFunction
!= NULL
) {
447 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
448 if (Status
== EFI_BUFFER_TOO_SMALL
) {
449 OutputBuffer
= malloc (CompressedLength
);
452 return EFI_OUT_OF_RESOURCES
;
455 Status
= CompressFunction (FileBuffer
, InputLength
, OutputBuffer
, &CompressedLength
);
459 FileBuffer
= OutputBuffer
;
461 if (EFI_ERROR (Status
)) {
462 if (FileBuffer
!= NULL
) {
470 TotalLength
= CompressedLength
+ sizeof (EFI_COMPRESSION_SECTION
);
472 // Add the section header for the compressed data
474 CompressionSect
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
475 CompressionSect
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
476 CompressionSect
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
477 CompressionSect
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
478 CompressionSect
.CompressionType
= (UINT8
) SectionSubType
;
479 CompressionSect
.UncompressedLength
= InputLength
;
481 fwrite (&CompressionSect
, sizeof (CompressionSect
), 1, OutFile
);
482 fwrite (FileBuffer
, CompressedLength
, 1, OutFile
);
488 GenSectionGuidDefinedSection (
489 char **InputFileName
,
492 UINTN SectionSubType
,
499 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
500 Input file must be already sectioned. The function won't validate
501 the input files' contents. Caller should hand in files already
506 InputFileName - Name of the input file.
508 InputFileNum - Number of input files. Should be at least 1.
510 SectionType - Section type to generate. Should be
511 EFI_SECTION_GUID_DEFINED
513 SectionSubType - Specify the authentication algorithm requested.
515 OutFile - Output file handle
519 EFI_SUCCESS on successful return
520 EFI_INVALID_PARAMETER if InputFileNum is less than 1
521 EFI_ABORTED if unable to open input file.
522 EFI_OUT_OF_RESOURCES No resource to complete the operation.
529 UINT32 Crc32Checksum
;
531 CRC32_SECTION_HEADER Crc32GuidSect
;
533 if (SectionType
!= EFI_SECTION_GUID_DEFINED
) {
534 Error (NULL
, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL
);
535 return EFI_INVALID_PARAMETER
;
540 FileBuffer
= (UINT8
*) malloc ((1024 * 1024 * 4) * sizeof (UINT8
));
541 if (FileBuffer
== NULL
) {
542 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
543 return EFI_OUT_OF_RESOURCES
;
546 // read all input file contents into a buffer
548 Status
= GetSectionContents (
554 if (EFI_ERROR (Status
)) {
559 // Now data is in FileBuffer, compress the data
561 switch (SectionSubType
) {
562 case EFI_SECTION_CRC32_GUID_DEFINED
:
564 CalculateCrc32 (FileBuffer
, InputLength
, &Crc32Checksum
);
565 if (EFI_ERROR (Status
)) {
570 TotalLength
= InputLength
+ CRC32_SECTION_HEADER_SIZE
;
571 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Type
= (EFI_SECTION_TYPE
) SectionType
;
572 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[0] = (UINT8
) (TotalLength
& 0xff);
573 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[1] = (UINT8
) ((TotalLength
& 0xff00) >> 8);
574 Crc32GuidSect
.GuidSectionHeader
.CommonHeader
.Size
[2] = (UINT8
) ((TotalLength
& 0xff0000) >> 16);
575 memcpy (&(Crc32GuidSect
.GuidSectionHeader
.SectionDefinitionGuid
), &gEfiCrc32SectionGuid
, sizeof (EFI_GUID
));
576 Crc32GuidSect
.GuidSectionHeader
.Attributes
= EFI_GUIDED_SECTION_AUTH_STATUS_VALID
;
577 Crc32GuidSect
.GuidSectionHeader
.DataOffset
= CRC32_SECTION_HEADER_SIZE
;
578 Crc32GuidSect
.CRC32Checksum
= Crc32Checksum
;
583 Error (NULL
, 0, 0, "invalid parameter", "unknown GUID defined type");
588 fwrite (&Crc32GuidSect
, sizeof (Crc32GuidSect
), 1, OutFile
);
589 fwrite (FileBuffer
, InputLength
, 1, OutFile
);
609 command line parameters
613 EFI_SUCCESS Section header successfully generated and section concatenated.
614 EFI_ABORTED Could not generate the section
615 EFI_OUT_OF_RESOURCES No resource to complete the operation.
622 UINTN SectionSubType
;
623 BOOLEAN InputFileRequired
;
624 BOOLEAN SubTypeRequired
;
629 char **InputFileName
;
630 char *OutputFileName
;
631 char AuxString
[500] = { 0 };
633 char *ParamSectionType
;
634 char *ParamSectionSubType
;
637 char *ParamDigitalSignature
;
640 EFI_COMMON_SECTION_HEADER CommonSect
;
642 InputFileName
= NULL
;
643 OutputFileName
= PARAMETER_NOT_SPECIFIED
;
644 ParamSectionType
= PARAMETER_NOT_SPECIFIED
;
645 ParamSectionSubType
= PARAMETER_NOT_SPECIFIED
;
646 ParamLength
= PARAMETER_NOT_SPECIFIED
;
647 ParamVersion
= PARAMETER_NOT_SPECIFIED
;
648 ParamDigitalSignature
= PARAMETER_NOT_SPECIFIED
;
649 Status
= EFI_SUCCESS
;
654 InputFileRequired
= TRUE
;
655 SubTypeRequired
= FALSE
;
659 Status
= EFI_SUCCESS
;
661 SetUtilityName (UTILITY_NAME
);
663 PrintUsageMessage ();
667 // Parse command line
670 while (Index
< argc
) {
671 if (strcmpi (argv
[Index
], "-i") == 0) {
676 InputFileName
= (char **) malloc (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *));
677 if (InputFileName
== NULL
) {
678 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
679 return EFI_OUT_OF_RESOURCES
;
682 memset (InputFileName
, 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
683 InputFileName
[InputFileNum
] = argv
[Index
];
687 // Parse subsequent parameters until another switch is encountered
689 while ((Index
< argc
) && (argv
[Index
][0] != '-')) {
690 if ((InputFileNum
% MAXIMUM_INPUT_FILE_NUM
) == 0) {
692 // InputFileName buffer too small, need to realloc
694 InputFileName
= (char **) realloc (
696 (InputFileNum
+ MAXIMUM_INPUT_FILE_NUM
) * sizeof (char *)
698 if (InputFileName
== NULL
) {
699 Error (__FILE__
, __LINE__
, 0, "application error", "failed to allocate memory");
700 return EFI_OUT_OF_RESOURCES
;
703 memset (&(InputFileName
[InputFileNum
]), 0, (MAXIMUM_INPUT_FILE_NUM
* sizeof (char *)));
706 InputFileName
[InputFileNum
] = argv
[Index
];
713 if (strcmpi (argv
[Index
], "-o") == 0) {
718 OutputFileName
= argv
[Index
];
719 } else if (strcmpi (argv
[Index
], "-s") == 0) {
721 // Section Type found
724 ParamSectionType
= argv
[Index
];
725 } else if (strcmpi (argv
[Index
], "-t") == 0) {
727 // Compression or Authentication type
730 ParamSectionSubType
= argv
[Index
];
731 } else if (strcmpi (argv
[Index
], "-l") == 0) {
736 ParamLength
= argv
[Index
];
737 } else if (strcmpi (argv
[Index
], "-v") == 0) {
742 ParamVersion
= argv
[Index
];
743 } else if (strcmpi (argv
[Index
], "-a") == 0) {
749 // Note, the MSVC C-Start parses out and consolidates quoted strings from the command
750 // line. Quote characters are stripped. If this tool is ported to other environments
751 // this will need to be taken into account
753 strncpy (AuxString
, argv
[Index
], 499);
754 } else if (strcmpi (argv
[Index
], "-d") == 0) {
756 // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)
759 ParamDigitalSignature
= argv
[Index
];
760 } else if (strcmpi (argv
[Index
], "-?") == 0) {
761 PrintUsageMessage ();
764 Error (NULL
, 0, 0, argv
[Index
], "unknown option");
765 return GetUtilityStatus ();
771 // At this point, all command line parameters are verified as not being totally
772 // bogus. Next verify the command line parameters are complete and make
775 if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPRESSION
]) == 0) {
776 SectionType
= EFI_SECTION_COMPRESSION
;
777 SubTypeRequired
= TRUE
;
778 if (stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_NOT_COMPRESSED
]) == 0) {
779 SectionSubType
= EFI_NOT_COMPRESSED
;
780 } else if (stricmp (ParamSectionSubType
, CompressionTypeName
[EFI_STANDARD_COMPRESSION
]) == 0) {
781 SectionSubType
= EFI_STANDARD_COMPRESSION
;
783 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown compression type");
784 PrintUsageMessage ();
785 return GetUtilityStatus ();
787 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_GUID_DEFINED
]) == 0) {
788 SectionType
= EFI_SECTION_GUID_DEFINED
;
789 SubTypeRequired
= TRUE
;
790 if (stricmp (ParamSectionSubType
, GUIDedSectionTypeName
[EFI_SECTION_CRC32_GUID_DEFINED
]) == 0) {
791 SectionSubType
= EFI_SECTION_CRC32_GUID_DEFINED
;
793 Error (NULL
, 0, 0, ParamSectionSubType
, "unknown GUID defined section type", ParamSectionSubType
);
794 PrintUsageMessage ();
795 return GetUtilityStatus ();
797 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PE32
]) == 0) {
798 SectionType
= EFI_SECTION_PE32
;
799 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PIC
]) == 0) {
800 SectionType
= EFI_SECTION_PIC
;
801 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_TE
]) == 0) {
802 SectionType
= EFI_SECTION_TE
;
803 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_DXE_DEPEX
]) == 0) {
804 SectionType
= EFI_SECTION_DXE_DEPEX
;
805 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_VERSION
]) == 0) {
806 SectionType
= EFI_SECTION_VERSION
;
807 InputFileRequired
= FALSE
;
808 Index
= sscanf (ParamVersion
, "%d", &VersionNumber
);
809 if (Index
!= 1 || VersionNumber
< 0 || VersionNumber
> 65565) {
810 Error (NULL
, 0, 0, ParamVersion
, "illegal version number");
811 PrintUsageMessage ();
812 return GetUtilityStatus ();
815 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
818 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_USER_INTERFACE
]) == 0) {
819 SectionType
= EFI_SECTION_USER_INTERFACE
;
820 InputFileRequired
= FALSE
;
821 if (strcmp (AuxString
, PARAMETER_NOT_SPECIFIED
) == 0) {
822 Error (NULL
, 0, 0, "user interface string not specified", NULL
);
823 PrintUsageMessage ();
824 return GetUtilityStatus ();
826 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_COMPATIBILITY16
]) == 0) {
827 SectionType
= EFI_SECTION_COMPATIBILITY16
;
828 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FIRMWARE_VOLUME_IMAGE
]) == 0) {
829 SectionType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
830 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_FREEFORM_SUBTYPE_GUID
]) == 0) {
831 SectionType
= EFI_SECTION_FREEFORM_SUBTYPE_GUID
;
832 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_RAW
]) == 0) {
833 SectionType
= EFI_SECTION_RAW
;
834 } else if (stricmp (ParamSectionType
, SectionTypeName
[EFI_SECTION_PEI_DEPEX
]) == 0) {
835 SectionType
= EFI_SECTION_PEI_DEPEX
;
837 Error (NULL
, 0, 0, ParamSectionType
, "unknown section type");
838 PrintUsageMessage ();
839 return GetUtilityStatus ();
844 OutFile
= fopen (OutputFileName
, "wb");
845 if (OutFile
== NULL
) {
846 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
847 if (InFile
!= NULL
) {
851 return GetUtilityStatus ();
854 // At this point, we've fully validated the command line, and opened appropriate
855 // files, so let's go and do what we've been asked to do...
858 // Within this switch, build and write out the section header including any
859 // section type specific pieces. If there's an input file, it's tacked on later
861 switch (SectionType
) {
862 case EFI_SECTION_COMPRESSION
:
863 Status
= GenSectionCompressionSection (
872 case EFI_SECTION_GUID_DEFINED
:
873 Status
= GenSectionGuidDefinedSection (
882 case EFI_SECTION_VERSION
:
883 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
885 Index
= sizeof (CommonSect
);
887 // 2 characters for the build number
891 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
893 Index
+= (strlen (AuxString
) * 2) + 2;
894 memcpy (&CommonSect
.Size
, &Index
, 3);
895 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
896 fwrite (&VersionNumber
, 2, 1, OutFile
);
897 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
900 case EFI_SECTION_USER_INTERFACE
:
901 CommonSect
.Type
= (EFI_SECTION_TYPE
) SectionType
;
902 Index
= sizeof (CommonSect
);
904 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
906 Index
+= (strlen (AuxString
) * 2) + 2;
907 memcpy (&CommonSect
.Size
, &Index
, 3);
908 fwrite (&CommonSect
, sizeof (CommonSect
), 1, OutFile
);
909 Ascii2UnicodeWriteString (AuxString
, OutFile
, FALSE
);
914 // All other section types are caught by default (they're all the same)
916 Status
= GenSectionCommonLeafSection (
925 if (InputFileName
!= NULL
) {
926 free (InputFileName
);
931 // If we had errors, then delete the output file
933 if (GetUtilityStatus () == STATUS_ERROR
) {
934 remove (OutputFileName
);
937 return GetUtilityStatus ();