]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/GenSection/GenSection.c
Initial import.
[mirror_edk2.git] / Tools / Source / TianoTools / GenSection / GenSection.c
1 /*++
2
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
8
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.
11
12 Module Name:
13
14 GenSection.c
15
16 Abstract:
17
18 Creates output file that is a properly formed section per the FV spec.
19
20 --*/
21
22 #include <Base.h>
23 #include <UefiBaseTypes.h>
24 #include "FirmwareVolumeImageFormat.h"
25 #include "CommonLib.h"
26 #include "EfiCompress.h"
27 #include "EfiCustomizedCompress.h"
28 #include "Crc32.h"
29 #include "EfiUtilityMsgs.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "GenSection.h"
36
37 #include <GuidedSectionExtraction.h>
38
39 #define UTILITY_NAME "GenSection"
40
41 #define PARAMETER_NOT_SPECIFIED "Parameter not specified"
42 #define MAXIMUM_INPUT_FILE_NUM 10
43
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
71 NULL, // 0x1A
72 "EFI_SECTION_PEI_DEPEX" // 0x1B
73 };
74
75 char *CompressionTypeName[] = { "NONE", "STANDARD" };
76 char *GUIDedSectionTypeName[] = { "CRC32" };
77 EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
78
79 static
80 VOID
81 PrintUsageMessage (
82 VOID
83 )
84 {
85 UINTN SectionType;
86 UINTN DisplayCount;
87
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");
90
91 DisplayCount = 0;
92 for (SectionType = 0; SectionType <= EFI_SECTION_LAST_SECTION_TYPE; SectionType++) {
93 if (SectionTypeName[SectionType] != NULL) {
94 printf (" %s\n", SectionTypeName[SectionType]);
95 }
96 }
97
98 printf ("\n and SectionType dependent parameters are as follows:\n\n");
99 printf (
100 " %s: -t < %s | %s >\n",
101 SectionTypeName[EFI_SECTION_COMPRESSION],
102 CompressionTypeName[EFI_NOT_COMPRESSED],
103 CompressionTypeName[EFI_STANDARD_COMPRESSION]
104 );
105 printf (
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]
109 );
110 printf (
111 " %s: -v VersionNumber\n"" [-a \"Version string\"]\n\n",
112 SectionTypeName[EFI_SECTION_VERSION]
113 );
114 printf (
115 " %s: -a \"Human readable name\"\n\n",
116 SectionTypeName[EFI_SECTION_USER_INTERFACE]
117 );
118 }
119
120 VOID
121 Ascii2UnicodeWriteString (
122 char *String,
123 FILE *OutFile,
124 BOOLEAN WriteLangCode
125 )
126 {
127 UINTN Index;
128 UINT8 AsciiNull;
129 //
130 // BUGBUG need to get correct language code...
131 //
132 char *EnglishLangCode = "eng";
133 AsciiNull = 0;
134 //
135 // first write the language code (english only)
136 //
137 if (WriteLangCode) {
138 fwrite (EnglishLangCode, 1, 4, OutFile);
139 }
140 //
141 // Next, write out the string... Convert ASCII to Unicode in the process.
142 //
143 Index = 0;
144 do {
145 fwrite (&String[Index], 1, 1, OutFile);
146 fwrite (&AsciiNull, 1, 1, OutFile);
147 } while (String[Index++] != 0);
148 }
149
150 STATUS
151 GenSectionCommonLeafSection (
152 char **InputFileName,
153 int InputFileNum,
154 UINTN SectionType,
155 FILE *OutFile
156 )
157 /*++
158
159 Routine Description:
160
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.
166
167 Arguments:
168
169 InputFileName - Name of the input file.
170
171 InputFileNum - Number of input files. Should be 1 for leaf section.
172
173 SectionType - A valid section type string
174
175 OutFile - Output file handle
176
177 Returns:
178
179 STATUS_ERROR - can't continue
180 STATUS_SUCCESS - successful return
181
182 --*/
183 {
184 UINT64 InputFileLength;
185 FILE *InFile;
186 UINT8 *Buffer;
187 INTN TotalLength;
188 EFI_COMMON_SECTION_HEADER CommonSect;
189 STATUS Status;
190
191 if (InputFileNum > 1) {
192 Error (NULL, 0, 0, "invalid parameter", "more than one input file specified");
193 return STATUS_ERROR;
194 } else if (InputFileNum < 1) {
195 Error (NULL, 0, 0, "no input file specified", NULL);
196 return STATUS_ERROR;
197 }
198 //
199 // Open the input file
200 //
201 InFile = fopen (InputFileName[0], "rb");
202 if (InFile == NULL) {
203 Error (NULL, 0, 0, InputFileName[0], "failed to open input file");
204 return STATUS_ERROR;
205 }
206
207 Status = STATUS_ERROR;
208 Buffer = NULL;
209 //
210 // Seek to the end of the input file so we can determine its size
211 //
212 fseek (InFile, 0, SEEK_END);
213 fgetpos (InFile, &InputFileLength);
214 fseek (InFile, 0, SEEK_SET);
215 //
216 // Fill in the fields in the local section header structure
217 //
218 CommonSect.Type = (EFI_SECTION_TYPE) SectionType;
219 TotalLength = sizeof (CommonSect) + (INTN) InputFileLength;
220 //
221 // Size must fit in 3 bytes
222 //
223 if (TotalLength >= 0x1000000) {
224 Error (NULL, 0, 0, InputFileName[0], "file size (0x%X) exceeds section size limit", TotalLength);
225 goto Done;
226 }
227 //
228 // Now copy the size into the section header and write out the section header
229 //
230 memcpy (&CommonSect.Size, &TotalLength, 3);
231 fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);
232 //
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.
235 //
236 if (InputFileLength != 0) {
237 Buffer = (UINT8 *) malloc ((size_t) InputFileLength);
238 if (Buffer == NULL) {
239 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
240 goto Done;
241 }
242
243 if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) {
244 Error (NULL, 0, 0, InputFileName[0], "failed to read contents of file");
245 goto Done;
246 }
247
248 if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) {
249 Error (NULL, 0, 0, "failed to write to output file", NULL);
250 goto Done;
251 }
252 }
253
254 Status = STATUS_SUCCESS;
255 Done:
256 fclose (InFile);
257 if (Buffer != NULL) {
258 free (Buffer);
259 }
260
261 return Status;
262 }
263
264 EFI_STATUS
265 GetSectionContents (
266 char **InputFileName,
267 int InputFileNum,
268 UINT8 *FileBuffer,
269 UINTN *BufferLength
270 )
271 /*++
272
273 Routine Description:
274
275 Get the contents of all section files specified in InputFileName
276 into FileBuffer.
277
278 Arguments:
279
280 InputFileName - Name of the input file.
281
282 InputFileNum - Number of input files. Should be at least 1.
283
284 FileBuffer - Output buffer to contain data
285
286 BufferLength - Actual length of the data
287
288 Returns:
289
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.
293
294 --*/
295 {
296 UINTN Size;
297 UINTN FileSize;
298 INTN Index;
299 FILE *InFile;
300
301 if (InputFileNum < 1) {
302 Error (NULL, 0, 0, "must specify at least one input file", NULL);
303 return EFI_INVALID_PARAMETER;
304 }
305
306 Size = 0;
307 //
308 // Go through our array of file names and copy their contents
309 // to the output buffer.
310 //
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");
315 return EFI_ABORTED;
316 }
317
318 fseek (InFile, 0, SEEK_END);
319 FileSize = ftell (InFile);
320 fseek (InFile, 0, SEEK_SET);
321 //
322 // Now read the contents of the file into the buffer
323 //
324 if (FileSize > 0) {
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");
327 fclose (InFile);
328 return EFI_ABORTED;
329 }
330 }
331
332 fclose (InFile);
333 Size += (UINTN) FileSize;
334 //
335 // make sure section ends on a DWORD boundary
336 //
337 while ((Size & 0x03) != 0) {
338 FileBuffer[Size] = 0;
339 Size++;
340 }
341 }
342
343 *BufferLength = Size;
344 return EFI_SUCCESS;
345 }
346
347 EFI_STATUS
348 GenSectionCompressionSection (
349 char **InputFileName,
350 int InputFileNum,
351 UINTN SectionType,
352 UINTN SectionSubType,
353 FILE *OutFile
354 )
355 /*++
356
357 Routine Description:
358
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
362 with section header.
363
364 Arguments:
365
366 InputFileName - Name of the input file.
367
368 InputFileNum - Number of input files. Should be at least 1.
369
370 SectionType - Section type to generate. Should be
371 EFI_SECTION_COMPRESSION
372
373 SectionSubType - Specify the compression algorithm requested.
374
375 OutFile - Output file handle
376
377 Returns:
378
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.
383 --*/
384 {
385 UINTN TotalLength;
386 UINTN InputLength;
387 UINTN CompressedLength;
388 UINT8 *FileBuffer;
389 UINT8 *OutputBuffer;
390 EFI_STATUS Status;
391 EFI_COMPRESSION_SECTION CompressionSect;
392 COMPRESS_FUNCTION CompressFunction;
393
394 if (SectionType != EFI_SECTION_COMPRESSION) {
395 Error (NULL, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL);
396 return EFI_INVALID_PARAMETER;
397 }
398
399 InputLength = 0;
400 FileBuffer = NULL;
401 OutputBuffer = NULL;
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;
407 }
408 //
409 // read all input file contents into a buffer
410 //
411 Status = GetSectionContents (
412 InputFileName,
413 InputFileNum,
414 FileBuffer,
415 &InputLength
416 );
417 if (EFI_ERROR (Status)) {
418 free (FileBuffer);
419 return Status;
420 }
421
422 CompressFunction = NULL;
423
424 //
425 // Now data is in FileBuffer, compress the data
426 //
427 switch (SectionSubType) {
428 case EFI_NOT_COMPRESSED:
429 CompressedLength = InputLength;
430 break;
431
432 case EFI_STANDARD_COMPRESSION:
433 CompressFunction = (COMPRESS_FUNCTION) Compress;
434 break;
435
436 case EFI_CUSTOMIZED_COMPRESSION:
437 CompressFunction = (COMPRESS_FUNCTION) CustomizedCompress;
438 break;
439
440 default:
441 Error (NULL, 0, 0, "unknown compression type", NULL);
442 free (FileBuffer);
443 return EFI_ABORTED;
444 }
445
446 if (CompressFunction != NULL) {
447
448 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);
449 if (Status == EFI_BUFFER_TOO_SMALL) {
450 OutputBuffer = malloc (CompressedLength);
451 if (!OutputBuffer) {
452 free (FileBuffer);
453 return EFI_OUT_OF_RESOURCES;
454 }
455
456 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);
457 }
458
459 free (FileBuffer);
460 FileBuffer = OutputBuffer;
461
462 if (EFI_ERROR (Status)) {
463 if (FileBuffer != NULL) {
464 free (FileBuffer);
465 }
466
467 return Status;
468 }
469 }
470
471 TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);
472 //
473 // Add the section header for the compressed data
474 //
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;
481
482 fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile);
483 fwrite (FileBuffer, CompressedLength, 1, OutFile);
484 free (FileBuffer);
485 return EFI_SUCCESS;
486 }
487
488 EFI_STATUS
489 GenSectionGuidDefinedSection (
490 char **InputFileName,
491 int InputFileNum,
492 UINTN SectionType,
493 UINTN SectionSubType,
494 FILE *OutFile
495 )
496 /*++
497
498 Routine Description:
499
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
503 with section header.
504
505 Arguments:
506
507 InputFileName - Name of the input file.
508
509 InputFileNum - Number of input files. Should be at least 1.
510
511 SectionType - Section type to generate. Should be
512 EFI_SECTION_GUID_DEFINED
513
514 SectionSubType - Specify the authentication algorithm requested.
515
516 OutFile - Output file handle
517
518 Returns:
519
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.
524
525 --*/
526 {
527 INTN TotalLength;
528 INTN InputLength;
529 UINT8 *FileBuffer;
530 UINT32 Crc32Checksum;
531 EFI_STATUS Status;
532 CRC32_SECTION_HEADER Crc32GuidSect;
533
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;
537 }
538
539 InputLength = 0;
540 FileBuffer = NULL;
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;
545 }
546 //
547 // read all input file contents into a buffer
548 //
549 Status = GetSectionContents (
550 InputFileName,
551 InputFileNum,
552 FileBuffer,
553 &InputLength
554 );
555 if (EFI_ERROR (Status)) {
556 free (FileBuffer);
557 return Status;
558 }
559 //
560 // Now data is in FileBuffer, compress the data
561 //
562 switch (SectionSubType) {
563 case EFI_SECTION_CRC32_GUID_DEFINED:
564 Crc32Checksum = 0;
565 CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum);
566 if (EFI_ERROR (Status)) {
567 free (FileBuffer);
568 return Status;
569 }
570
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;
580
581 break;
582
583 default:
584 Error (NULL, 0, 0, "invalid parameter", "unknown GUID defined type");
585 free (FileBuffer);
586 return EFI_ABORTED;
587 }
588
589 fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile);
590 fwrite (FileBuffer, InputLength, 1, OutFile);
591
592 free (FileBuffer);
593
594 return EFI_SUCCESS;
595 }
596
597 int
598 main (
599 int argc,
600 char *argv[]
601 )
602 /*++
603
604 Routine Description:
605
606 Main
607
608 Arguments:
609
610 command line parameters
611
612 Returns:
613
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.
617
618 --*/
619 {
620 INTN Index;
621 INTN VersionNumber;
622 UINTN SectionType;
623 UINTN SectionSubType;
624 BOOLEAN InputFileRequired;
625 BOOLEAN SubTypeRequired;
626 FILE *InFile;
627 FILE *OutFile;
628 INTN InputFileNum;
629
630 char **InputFileName;
631 char *OutputFileName;
632 char AuxString[500] = { 0 };
633
634 char *ParamSectionType;
635 char *ParamSectionSubType;
636 char *ParamLength;
637 char *ParamVersion;
638 char *ParamDigitalSignature;
639
640 EFI_STATUS Status;
641 EFI_COMMON_SECTION_HEADER CommonSect;
642
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;
651
652 VersionNumber = 0;
653 SectionType = 0;
654 SectionSubType = 0;
655 InputFileRequired = TRUE;
656 SubTypeRequired = FALSE;
657 InFile = NULL;
658 OutFile = NULL;
659 InputFileNum = 0;
660 Status = EFI_SUCCESS;
661
662 SetUtilityName (UTILITY_NAME);
663 if (argc == 1) {
664 PrintUsageMessage ();
665 return STATUS_ERROR;
666 }
667 //
668 // Parse command line
669 //
670 Index = 1;
671 while (Index < argc) {
672 if (strcmpi (argv[Index], "-i") == 0) {
673 //
674 // Input File found
675 //
676 Index++;
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;
681 }
682
683 memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)));
684 InputFileName[InputFileNum] = argv[Index];
685 InputFileNum++;
686 Index++;
687 //
688 // Parse subsequent parameters until another switch is encountered
689 //
690 while ((Index < argc) && (argv[Index][0] != '-')) {
691 if ((InputFileNum % MAXIMUM_INPUT_FILE_NUM) == 0) {
692 //
693 // InputFileName buffer too small, need to realloc
694 //
695 InputFileName = (char **) realloc (
696 InputFileName,
697 (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (char *)
698 );
699 if (InputFileName == NULL) {
700 Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");
701 return EFI_OUT_OF_RESOURCES;
702 }
703
704 memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)));
705 }
706
707 InputFileName[InputFileNum] = argv[Index];
708 InputFileNum++;
709 Index++;
710 }
711
712 }
713
714 if (strcmpi (argv[Index], "-o") == 0) {
715 //
716 // Output file found
717 //
718 Index++;
719 OutputFileName = argv[Index];
720 } else if (strcmpi (argv[Index], "-s") == 0) {
721 //
722 // Section Type found
723 //
724 Index++;
725 ParamSectionType = argv[Index];
726 } else if (strcmpi (argv[Index], "-t") == 0) {
727 //
728 // Compression or Authentication type
729 //
730 Index++;
731 ParamSectionSubType = argv[Index];
732 } else if (strcmpi (argv[Index], "-l") == 0) {
733 //
734 // Length
735 //
736 Index++;
737 ParamLength = argv[Index];
738 } else if (strcmpi (argv[Index], "-v") == 0) {
739 //
740 // VersionNumber
741 //
742 Index++;
743 ParamVersion = argv[Index];
744 } else if (strcmpi (argv[Index], "-a") == 0) {
745 //
746 // Aux string
747 //
748 Index++;
749 //
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
753 //
754 strncpy (AuxString, argv[Index], 499);
755 } else if (strcmpi (argv[Index], "-d") == 0) {
756 //
757 // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)
758 //
759 Index++;
760 ParamDigitalSignature = argv[Index];
761 } else if (strcmpi (argv[Index], "-?") == 0) {
762 PrintUsageMessage ();
763 return STATUS_ERROR;
764 } else {
765 Error (NULL, 0, 0, argv[Index], "unknown option");
766 return GetUtilityStatus ();
767 }
768
769 Index++;
770 }
771 //
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
774 // sense...
775 //
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;
783 } else {
784 Error (NULL, 0, 0, ParamSectionSubType, "unknown compression type");
785 PrintUsageMessage ();
786 return GetUtilityStatus ();
787 }
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;
793 } else {
794 Error (NULL, 0, 0, ParamSectionSubType, "unknown GUID defined section type", ParamSectionSubType);
795 PrintUsageMessage ();
796 return GetUtilityStatus ();
797 }
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 ();
814 }
815
816 if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) {
817 AuxString[0] = 0;
818 }
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 ();
826 }
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;
837 } else {
838 Error (NULL, 0, 0, ParamSectionType, "unknown section type");
839 PrintUsageMessage ();
840 return GetUtilityStatus ();
841 }
842 //
843 // Open output file
844 //
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) {
849 fclose (InFile);
850 }
851
852 return GetUtilityStatus ();
853 }
854 //
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...
857 //
858 //
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
861 //
862 switch (SectionType) {
863 case EFI_SECTION_COMPRESSION:
864 Status = GenSectionCompressionSection (
865 InputFileName,
866 InputFileNum,
867 SectionType,
868 SectionSubType,
869 OutFile
870 );
871 break;
872
873 case EFI_SECTION_GUID_DEFINED:
874 Status = GenSectionGuidDefinedSection (
875 InputFileName,
876 InputFileNum,
877 SectionType,
878 SectionSubType,
879 OutFile
880 );
881 break;
882
883 case EFI_SECTION_VERSION:
884 CommonSect.Type = (EFI_SECTION_TYPE) SectionType;
885
886 Index = sizeof (CommonSect);
887 //
888 // 2 characters for the build number
889 //
890 Index += 2;
891 //
892 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
893 //
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);
899 break;
900
901 case EFI_SECTION_USER_INTERFACE:
902 CommonSect.Type = (EFI_SECTION_TYPE) SectionType;
903 Index = sizeof (CommonSect);
904 //
905 // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
906 //
907 Index += (strlen (AuxString) * 2) + 2;
908 memcpy (&CommonSect.Size, &Index, 3);
909 fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);
910 Ascii2UnicodeWriteString (AuxString, OutFile, FALSE);
911 break;
912
913 default:
914 //
915 // All other section types are caught by default (they're all the same)
916 //
917 Status = GenSectionCommonLeafSection (
918 InputFileName,
919 InputFileNum,
920 SectionType,
921 OutFile
922 );
923 break;
924 }
925
926 if (InputFileName != NULL) {
927 free (InputFileName);
928 }
929
930 fclose (OutFile);
931 //
932 // If we had errors, then delete the output file
933 //
934 if (GetUtilityStatus () == STATUS_ERROR) {
935 remove (OutputFileName);
936 }
937
938 return GetUtilityStatus ();
939 }