3 Copyright (c) 2004, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
18 Creates output file that is a properly formed section per the FV spec.
\r
26 #include <Common/UefiBaseTypes.h>
\r
27 #include <Common/FirmwareVolumeImageFormat.h>
\r
28 #include <Protocol/GuidedSectionExtraction.h>
\r
30 #include "CommonLib.h"
\r
31 #include "Compress.h"
\r
33 #include "EfiUtilityMsgs.h"
\r
36 // GenSec Tool Information
\r
38 #define UTILITY_NAME "GenSec"
\r
39 #define UTILITY_MAJOR_VERSION 1
\r
40 #define UTILITY_MINOR_VERSION 0
\r
42 #define MAXIMUM_INPUT_FILE_NUM 10
\r
43 #define MAX_SECTION_SIZE 0x1000000
\r
45 CHAR8 *SectionTypeName[] = {
\r
46 NULL, // 0x00 - reserved
\r
47 "EFI_SECTION_COMPRESSION", // 0x01
\r
48 "EFI_SECTION_GUID_DEFINED", // 0x02
\r
49 NULL, // 0x03 - reserved
\r
50 NULL, // 0x04 - reserved
\r
51 NULL, // 0x05 - reserved
\r
52 NULL, // 0x06 - reserved
\r
53 NULL, // 0x07 - reserved
\r
54 NULL, // 0x08 - reserved
\r
55 NULL, // 0x09 - reserved
\r
56 NULL, // 0x0A - reserved
\r
57 NULL, // 0x0B - reserved
\r
58 NULL, // 0x0C - reserved
\r
59 NULL, // 0x0D - reserved
\r
60 NULL, // 0x0E - reserved
\r
61 NULL, // 0x0F - reserved
\r
62 "EFI_SECTION_PE32", // 0x10
\r
63 "EFI_SECTION_PIC", // 0x11
\r
64 "EFI_SECTION_TE", // 0x12
\r
65 "EFI_SECTION_DXE_DEPEX", // 0x13
\r
66 "EFI_SECTION_VERSION", // 0x14
\r
67 "EFI_SECTION_USER_INTERFACE", // 0x15
\r
68 "EFI_SECTION_COMPATIBILITY16", // 0x16
\r
69 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17
\r
70 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18
\r
71 "EFI_SECTION_RAW", // 0x19
\r
73 "EFI_SECTION_PEI_DEPEX" // 0x1B
\r
76 CHAR8 *CompressionTypeName[] = { "PI_NONE", "PI_STD" };
\r
77 CHAR8 *GUIDedSectionAttribue[] = { NULL, "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};
\r
80 // Crc32 GUID section related definitions.
\r
83 EFI_GUID_DEFINED_SECTION GuidSectionHeader;
\r
84 UINT32 CRC32Checksum;
\r
85 } CRC32_SECTION_HEADER;
\r
87 EFI_GUID gZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
\r
88 EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
\r
97 Routine Description:
\r
99 Print out version information for this utility.
\r
111 printf ("%s v%d.%d - EDKII Utility to create output file with formed section per the PI spec.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
\r
112 printf ("Copyright (c) 2007 Intel Corporation. All rights reserved.\n");
\r
123 printf ("\nUsage: " UTILITY_NAME " [inputfilename]\n\
\r
124 -o, --outputfile [FileName]\n\
\r
125 -s, --SectionType <EFI_SECTION_COMPRESSION|\n\
\r
126 EFI_SECTION_GUID_DEFINED|\n\
\r
127 EFI_SECTION_PE32|\n\
\r
128 EFI_SECTION_PIC|\n\
\r
130 EFI_SECTION_DXE_DEPEX|\n\
\r
131 EFI_SECTION_VERSION|\n\
\r
132 EFI_SECTION_USER_INTERFACE|\n\
\r
133 EFI_SECTION_COMPATIBILITY16|\n\
\r
134 EFI_SECTION_FIRMWARE_VOLUME_IMAGE|\n\
\r
135 EFI_SECTION_FREEFORM_SUBTYPE_GUID|\n\
\r
136 EFI_SECTION_RAW|\n\
\r
137 EFI_SECTION_PEI_DEPEX>\n\
\r
138 -c, --compress <PI_NONE|PI_STD>\n\
\r
139 -g, --vendorguid [GuidValue (########-####-####-####-############)]\n\
\r
140 -r, --attributes <PROCESSING_REQUIRED|AUTH_STATUS_VALID>\n\
\r
141 -n, --name \"string\"\n\
\r
142 -j, --buildnumber #### (0000~9999)\n\
\r
148 Ascii2UnicodeWriteString (
\r
159 // Next, write out the string... Convert ASCII to Unicode in the process.
\r
163 fwrite (&String[Index], 1, 1, OutFile);
\r
164 fwrite (&AsciiNull, 1, 1, OutFile);
\r
165 } while (String[Index++] != 0);
\r
169 GenSectionCommonLeafSection (
\r
170 CHAR8 **InputFileName,
\r
171 UINT32 InputFileNum,
\r
177 Routine Description:
\r
179 Generate a leaf section of type other than EFI_SECTION_VERSION
\r
180 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
\r
181 The function won't validate the input file's contents. For
\r
182 common leaf sections, the input file may be a binary file.
\r
183 The utility will add section header to the file.
\r
187 InputFileName - Name of the input file.
\r
189 InputFileNum - Number of input files. Should be 1 for leaf section.
\r
191 SectionType - A valid section type string
\r
193 OutFile - Output file handle
\r
197 STATUS_ERROR - can't continue
\r
198 STATUS_SUCCESS - successful return
\r
202 UINT32 InputFileLength;
\r
205 UINT32 TotalLength;
\r
206 EFI_COMMON_SECTION_HEADER CommonSect;
\r
209 if (InputFileNum > 1) {
\r
210 Error (NULL, 0, 0, "invalid parameter", "more than one input file specified");
\r
211 return STATUS_ERROR;
\r
212 } else if (InputFileNum < 1) {
\r
213 Error (NULL, 0, 0, "no input file specified", NULL);
\r
214 return STATUS_ERROR;
\r
217 // Open the input file
\r
219 InFile = fopen (InputFileName[0], "rb");
\r
220 if (InFile == NULL) {
\r
221 Error (NULL, 0, 0, InputFileName[0], "failed to open input file");
\r
222 return STATUS_ERROR;
\r
225 Status = STATUS_ERROR;
\r
228 // Seek to the end of the input file so we can determine its size
\r
230 fseek (InFile, 0, SEEK_END);
\r
231 InputFileLength = ftell (InFile);
\r
232 fseek (InFile, 0, SEEK_SET);
\r
234 // Fill in the fields in the local section header structure
\r
236 CommonSect.Type = (EFI_SECTION_TYPE) SectionType;
\r
237 TotalLength = sizeof (CommonSect) + InputFileLength;
\r
239 // Size must fit in 3 bytes
\r
241 if (TotalLength >= MAX_SECTION_SIZE) {
\r
242 Error (NULL, 0, 0, InputFileName[0], "file size (0x%X) exceeds section size limit(%dM).", TotalLength, MAX_SECTION_SIZE>>20);
\r
246 // Now copy the size into the section header and write out the section header
\r
248 memcpy (&CommonSect.Size, &TotalLength, 3);
\r
249 fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);
\r
251 // Allocate a buffer to read in the contents of the input file. Then
\r
252 // read it in as one block and write it to the output file.
\r
254 if (InputFileLength != 0) {
\r
255 Buffer = (UINT8 *) malloc ((size_t) InputFileLength);
\r
256 if (Buffer == NULL) {
\r
257 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
\r
261 if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) {
\r
262 Error (NULL, 0, 0, InputFileName[0], "failed to read contents of file");
\r
266 if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) {
\r
267 Error (NULL, 0, 0, "failed to write to output file", NULL);
\r
272 Status = STATUS_SUCCESS;
\r
276 if (Buffer != NULL) {
\r
284 GetSectionContents (
\r
285 CHAR8 **InputFileName,
\r
286 UINT32 InputFileNum,
\r
288 UINT32 *BufferLength
\r
292 Routine Description:
\r
294 Get the contents of all section files specified in InputFileName
\r
299 InputFileName - Name of the input file.
\r
301 InputFileNum - Number of input files. Should be at least 1.
\r
303 FileBuffer - Output buffer to contain data
\r
305 BufferLength - On input, this is size of the FileBuffer.
\r
306 On output, this is the actual length of the data.
\r
310 EFI_SUCCESS on successful return
\r
311 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
\r
312 EFI_ABORTED if unable to open input file.
\r
313 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
\r
321 if (InputFileNum < 1) {
\r
322 Error (NULL, 0, 0, "must specify at least one input file", NULL);
\r
323 return EFI_INVALID_PARAMETER;
\r
326 if (BufferLength == NULL) {
\r
327 Error (NULL, 0, 0, "BufferLength can't be NULL", NULL);
\r
328 return EFI_INVALID_PARAMETER;
\r
333 // Go through our array of file names and copy their contents
\r
334 // to the output buffer.
\r
336 for (Index = 0; Index < InputFileNum; Index++) {
\r
338 // make sure section ends on a DWORD boundary
\r
340 while ((Size & 0x03) != 0) {
\r
341 if (FileBuffer != NULL && Size < *BufferLength) {
\r
342 FileBuffer[Size] = 0;
\r
348 // Open file and read contents
\r
350 InFile = fopen (InputFileName[Index], "rb");
\r
351 if (InFile == NULL) {
\r
352 Error (NULL, 0, 0, InputFileName[Index], "failed to open input file");
\r
353 return EFI_ABORTED;
\r
356 fseek (InFile, 0, SEEK_END);
\r
357 FileSize = ftell (InFile);
\r
358 fseek (InFile, 0, SEEK_SET);
\r
360 // Now read the contents of the file into the buffer
\r
361 // Buffer must be enough to contain the file content.
\r
363 if (FileSize > 0 && FileBuffer != NULL && (Size + FileSize) <= *BufferLength) {
\r
364 if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {
\r
365 Error (NULL, 0, 0, InputFileName[Index], "failed to read contents of input file");
\r
367 return EFI_ABORTED;
\r
375 if (Size > *BufferLength) {
\r
376 *BufferLength = Size;
\r
377 return EFI_BUFFER_TOO_SMALL;
\r
379 *BufferLength = Size;
\r
380 return EFI_SUCCESS;
\r
385 GenSectionCompressionSection (
\r
386 CHAR8 **InputFileName,
\r
387 UINT32 InputFileNum,
\r
388 UINT8 SectCompSubType,
\r
393 Routine Description:
\r
395 Generate an encapsulating section of type EFI_SECTION_COMPRESSION
\r
396 Input file must be already sectioned. The function won't validate
\r
397 the input files' contents. Caller should hand in files already
\r
398 with section header.
\r
402 InputFileName - Name of the input file.
\r
404 InputFileNum - Number of input files. Should be at least 1.
\r
406 SectCompSubType - Specify the compression algorithm requested.
\r
408 OutFile - Output file handle
\r
412 EFI_SUCCESS on successful return
\r
413 EFI_INVALID_PARAMETER if InputFileNum is less than 1
\r
414 EFI_ABORTED if unable to open input file.
\r
415 EFI_OUT_OF_RESOURCES No resource to complete the operation.
\r
418 UINT32 TotalLength;
\r
419 UINT32 InputLength;
\r
420 UINT32 CompressedLength;
\r
422 UINT8 *OutputBuffer;
\r
424 EFI_COMPRESSION_SECTION CompressionSect;
\r
425 COMPRESS_FUNCTION CompressFunction;
\r
429 OutputBuffer = NULL;
\r
430 CompressedLength = 0;
\r
432 // read all input file contents into a buffer
\r
433 // first get the size of all file contents
\r
435 Status = GetSectionContents (
\r
442 if (Status == EFI_BUFFER_TOO_SMALL) {
\r
443 FileBuffer = (UINT8 *) malloc (InputLength);
\r
444 if (FileBuffer == NULL) {
\r
445 Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");
\r
446 return EFI_OUT_OF_RESOURCES;
\r
449 // read all input file contents into a buffer
\r
451 Status = GetSectionContents (
\r
459 if (EFI_ERROR (Status)) {
\r
460 if (FileBuffer != NULL) {
\r
466 CompressFunction = NULL;
\r
469 // Now data is in FileBuffer, compress the data
\r
471 switch (SectCompSubType) {
\r
472 case EFI_NOT_COMPRESSED:
\r
473 CompressedLength = InputLength;
\r
476 case EFI_STANDARD_COMPRESSION:
\r
477 CompressFunction = (COMPRESS_FUNCTION) EfiCompress;
\r
481 Error (NULL, 0, 0, "unknown compression type", NULL);
\r
483 return EFI_ABORTED;
\r
486 if (CompressFunction != NULL) {
\r
488 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);
\r
489 if (Status == EFI_BUFFER_TOO_SMALL) {
\r
490 OutputBuffer = malloc (CompressedLength);
\r
491 if (!OutputBuffer) {
\r
493 return EFI_OUT_OF_RESOURCES;
\r
496 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);
\r
500 FileBuffer = OutputBuffer;
\r
502 if (EFI_ERROR (Status)) {
\r
503 if (FileBuffer != NULL) {
\r
511 TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);
\r
512 if (TotalLength >= MAX_SECTION_SIZE) {
\r
513 Error (__FILE__, __LINE__, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE>>20);
\r
514 if (FileBuffer != NULL) {
\r
517 if (OutputBuffer != NULL) {
\r
518 free (OutputBuffer);
\r
520 return STATUS_ERROR;
\r
524 // Add the section header for the compressed data
\r
526 CompressionSect.CommonHeader.Type = EFI_SECTION_COMPRESSION;
\r
527 CompressionSect.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
\r
528 CompressionSect.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
\r
529 CompressionSect.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
\r
530 CompressionSect.CompressionType = SectCompSubType;
\r
531 CompressionSect.UncompressedLength = InputLength;
\r
533 fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile);
\r
534 fwrite (FileBuffer, CompressedLength, 1, OutFile);
\r
536 return EFI_SUCCESS;
\r
540 GenSectionGuidDefinedSection (
\r
541 CHAR8 **InputFileName,
\r
542 UINT32 InputFileNum,
\r
543 EFI_GUID *VendorGuid,
\r
544 UINT16 DataAttribute,
\r
549 Routine Description:
\r
551 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
\r
552 Input file must be already sectioned. The function won't validate
\r
553 the input files' contents. Caller should hand in files already
\r
554 with section header.
\r
558 InputFileName - Name of the input file.
\r
560 InputFileNum - Number of input files. Should be at least 1.
\r
562 VendorGuid - Specify vendor guid value.
\r
564 DataAttribute - Specify attribute for the vendor guid data.
\r
566 OutFile - Output file handle
\r
570 EFI_SUCCESS on successful return
\r
571 EFI_INVALID_PARAMETER if InputFileNum is less than 1
\r
572 EFI_ABORTED if unable to open input file.
\r
573 EFI_OUT_OF_RESOURCES No resource to complete the operation.
\r
577 UINT32 TotalLength;
\r
578 UINT32 InputLength;
\r
580 UINT32 Crc32Checksum;
\r
582 CRC32_SECTION_HEADER Crc32GuidSect;
\r
583 EFI_GUID_DEFINED_SECTION VendorGuidSect;
\r
588 // read all input file contents into a buffer
\r
589 // first get the size of all file contents
\r
591 Status = GetSectionContents (
\r
598 if (Status == EFI_BUFFER_TOO_SMALL) {
\r
599 FileBuffer = (UINT8 *) malloc (InputLength);
\r
600 if (FileBuffer == NULL) {
\r
601 Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");
\r
602 return EFI_OUT_OF_RESOURCES;
\r
605 // read all input file contents into a buffer
\r
607 Status = GetSectionContents (
\r
615 if (EFI_ERROR (Status)) {
\r
616 if (FileBuffer != NULL) {
\r
623 // Now data is in FileBuffer
\r
625 if (CompareGuid (VendorGuid, &gEfiCrc32SectionGuid) == 0) {
\r
627 // Default Guid section is CRC32.
\r
630 CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum);
\r
632 TotalLength = InputLength + sizeof (CRC32_SECTION_HEADER);
\r
633 if (TotalLength >= MAX_SECTION_SIZE) {
\r
634 Error (__FILE__, __LINE__, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE>>20);
\r
636 return STATUS_ERROR;
\r
639 Crc32GuidSect.GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
\r
640 Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
\r
641 Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
\r
642 Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
\r
643 memcpy (&(Crc32GuidSect.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));
\r
644 Crc32GuidSect.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
\r
645 Crc32GuidSect.GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);
\r
646 Crc32GuidSect.CRC32Checksum = Crc32Checksum;
\r
647 fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile);
\r
650 TotalLength = InputLength + sizeof (EFI_GUID_DEFINED_SECTION);
\r
651 if (TotalLength >= MAX_SECTION_SIZE) {
\r
652 Error (__FILE__, __LINE__, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE>>20);
\r
654 return STATUS_ERROR;
\r
657 VendorGuidSect.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
\r
658 VendorGuidSect.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
\r
659 VendorGuidSect.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
\r
660 VendorGuidSect.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
\r
661 memcpy (&(VendorGuidSect.SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));
\r
662 VendorGuidSect.Attributes = DataAttribute;
\r
663 VendorGuidSect.DataOffset = sizeof (EFI_GUID_DEFINED_SECTION);
\r
664 fwrite (&VendorGuidSect, sizeof (EFI_GUID_DEFINED_SECTION), 1, OutFile);
\r
667 fwrite (FileBuffer, InputLength, 1, OutFile);
\r
670 return EFI_SUCCESS;
\r
680 Routine Description:
\r
686 command line parameters
\r
690 EFI_SUCCESS Section header successfully generated and section concatenated.
\r
691 EFI_ABORTED Could not generate the section
\r
692 EFI_OUT_OF_RESOURCES No resource to complete the operation.
\r
697 UINT32 InputFileNum;
\r
700 CHAR8 **InputFileName;
\r
701 CHAR8 *OutputFileName;
\r
702 CHAR8 *SectionName;
\r
703 CHAR8 *CompressionName;
\r
704 CHAR8 *StringBuffer;
\r
705 EFI_GUID VendorGuid = gZeroGuid;
\r
706 INT32 VersionNumber;
\r
708 UINT8 SectCompSubType;
\r
709 UINT16 SectGuidAttribute;
\r
710 EFI_COMMON_SECTION_HEADER CommonSect;
\r
711 UINT32 InputLength;
\r
713 BOOLEAN AllocatedFlag;
\r
716 fprintf (stdout, "GenSec tool start.\n");
\r
718 InputFileName = NULL;
\r
719 OutputFileName = NULL;
\r
720 SectionName = NULL;
\r
721 CompressionName = NULL;
\r
728 SectType = EFI_SECTION_ALL;
\r
729 SectCompSubType = 0;
\r
730 SectGuidAttribute = 0;
\r
733 AllocatedFlag = FALSE;
\r
734 Status = STATUS_SUCCESS;
\r
737 SetUtilityName (UTILITY_NAME);
\r
741 return STATUS_ERROR;
\r
745 // Parse command line
\r
750 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
\r
752 return STATUS_ERROR;
\r
755 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--version") == 0)) {
\r
757 return STATUS_ERROR;
\r
761 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--SectionType") == 0)) {
\r
762 SectionName = argv[1];
\r
768 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
\r
769 OutputFileName = argv[1];
\r
775 if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--compress") == 0)) {
\r
776 CompressionName = argv[1];
\r
782 if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--vendorguid") == 0)) {
\r
783 Status = StringToGuid (argv[1], &VendorGuid);
\r
784 if (EFI_ERROR (Status)) {
\r
785 Error (NULL, 0, 0, NULL, "ERROR: %s is not a formal GUID value.", argv[1]);
\r
793 if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {
\r
794 if (stricmp (argv[1], GUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {
\r
795 SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
\r
796 } else if (stricmp (argv[1], GUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {
\r
797 SectGuidAttribute |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
\r
799 Error (NULL, 0, 0, argv[1], "unknown Guid Section Attribute");
\r
807 if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--name") == 0)) {
\r
808 StringBuffer = argv[1];
\r
814 if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--buildnumber") == 0)) {
\r
816 // Verify string is a integrator number
\r
818 for (Index = 0; Index < strlen (argv[1]); Index++) {
\r
819 if ((argv[1][Index] != '-') && (isdigit (argv[1][Index]) == 0)) {
\r
820 Error (NULL, 0, 0, NULL, "ERROR: %s is not a valid integer.", argv[1]);
\r
825 sscanf (argv[1], "%d", &VersionNumber);
\r
832 // Get Input file name
\r
834 if ((InputFileNum == 0) && (InputFileName == NULL)) {
\r
835 InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));
\r
836 if (InputFileName == NULL) {
\r
837 Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");
\r
838 return EFI_OUT_OF_RESOURCES;
\r
841 memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
\r
842 } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {
\r
844 // InputFileName buffer too small, need to realloc
\r
846 InputFileName = (CHAR8 **) realloc (
\r
848 (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
\r
851 if (InputFileName == NULL) {
\r
852 Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");
\r
853 return EFI_OUT_OF_RESOURCES;
\r
856 memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
\r
859 InputFileName[InputFileNum++] = argv[0];
\r
865 // Parse all command line parameters to get the corresponding section type.
\r
867 if (SectionName == NULL) {
\r
869 // No specified Section type, default is SECTION_ALL.
\r
871 SectType = EFI_SECTION_ALL;
\r
872 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {
\r
873 SectType = EFI_SECTION_COMPRESSION;
\r
874 if (CompressionName == NULL) {
\r
876 // Default is PI_STD compression algorithm.
\r
878 SectCompSubType = EFI_STANDARD_COMPRESSION;
\r
879 } else if (stricmp (CompressionName, CompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {
\r
880 SectCompSubType = EFI_NOT_COMPRESSED;
\r
881 } else if (stricmp (CompressionName, CompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {
\r
882 SectCompSubType = EFI_STANDARD_COMPRESSION;
\r
884 Error (NULL, 0, 0, CompressionName, "unknown compression type");
\r
887 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {
\r
888 SectType = EFI_SECTION_GUID_DEFINED;
\r
890 if (CompareGuid (&VendorGuid, &gZeroGuid) == 0) {
\r
891 memcpy (&VendorGuid, &gEfiCrc32SectionGuid, sizeof (EFI_GUID));
\r
894 if (SectGuidAttribute == 0) {
\r
895 SectGuidAttribute = EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
\r
897 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PE32]) == 0) {
\r
898 SectType = EFI_SECTION_PE32;
\r
899 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PIC]) == 0) {
\r
900 SectType = EFI_SECTION_PIC;
\r
901 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_TE]) == 0) {
\r
902 SectType = EFI_SECTION_TE;
\r
903 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {
\r
904 SectType = EFI_SECTION_DXE_DEPEX;
\r
905 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_VERSION]) == 0) {
\r
906 SectType = EFI_SECTION_VERSION;
\r
907 if (VersionNumber < 0 || VersionNumber > 9999) {
\r
908 Error (NULL, 0, 0, NULL, "%d is illegal version number\n", VersionNumber);
\r
911 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {
\r
912 SectType = EFI_SECTION_USER_INTERFACE;
\r
913 if (StringBuffer[0] == '\0') {
\r
914 Error (NULL, 0, 0, "user interface string not specified", NULL);
\r
917 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {
\r
918 SectType = EFI_SECTION_COMPATIBILITY16;
\r
919 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {
\r
920 SectType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
\r
921 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {
\r
922 SectType = EFI_SECTION_FREEFORM_SUBTYPE_GUID;
\r
923 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_RAW]) == 0) {
\r
924 SectType = EFI_SECTION_RAW;
\r
925 } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {
\r
926 SectType = EFI_SECTION_PEI_DEPEX;
\r
928 Error (NULL, 0, 0, SectionName, "unknown section type");
\r
932 if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {
\r
934 // The input file are required for those section type.
\r
935 // The file are from stdin.
\r
937 if (InputFileNum == 0) {
\r
938 Error (NULL, 0, 0, NULL, "No input files is specified.");
\r
944 // Open output file
\r
946 if (OutputFileName == NULL) {
\r
947 Error (NULL, 0, 0, NULL, "No output file name is specified.");
\r
949 // OutFile = stdout;
\r
951 OutFile = fopen (OutputFileName, "wb");
\r
954 if (OutFile == NULL) {
\r
955 Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");
\r
960 // At this point, we've fully validated the command line, and opened appropriate
\r
961 // files, so let's go and do what we've been asked to do...
\r
964 // Within this switch, build and write out the section header including any
\r
965 // section type specific pieces. If there's an input file, it's tacked on later
\r
967 switch (SectType) {
\r
968 case EFI_SECTION_COMPRESSION:
\r
969 Status = GenSectionCompressionSection (
\r
977 case EFI_SECTION_GUID_DEFINED:
\r
978 Status = GenSectionGuidDefinedSection (
\r
987 case EFI_SECTION_VERSION:
\r
988 CommonSect.Type = (EFI_SECTION_TYPE) SectType;
\r
990 Index = sizeof (CommonSect);
\r
992 // 2 bytes for the build number UINT16
\r
996 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
\r
998 Index += (strlen (StringBuffer) * 2) + 2;
\r
999 memcpy (&CommonSect.Size, &Index, 3);
\r
1000 fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);
\r
1001 fwrite (&VersionNumber, sizeof (UINT16), 1, OutFile);
\r
1002 Ascii2UnicodeWriteString (StringBuffer, OutFile);
\r
1005 case EFI_SECTION_USER_INTERFACE:
\r
1006 CommonSect.Type = (EFI_SECTION_TYPE) SectType;
\r
1007 Index = sizeof (CommonSect);
\r
1009 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
\r
1011 Index += (strlen (StringBuffer) * 2) + 2;
\r
1012 memcpy (&CommonSect.Size, &Index, 3);
\r
1013 fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);
\r
1014 Ascii2UnicodeWriteString (StringBuffer, OutFile);
\r
1017 case EFI_SECTION_ALL:
\r
1019 // read all input file contents into a buffer
\r
1020 // first get the size of all file contents
\r
1022 Status = GetSectionContents (
\r
1029 if (Status == EFI_BUFFER_TOO_SMALL) {
\r
1030 FileBuffer = (UINT8 *) malloc (InputLength);
\r
1031 if (FileBuffer == NULL) {
\r
1032 Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");
\r
1036 // read all input file contents into a buffer
\r
1038 Status = GetSectionContents (
\r
1046 if (Status == EFI_SUCCESS) {
\r
1047 fwrite (FileBuffer, InputLength, 1, OutFile);
\r
1050 if (FileBuffer != NULL) {
\r
1051 free (FileBuffer);
\r
1057 // All other section types are caught by default (they're all the same)
\r
1059 Status = GenSectionCommonLeafSection (
\r
1069 if (AllocatedFlag == TRUE) {
\r
1070 for (Index = 0; Index < InputFileNum; Index ++) {
\r
1071 free (InputFileName[Index]);
\r
1075 if (InputFileName != NULL) {
\r
1076 free (InputFileName);
\r
1079 if (OutFile != NULL) {
\r
1083 fprintf (stdout, "GenSec tool done with return code is 0x%x.\n", GetUtilityStatus ());
\r
1085 return GetUtilityStatus ();
\r