]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenSec/GenSec.c
Sync basetools' source and binary files with r1707 of the basetools project.
[mirror_edk2.git] / BaseTools / Source / C / GenSec / GenSec.c
CommitLineData
30fdf114
LG
1/** @file\r
2\r
3Copyright (c) 2004 - 2008, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 GenSection.c\r
15\r
16Abstract:\r
17\r
18 Creates output file that is a properly formed section per the PI spec.\r
19\r
20**/\r
21\r
22#include <stdio.h>\r
23#include <stdlib.h>\r
24#include <string.h>\r
25#include <ctype.h>\r
26\r
27#include <Common/UefiBaseTypes.h>\r
28#include <Common/PiFirmwareFile.h>\r
29#include <Protocol/GuidedSectionExtraction.h>\r
30\r
31#include "CommonLib.h"\r
32#include "Compress.h"\r
33#include "Crc32.h"\r
34#include "EfiUtilityMsgs.h"\r
35#include "ParseInf.h"\r
36\r
37//\r
38// GenSec Tool Information\r
39//\r
40#define UTILITY_NAME "GenSec"\r
41#define UTILITY_MAJOR_VERSION 0\r
42#define UTILITY_MINOR_VERSION 1\r
43\r
44#define MAX_SECTION_SIZE 0x1000000\r
45\r
46STATIC CHAR8 *mSectionTypeName[] = {\r
47 NULL, // 0x00 - reserved\r
48 "EFI_SECTION_COMPRESSION", // 0x01\r
49 "EFI_SECTION_GUID_DEFINED", // 0x02\r
50 NULL, // 0x03 - reserved\r
51 NULL, // 0x04 - reserved\r
52 NULL, // 0x05 - reserved\r
53 NULL, // 0x06 - reserved\r
54 NULL, // 0x07 - reserved\r
55 NULL, // 0x08 - reserved\r
56 NULL, // 0x09 - reserved\r
57 NULL, // 0x0A - reserved\r
58 NULL, // 0x0B - reserved\r
59 NULL, // 0x0C - reserved\r
60 NULL, // 0x0D - reserved\r
61 NULL, // 0x0E - reserved\r
62 NULL, // 0x0F - reserved\r
63 "EFI_SECTION_PE32", // 0x10\r
64 "EFI_SECTION_PIC", // 0x11\r
65 "EFI_SECTION_TE", // 0x12\r
66 "EFI_SECTION_DXE_DEPEX", // 0x13\r
67 "EFI_SECTION_VERSION", // 0x14\r
68 "EFI_SECTION_USER_INTERFACE", // 0x15\r
69 "EFI_SECTION_COMPATIBILITY16", // 0x16\r
70 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17\r
71 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18\r
72 "EFI_SECTION_RAW", // 0x19\r
73 NULL, // 0x1A\r
74 "EFI_SECTION_PEI_DEPEX", // 0x1B\r
75 "EFI_SECTION_SMM_DEPEX" // 0x1C\r
76};\r
77\r
78STATIC CHAR8 *mCompressionTypeName[] = { "PI_NONE", "PI_STD" };\r
79\r
80#define EFI_GUIDED_SECTION_NONE 0x80\r
81STATIC CHAR8 *mGUIDedSectionAttribue[] = { "NONE", "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};\r
82\r
83//\r
84// Crc32 GUID section related definitions.\r
85//\r
86typedef struct {\r
87 EFI_GUID_DEFINED_SECTION GuidSectionHeader;\r
88 UINT32 CRC32Checksum;\r
89} CRC32_SECTION_HEADER;\r
90\r
91STATIC EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
92STATIC EFI_GUID mEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
93\r
94STATIC\r
95VOID \r
96Version (\r
97 VOID\r
98 )\r
99/*++\r
100\r
101Routine Description:\r
102\r
103 Print out version information for this utility.\r
104\r
105Arguments:\r
106\r
107 None\r
108 \r
109Returns:\r
110\r
111 None\r
112 \r
113--*/ \r
114{\r
115 fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
116}\r
117\r
118STATIC\r
119VOID\r
120Usage (\r
121 VOID\r
122 )\r
123/*++\r
124\r
125Routine Description:\r
126\r
127 Print Help message.\r
128\r
129Arguments:\r
130\r
131 VOID\r
132\r
133Returns:\r
134\r
135 None\r
136\r
137--*/\r
138{\r
139 //\r
140 // Summary usage\r
141 //\r
142 fprintf (stdout, "\nUsage: %s [options] [input_file]\n\n", UTILITY_NAME);\r
143 \r
144 //\r
145 // Copyright declaration\r
146 // \r
147 fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
148\r
149 //\r
150 // Details Option\r
151 //\r
152 fprintf (stdout, "Options:\n");\r
153 fprintf (stdout, " -o FileName, --outputfile FileName\n\\r
154 File is the SectionFile to be created.\n");\r
155 fprintf (stdout, " -s [SectionType], --sectiontype [SectionType]\n\\r
156 SectionType defined in PI spec is one type of\n\\r
157 EFI_SECTION_COMPRESSION, EFI_SECTION_GUID_DEFINED,\n\\r
158 EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE,\n\\r
159 EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16,\n\\r
160 EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION,\n\\r
161 EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW,\n\\r
162 EFI_SECTION_FREEFORM_SUBTYPE_GUID,\n\\r
fd171542 163 EFI_SECTION_PEI_DEPEX, EFI_SECTION_SMM_DEPEX.\n\\r
164 if -s option is not given, \n\\r
30fdf114
LG
165 EFI_SECTION_ALL is default section type.\n");\r
166 fprintf (stdout, " -c [Type], --compress [Type]\n\\r
167 Compress method type can be PI_NONE or PI_STD.\n\\r
168 if -c option is not given, PI_STD is default type.\n"); \r
169 fprintf (stdout, " -g GuidValue, --vendor GuidValue\n\\r
170 GuidValue is one specific vendor guid value.\n\\r
171 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
172 fprintf (stdout, " -l GuidHeaderLength, --HeaderLength GuidHeaderLength\n\\r
173 GuidHeaderLength is the size of header of guided data\n");\r
174 fprintf (stdout, " -r GuidAttr, --attributes GuidAttr\n\\r
175 GuidAttr is guid section atttributes, which may be\n\\r
176 PROCESSING_REQUIRED, AUTH_STATUS_VALID and NONE. \n\\r
177 if -r option is not given, default PROCESSING_REQUIRED\n");\r
178 fprintf (stdout, " -n String, --name String\n\\r
179 String is a NULL terminated string used in Ui section.\n");\r
180 fprintf (stdout, " -j Number, --buildnumber Number\n\\r
181 Number is an integer value between 0000 and 9999\n\\r
182 used in Ver section.\n");\r
183 fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
184 fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");\r
185 fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");\r
186 fprintf (stdout, " --version Show program's version number and exit.\n");\r
187 fprintf (stdout, " -h, --help Show this help message and exit.\n");\r
188}\r
189\r
190VOID\r
191Ascii2UnicodeString (\r
192 CHAR8 *String,\r
193 CHAR16 *UniString\r
194 )\r
195/*++\r
196\r
197Routine Description:\r
198\r
199 Write ascii string as unicode string format to FILE \r
200\r
201Arguments:\r
202\r
203 String - Pointer to string that is written to FILE.\r
204 UniString - Pointer to unicode string\r
205\r
206Returns:\r
207\r
208 NULL\r
209\r
210--*/\r
211{\r
212 while (*String != '\0') {\r
213 *(UniString++) = (CHAR16) *(String++);\r
214 }\r
215 //\r
216 // End the UniString with a NULL.\r
217 //\r
218 *UniString = '\0';\r
219} \r
220\r
221STATUS\r
222GenSectionCommonLeafSection (\r
223 CHAR8 **InputFileName,\r
224 UINT32 InputFileNum,\r
225 UINT8 SectionType,\r
226 UINT8 **OutFileBuffer\r
227 )\r
228/*++\r
229 \r
230Routine Description:\r
231 \r
232 Generate a leaf section of type other than EFI_SECTION_VERSION\r
233 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.\r
234 The function won't validate the input file's contents. For\r
235 common leaf sections, the input file may be a binary file.\r
236 The utility will add section header to the file.\r
237 \r
238Arguments:\r
239 \r
240 InputFileName - Name of the input file.\r
241 \r
242 InputFileNum - Number of input files. Should be 1 for leaf section.\r
243\r
244 SectionType - A valid section type string\r
245\r
246 OutFileBuffer - Buffer pointer to Output file contents\r
247\r
248Returns:\r
249 \r
250 STATUS_ERROR - can't continue\r
251 STATUS_SUCCESS - successful return\r
252\r
253--*/\r
254{\r
255 UINT32 InputFileLength;\r
256 FILE *InFile;\r
257 UINT8 *Buffer;\r
258 UINT32 TotalLength;\r
259 EFI_COMMON_SECTION_HEADER *CommonSect;\r
260 STATUS Status;\r
261\r
262 if (InputFileNum > 1) {\r
263 Error (NULL, 0, 2000, "Invalid paramter", "more than one input file specified");\r
264 return STATUS_ERROR;\r
265 } else if (InputFileNum < 1) {\r
266 Error (NULL, 0, 2000, "Invalid paramter", "no input file specified");\r
267 return STATUS_ERROR;\r
268 }\r
269 //\r
270 // Open the input file\r
271 //\r
272 InFile = fopen (InputFileName[0], "rb");\r
273 if (InFile == NULL) {\r
274 Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
275 return STATUS_ERROR;\r
276 }\r
277\r
278 Status = STATUS_ERROR;\r
279 Buffer = NULL;\r
280 //\r
281 // Seek to the end of the input file so we can determine its size\r
282 //\r
283 fseek (InFile, 0, SEEK_END);\r
284 InputFileLength = ftell (InFile);\r
285 fseek (InFile, 0, SEEK_SET);\r
fd171542 286 DebugMsg (NULL, 0, 9, "Input file", "File name is %s and File size is %u bytes", InputFileName[0], (unsigned) InputFileLength);\r
30fdf114
LG
287 TotalLength = sizeof (EFI_COMMON_SECTION_HEADER) + InputFileLength;\r
288 //\r
289 // Size must fit in 3 bytes\r
290 //\r
291 if (TotalLength >= MAX_SECTION_SIZE) {\r
fd171542 292 Error (NULL, 0, 2000, "Invalid paramter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);\r
30fdf114
LG
293 goto Done;\r
294 }\r
fd171542 295 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
30fdf114
LG
296 //\r
297 // Fill in the fields in the local section header structure\r
298 //\r
299 Buffer = (UINT8 *) malloc ((size_t) TotalLength);\r
300 if (Buffer == NULL) {\r
301 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); \r
302 goto Done;\r
303 }\r
304 CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;\r
305 CommonSect->Type = SectionType;\r
306 CommonSect->Size[0] = (UINT8) (TotalLength & 0xff);\r
307 CommonSect->Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
308 CommonSect->Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
309 \r
310 //\r
311 // read data from the input file.\r
312 //\r
313 if (InputFileLength != 0) {\r
314 if (fread (Buffer + sizeof (EFI_COMMON_SECTION_HEADER), (size_t) InputFileLength, 1, InFile) != 1) {\r
315 Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);\r
316 goto Done;\r
317 }\r
318 }\r
319\r
320 //\r
321 // Set OutFileBuffer \r
322 //\r
323 *OutFileBuffer = Buffer;\r
324 Status = STATUS_SUCCESS;\r
325\r
326Done:\r
327 fclose (InFile);\r
328\r
329 return Status;\r
330}\r
331\r
332EFI_STATUS\r
333GetSectionContents (\r
334 CHAR8 **InputFileName,\r
335 UINT32 InputFileNum,\r
336 UINT8 *FileBuffer,\r
337 UINT32 *BufferLength\r
338 )\r
339/*++\r
340 \r
341Routine Description:\r
342 \r
343 Get the contents of all section files specified in InputFileName\r
344 into FileBuffer.\r
345 \r
346Arguments:\r
347 \r
348 InputFileName - Name of the input file.\r
349 \r
350 InputFileNum - Number of input files. Should be at least 1.\r
351\r
352 FileBuffer - Output buffer to contain data\r
353\r
354 BufferLength - On input, this is size of the FileBuffer. \r
355 On output, this is the actual length of the data.\r
356\r
357Returns:\r
358 \r
359 EFI_SUCCESS on successful return\r
360 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.\r
361 EFI_ABORTED if unable to open input file.\r
362 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.\r
363--*/\r
364{\r
365 UINT32 Size;\r
366 UINT32 FileSize;\r
367 UINT32 Index;\r
368 FILE *InFile;\r
369\r
370 if (InputFileNum < 1) {\r
371 Error (NULL, 0, 2000, "Invalid paramter", "must specify at least one input file");\r
372 return EFI_INVALID_PARAMETER;\r
373 }\r
374\r
375 if (BufferLength == NULL) {\r
376 Error (NULL, 0, 2000, "Invalid paramter", "BufferLength can't be NULL");\r
377 return EFI_INVALID_PARAMETER;\r
378 }\r
379\r
380 Size = 0;\r
381 //\r
382 // Go through our array of file names and copy their contents\r
383 // to the output buffer.\r
384 //\r
385 for (Index = 0; Index < InputFileNum; Index++) {\r
386 //\r
387 // make sure section ends on a DWORD boundary\r
388 //\r
389 while ((Size & 0x03) != 0) {\r
390 if (FileBuffer != NULL && Size < *BufferLength) {\r
391 FileBuffer[Size] = 0;\r
392 }\r
393 Size++;\r
394 }\r
395 \r
396 // \r
397 // Open file and read contents\r
398 //\r
399 InFile = fopen (InputFileName[Index], "rb");\r
400 if (InFile == NULL) {\r
401 Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);\r
402 return EFI_ABORTED;\r
403 }\r
404\r
405 fseek (InFile, 0, SEEK_END);\r
406 FileSize = ftell (InFile);\r
407 fseek (InFile, 0, SEEK_SET);\r
fd171542 408 DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); \r
30fdf114
LG
409 //\r
410 // Now read the contents of the file into the buffer\r
411 // Buffer must be enough to contain the file content.\r
412 //\r
413 if (FileSize > 0 && FileBuffer != NULL && (Size + FileSize) <= *BufferLength) {\r
414 if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {\r
415 Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);\r
416 fclose (InFile);\r
417 return EFI_ABORTED;\r
418 }\r
419 }\r
420\r
421 fclose (InFile);\r
422 Size += FileSize;\r
423 }\r
424 \r
425 //\r
426 // Set the real required buffer size.\r
427 //\r
428 if (Size > *BufferLength) {\r
429 *BufferLength = Size;\r
430 return EFI_BUFFER_TOO_SMALL;\r
431 } else {\r
432 *BufferLength = Size;\r
433 return EFI_SUCCESS;\r
434 }\r
435}\r
436\r
437EFI_STATUS\r
438GenSectionCompressionSection (\r
439 CHAR8 **InputFileName,\r
440 UINT32 InputFileNum,\r
441 UINT8 SectCompSubType,\r
442 UINT8 **OutFileBuffer\r
443 )\r
444/*++\r
445 \r
446Routine Description:\r
447 \r
448 Generate an encapsulating section of type EFI_SECTION_COMPRESSION\r
449 Input file must be already sectioned. The function won't validate\r
450 the input files' contents. Caller should hand in files already \r
451 with section header.\r
452 \r
453Arguments:\r
454 \r
455 InputFileName - Name of the input file.\r
456 \r
457 InputFileNum - Number of input files. Should be at least 1.\r
458\r
459 SectCompSubType - Specify the compression algorithm requested. \r
460 \r
461 OutFileBuffer - Buffer pointer to Output file contents\r
462\r
463Returns:\r
464 \r
465 EFI_SUCCESS on successful return\r
466 EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
467 EFI_ABORTED if unable to open input file.\r
468 EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
469--*/\r
470{\r
471 UINT32 TotalLength;\r
472 UINT32 InputLength;\r
473 UINT32 CompressedLength;\r
474 UINT8 *FileBuffer;\r
475 UINT8 *OutputBuffer;\r
476 EFI_STATUS Status;\r
477 EFI_COMPRESSION_SECTION *CompressionSect;\r
478 COMPRESS_FUNCTION CompressFunction;\r
479\r
480 InputLength = 0;\r
481 FileBuffer = NULL;\r
482 OutputBuffer = NULL;\r
483 CompressedLength = 0;\r
484 //\r
485 // read all input file contents into a buffer\r
486 // first get the size of all file contents\r
487 //\r
488 Status = GetSectionContents (\r
489 InputFileName,\r
490 InputFileNum,\r
491 FileBuffer,\r
492 &InputLength\r
493 );\r
494\r
495 if (Status == EFI_BUFFER_TOO_SMALL) {\r
496 FileBuffer = (UINT8 *) malloc (InputLength);\r
497 if (FileBuffer == NULL) {\r
498 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
499 return EFI_OUT_OF_RESOURCES;\r
500 }\r
501 //\r
502 // read all input file contents into a buffer\r
503 //\r
504 Status = GetSectionContents (\r
505 InputFileName,\r
506 InputFileNum,\r
507 FileBuffer,\r
508 &InputLength\r
509 );\r
510 }\r
511\r
512 if (EFI_ERROR (Status)) {\r
513 if (FileBuffer != NULL) {\r
514 free (FileBuffer);\r
515 }\r
516 return Status;\r
517 }\r
518\r
519 CompressFunction = NULL;\r
520\r
521 //\r
522 // Now data is in FileBuffer, compress the data\r
523 //\r
524 switch (SectCompSubType) {\r
525 case EFI_NOT_COMPRESSED:\r
526 CompressedLength = InputLength;\r
527 break;\r
528\r
529 case EFI_STANDARD_COMPRESSION:\r
530 CompressFunction = (COMPRESS_FUNCTION) EfiCompress;\r
531 break;\r
532\r
533 default:\r
534 Error (NULL, 0, 2000, "Invalid paramter", "unknown compression type");\r
535 free (FileBuffer);\r
536 return EFI_ABORTED;\r
537 }\r
538\r
539 if (CompressFunction != NULL) {\r
540\r
541 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
542 if (Status == EFI_BUFFER_TOO_SMALL) {\r
543 OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
544 if (!OutputBuffer) {\r
545 free (FileBuffer);\r
546 return EFI_OUT_OF_RESOURCES;\r
547 }\r
548\r
549 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), &CompressedLength);\r
550 }\r
551\r
552 free (FileBuffer);\r
553 FileBuffer = OutputBuffer;\r
554\r
555 if (EFI_ERROR (Status)) {\r
556 if (FileBuffer != NULL) {\r
557 free (FileBuffer);\r
558 }\r
559\r
560 return Status;\r
561 }\r
562 }\r
563\r
564 DebugMsg (NULL, 0, 9, "comprss file size", \r
fd171542 565 "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);\r
30fdf114
LG
566 TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);\r
567 if (TotalLength >= MAX_SECTION_SIZE) {\r
fd171542 568 Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
30fdf114
LG
569 if (FileBuffer != NULL) {\r
570 free (FileBuffer);\r
571 }\r
572 if (OutputBuffer != NULL) {\r
573 free (OutputBuffer);\r
574 }\r
575 return STATUS_ERROR;\r
576 }\r
fd171542 577 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
30fdf114
LG
578\r
579 //\r
580 // Add the section header for the compressed data\r
581 //\r
582 CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
583 \r
584 CompressionSect->CommonHeader.Type = EFI_SECTION_COMPRESSION;\r
585 CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
586 CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
587 CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
588 CompressionSect->CompressionType = SectCompSubType;\r
589 CompressionSect->UncompressedLength = InputLength;\r
590\r
591 //\r
592 // Set OutFileBuffer \r
593 //\r
594 *OutFileBuffer = FileBuffer;\r
595\r
596 return EFI_SUCCESS;\r
597}\r
598\r
599EFI_STATUS\r
600GenSectionGuidDefinedSection (\r
601 CHAR8 **InputFileName,\r
602 UINT32 InputFileNum,\r
603 EFI_GUID *VendorGuid,\r
604 UINT16 DataAttribute,\r
605 UINT32 DataHeaderSize,\r
606 UINT8 **OutFileBuffer\r
607 )\r
608/*++\r
609 \r
610Routine Description:\r
611 \r
612 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED\r
613 Input file must be already sectioned. The function won't validate\r
614 the input files' contents. Caller should hand in files already \r
615 with section header.\r
616 \r
617Arguments:\r
618 \r
619 InputFileName - Name of the input file.\r
620 \r
621 InputFileNum - Number of input files. Should be at least 1.\r
622\r
623 VendorGuid - Specify vendor guid value.\r
624\r
625 DataAttribute - Specify attribute for the vendor guid data. \r
626 \r
627 DataHeaderSize- Guided Data Header Size\r
628 \r
629 OutFileBuffer - Buffer pointer to Output file contents\r
630\r
631Returns:\r
632 \r
633 EFI_SUCCESS on successful return\r
634 EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
635 EFI_ABORTED if unable to open input file.\r
636 EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
637\r
638--*/\r
639{\r
640 UINT32 TotalLength;\r
641 UINT32 InputLength;\r
642 UINT32 Offset;\r
643 UINT8 *FileBuffer;\r
644 UINT32 Crc32Checksum;\r
645 EFI_STATUS Status;\r
646 CRC32_SECTION_HEADER *Crc32GuidSect;\r
647 EFI_GUID_DEFINED_SECTION *VendorGuidSect;\r
648\r
649 InputLength = 0;\r
650 Offset = 0;\r
651 FileBuffer = NULL;\r
652\r
653 if (CompareGuid (VendorGuid, &mEfiCrc32SectionGuid) == 0) {\r
654 Offset = sizeof (CRC32_SECTION_HEADER);\r
655 } else {\r
656 Offset = sizeof (EFI_GUID_DEFINED_SECTION);\r
657 }\r
658\r
659 //\r
660 // read all input file contents into a buffer\r
661 // first get the size of all file contents\r
662 //\r
663 Status = GetSectionContents (\r
664 InputFileName,\r
665 InputFileNum,\r
666 FileBuffer,\r
667 &InputLength\r
668 );\r
669\r
670 if (Status == EFI_BUFFER_TOO_SMALL) {\r
671 FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
672 if (FileBuffer == NULL) {\r
673 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
674 return EFI_OUT_OF_RESOURCES;\r
675 }\r
676 //\r
677 // read all input file contents into a buffer\r
678 //\r
679 Status = GetSectionContents (\r
680 InputFileName,\r
681 InputFileNum,\r
682 FileBuffer + Offset,\r
683 &InputLength\r
684 );\r
685 }\r
686\r
687 if (EFI_ERROR (Status)) {\r
688 if (FileBuffer != NULL) {\r
689 free (FileBuffer);\r
690 }\r
691 Error (NULL, 0, 0001, "Error opening file for reading", InputFileName[0]);\r
692 return Status;\r
693 }\r
694\r
695 if (InputLength == 0) {\r
696 Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
697 return EFI_NOT_FOUND;\r
698 }\r
699\r
700 //\r
701 // Now data is in FileBuffer + Offset\r
702 //\r
703 if (CompareGuid (VendorGuid, &mEfiCrc32SectionGuid) == 0) {\r
704 //\r
705 // Default Guid section is CRC32.\r
706 //\r
707 Crc32Checksum = 0;\r
708 CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);\r
709\r
710 TotalLength = InputLength + sizeof (CRC32_SECTION_HEADER);\r
711 if (TotalLength >= MAX_SECTION_SIZE) {\r
fd171542 712 Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
30fdf114
LG
713 free (FileBuffer);\r
714 return STATUS_ERROR;\r
715 }\r
716 \r
717 Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;\r
718 Crc32GuidSect->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
719 Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
720 Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
721 Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
722 memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
723 Crc32GuidSect->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
724 Crc32GuidSect->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);\r
725 Crc32GuidSect->CRC32Checksum = Crc32Checksum;\r
fd171542 726 DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
30fdf114
LG
727\r
728 } else {\r
729 TotalLength = InputLength + sizeof (EFI_GUID_DEFINED_SECTION);\r
730 if (TotalLength >= MAX_SECTION_SIZE) {\r
fd171542 731 Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
30fdf114
LG
732 free (FileBuffer);\r
733 return STATUS_ERROR;\r
734 }\r
735\r
736 VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;\r
737 VendorGuidSect->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
738 VendorGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
739 VendorGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
740 VendorGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
741 memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
742 VendorGuidSect->Attributes = DataAttribute;\r
fd171542 743 VendorGuidSect->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);\r
744 DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);\r
30fdf114 745 }\r
fd171542 746 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
30fdf114
LG
747 \r
748 //\r
749 // Set OutFileBuffer \r
750 //\r
751 *OutFileBuffer = FileBuffer;\r
752\r
753 return EFI_SUCCESS;\r
754}\r
755\r
756int\r
757main (\r
758 int argc,\r
759 char *argv[]\r
760 )\r
761/*++\r
762\r
763Routine Description:\r
764\r
765 Main\r
766\r
767Arguments:\r
768\r
769 command line parameters\r
770\r
771Returns:\r
772\r
773 EFI_SUCCESS Section header successfully generated and section concatenated.\r
774 EFI_ABORTED Could not generate the section\r
775 EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
776\r
777--*/\r
778{\r
779 UINT32 Index;\r
780 UINT32 InputFileNum;\r
781 FILE *InFile;\r
782 FILE *OutFile;\r
783 CHAR8 **InputFileName;\r
784 CHAR8 *OutputFileName;\r
785 CHAR8 *SectionName;\r
786 CHAR8 *CompressionName;\r
787 CHAR8 *StringBuffer;\r
788 EFI_GUID VendorGuid = mZeroGuid;\r
fd171542 789 int VersionNumber;\r
30fdf114
LG
790 UINT8 SectType;\r
791 UINT8 SectCompSubType;\r
792 UINT16 SectGuidAttribute; \r
793 UINT64 SectGuidHeaderLength;\r
794 EFI_VERSION_SECTION *VersionSect;\r
795 EFI_USER_INTERFACE_SECTION *UiSect;\r
796 UINT32 InputLength;\r
797 UINT8 *OutFileBuffer;\r
798 EFI_STATUS Status;\r
799 UINT64 LogLevel;\r
800 \r
801 InputFileName = NULL;\r
802 OutputFileName = NULL;\r
803 SectionName = NULL;\r
804 CompressionName = NULL;\r
805 StringBuffer = "";\r
806 InFile = NULL;\r
807 OutFile = NULL;\r
808 VersionNumber = 0;\r
809 InputFileNum = 0;\r
810 SectType = EFI_SECTION_ALL;\r
811 SectCompSubType = 0;\r
812 SectGuidAttribute = 0;\r
813 OutFileBuffer = NULL;\r
814 InputLength = 0;\r
815 Status = STATUS_SUCCESS;\r
816 LogLevel = 0;\r
817 SectGuidHeaderLength = 0;\r
818 VersionSect = NULL;\r
819 UiSect = NULL;\r
820 \r
821 SetUtilityName (UTILITY_NAME);\r
822 \r
823 if (argc == 1) {\r
824 Error (NULL, 0, 1001, "Missing options", "No options input");\r
825 Usage ();\r
826 return STATUS_ERROR;\r
827 }\r
828\r
829 //\r
830 // Parse command line\r
831 //\r
832 argc --;\r
833 argv ++;\r
834\r
835 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
836 Version ();\r
837 Usage ();\r
838 return STATUS_SUCCESS; \r
839 }\r
840\r
841 if (stricmp (argv[0], "--version") == 0) {\r
842 Version ();\r
843 return STATUS_SUCCESS; \r
844 }\r
845\r
846 while (argc > 0) {\r
847 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--SectionType") == 0)) {\r
848 SectionName = argv[1];\r
849 if (SectionName == NULL) {\r
850 Error (NULL, 0, 1003, "Invalid option value", "Section Type can't be NULL");\r
851 goto Finish;\r
852 }\r
853 argc -= 2;\r
854 argv += 2;\r
855 continue; \r
856 }\r
857\r
858 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
859 OutputFileName = argv[1];\r
860 if (OutputFileName == NULL) {\r
861 Error (NULL, 0, 1003, "Invalid option value", "Output file can't be NULL");\r
862 goto Finish;\r
863 }\r
864 argc -= 2;\r
865 argv += 2;\r
866 continue; \r
867 }\r
868\r
869 if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--compress") == 0)) {\r
870 CompressionName = argv[1];\r
871 if (CompressionName == NULL) {\r
872 Error (NULL, 0, 1003, "Invalid option value", "Compression Type can't be NULL");\r
873 goto Finish;\r
874 }\r
875 argc -= 2;\r
876 argv += 2;\r
877 continue;\r
878 }\r
879\r
880 if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--vendor") == 0)) {\r
881 Status = StringToGuid (argv[1], &VendorGuid);\r
882 if (EFI_ERROR (Status)) {\r
883 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
884 goto Finish;\r
885 }\r
886 argc -= 2;\r
887 argv += 2;\r
888 continue;\r
889 }\r
890\r
891 if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {\r
892 if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
893 SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
894 } else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
895 SectGuidAttribute |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
896 } else if (stricmp (argv[1], mGUIDedSectionAttribue[0]) == 0) {\r
897 //\r
898 // NONE attribute\r
899 //\r
900 SectGuidAttribute |= EFI_GUIDED_SECTION_NONE;\r
901 } else {\r
902 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
903 goto Finish;\r
904 }\r
905 argc -= 2;\r
906 argv += 2;\r
907 continue;\r
908 }\r
909\r
910 if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--HeaderLength") == 0)) {\r
911 Status = AsciiStringToUint64 (argv[1], FALSE, &SectGuidHeaderLength);\r
912 if (EFI_ERROR (Status)) {\r
913 Error (NULL, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv[0], argv[1]);\r
914 goto Finish;\r
915 }\r
916 argc -= 2;\r
917 argv += 2;\r
918 continue;\r
919 }\r
920\r
921 if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--name") == 0)) {\r
922 StringBuffer = argv[1];\r
923 if (StringBuffer == NULL) {\r
924 Error (NULL, 0, 1003, "Invalid option value", "Name can't be NULL");\r
925 goto Finish;\r
926 }\r
927 argc -= 2;\r
928 argv += 2;\r
929 continue;\r
930 }\r
931\r
932 if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--buildnumber") == 0)) {\r
933 if (argv[1] == NULL) {\r
934 Error (NULL, 0, 1003, "Invalid option value", "build number can't be NULL");\r
935 goto Finish;\r
936 }\r
937 //\r
938 // Verify string is a integrator number\r
939 //\r
940 for (Index = 0; Index < strlen (argv[1]); Index++) {\r
941 if ((argv[1][Index] != '-') && (isdigit (argv[1][Index]) == 0)) {\r
942 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
943 goto Finish;\r
944 }\r
945 }\r
946\r
947 sscanf (argv[1], "%d", &VersionNumber);\r
948 argc -= 2;\r
949 argv += 2;\r
950 continue;\r
951 }\r
952\r
953 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
954 SetPrintLevel (VERBOSE_LOG_LEVEL);\r
955 VerboseMsg ("Verbose output Mode Set!");\r
956 argc --;\r
957 argv ++;\r
958 continue;\r
959 }\r
960\r
961 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
962 SetPrintLevel (KEY_LOG_LEVEL);\r
963 KeyMsg ("Quiet output Mode Set!");\r
964 argc --;\r
965 argv ++;\r
966 continue;\r
967 }\r
968\r
969 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
970 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
971 if (EFI_ERROR (Status)) {\r
972 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
973 goto Finish;\r
974 }\r
975 if (LogLevel > 9) {\r
fd171542 976 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0~9, currnt input level is %d", (int) LogLevel);\r
30fdf114
LG
977 goto Finish;\r
978 }\r
979 SetPrintLevel (LogLevel);\r
980 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
981 argc -= 2;\r
982 argv += 2;\r
983 continue;\r
984 }\r
985\r
986 //\r
987 // Get Input file name\r
988 //\r
989 if ((InputFileNum == 0) && (InputFileName == NULL)) {\r
990 InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
991 if (InputFileName == NULL) {\r
992 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
993 return 1;\r
994 }\r
995\r
996 memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
997 } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
998 //\r
999 // InputFileName buffer too small, need to realloc\r
1000 //\r
1001 InputFileName = (CHAR8 **) realloc (\r
1002 InputFileName,\r
1003 (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
1004 );\r
1005\r
1006 if (InputFileName == NULL) {\r
1007 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1008 return 1;\r
1009 }\r
1010\r
1011 memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
1012 }\r
1013\r
1014 InputFileName[InputFileNum++] = argv[0];\r
1015 argc --;\r
1016 argv ++;\r
1017 }\r
1018\r
1019 VerboseMsg ("%s tool start.", UTILITY_NAME);\r
1020\r
1021 //\r
1022 // Parse all command line parameters to get the corresponding section type.\r
1023 //\r
1024 VerboseMsg ("Section type is %s", SectionName);\r
1025 if (SectionName == NULL) {\r
1026 //\r
1027 // No specified Section type, default is SECTION_ALL.\r
1028 //\r
1029 SectType = EFI_SECTION_ALL;\r
1030 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {\r
1031 SectType = EFI_SECTION_COMPRESSION;\r
1032 if (CompressionName == NULL) {\r
1033 //\r
1034 // Default is PI_STD compression algorithm.\r
1035 //\r
1036 SectCompSubType = EFI_STANDARD_COMPRESSION;\r
1037 } else if (stricmp (CompressionName, mCompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {\r
1038 SectCompSubType = EFI_NOT_COMPRESSED;\r
1039 } else if (stricmp (CompressionName, mCompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {\r
1040 SectCompSubType = EFI_STANDARD_COMPRESSION;\r
1041 } else {\r
1042 Error (NULL, 0, 1003, "Invalid option value", "--compress = %s", CompressionName);\r
1043 goto Finish;\r
1044 }\r
1045 VerboseMsg ("Compress method is %s", mCompressionTypeName [SectCompSubType]);\r
1046 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
1047 SectType = EFI_SECTION_GUID_DEFINED;\r
1048\r
1049 if (CompareGuid (&VendorGuid, &mZeroGuid) == 0) {\r
1050 memcpy (&VendorGuid, &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
1051 }\r
1052 \r
1053 if (SectGuidAttribute == 0) {\r
1054 SectGuidAttribute = EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
1055 }\r
1056 if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {\r
1057 //\r
1058 // NONE attribute, clear attribute value.\r
1059 //\r
1060 SectGuidAttribute = 0;\r
1061 }\r
1062 VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
fd171542 1063 (unsigned) VendorGuid.Data1,\r
30fdf114
LG
1064 VendorGuid.Data2,\r
1065 VendorGuid.Data3,\r
1066 VendorGuid.Data4[0],\r
1067 VendorGuid.Data4[1],\r
1068 VendorGuid.Data4[2],\r
1069 VendorGuid.Data4[3],\r
1070 VendorGuid.Data4[4],\r
1071 VendorGuid.Data4[5],\r
1072 VendorGuid.Data4[6],\r
1073 VendorGuid.Data4[7]);\r
1074 if ((SectGuidAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {\r
1075 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]);\r
1076 }\r
1077 if ((SectGuidAttribute & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) {\r
1078 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]);\r
1079 }\r
1080 if (SectGuidHeaderLength != 0) {\r
fd171542 1081 VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength);\r
30fdf114
LG
1082 }\r
1083 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PE32]) == 0) {\r
1084 SectType = EFI_SECTION_PE32;\r
1085 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PIC]) == 0) {\r
1086 SectType = EFI_SECTION_PIC;\r
1087 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_TE]) == 0) {\r
1088 SectType = EFI_SECTION_TE;\r
1089 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {\r
1090 SectType = EFI_SECTION_DXE_DEPEX;\r
fd171542 1091 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_SMM_DEPEX]) == 0) {\r
1092 SectType = EFI_SECTION_SMM_DEPEX;\r
30fdf114
LG
1093 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_VERSION]) == 0) {\r
1094 SectType = EFI_SECTION_VERSION;\r
1095 if (VersionNumber < 0 || VersionNumber > 9999) {\r
1096 Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~9999", VersionNumber);\r
1097 goto Finish;\r
1098 }\r
1099 VerboseMsg ("Version section number is %d", VersionNumber);\r
1100 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {\r
1101 SectType = EFI_SECTION_USER_INTERFACE;\r
1102 if (StringBuffer[0] == '\0') {\r
1103 Error (NULL, 0, 1001, "Missing option", "user interface string");\r
1104 goto Finish;\r
1105 }\r
1106 VerboseMsg ("UI section string name is %s", StringBuffer);\r
1107 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {\r
1108 SectType = EFI_SECTION_COMPATIBILITY16;\r
1109 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {\r
1110 SectType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
1111 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {\r
1112 SectType = EFI_SECTION_FREEFORM_SUBTYPE_GUID;\r
1113 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_RAW]) == 0) {\r
1114 SectType = EFI_SECTION_RAW;\r
1115 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {\r
1116 SectType = EFI_SECTION_PEI_DEPEX;\r
1117 } else {\r
1118 Error (NULL, 0, 1003, "Invalid option value", "SectionType = %s", SectionName);\r
1119 goto Finish;\r
1120 }\r
1121 \r
1122 //\r
1123 // GuidValue is only required by Guided section.\r
1124 //\r
1125 if ((SectType != EFI_SECTION_GUID_DEFINED) && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
1126 fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
1127 }\r
1128 \r
1129 //\r
1130 // Check whether there is input file\r
1131 // \r
1132 if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {\r
1133 //\r
1134 // The input file are required for other section type.\r
1135 //\r
1136 if (InputFileNum == 0) {\r
1137 Error (NULL, 0, 1001, "Missing options", "Input files");\r
1138 goto Finish;\r
1139 }\r
1140 }\r
1141 //\r
1142 // Check whether there is output file\r
1143 //\r
1144 for (Index = 0; Index < InputFileNum; Index ++) {\r
fd171542 1145 VerboseMsg ("the %uth input file name is %s", (unsigned) Index, InputFileName[Index]);\r
30fdf114
LG
1146 }\r
1147 if (OutputFileName == NULL) {\r
1148 Error (NULL, 0, 1001, "Missing options", "Output file");\r
1149 goto Finish;\r
1150 // OutFile = stdout;\r
1151 }\r
1152 VerboseMsg ("Output file name is %s", OutputFileName);\r
1153\r
1154 //\r
1155 // At this point, we've fully validated the command line, and opened appropriate\r
1156 // files, so let's go and do what we've been asked to do...\r
1157 //\r
1158 //\r
1159 // Within this switch, build and write out the section header including any\r
1160 // section type specific pieces. If there's an input file, it's tacked on later\r
1161 //\r
1162 switch (SectType) {\r
1163 case EFI_SECTION_COMPRESSION:\r
1164 Status = GenSectionCompressionSection (\r
1165 InputFileName,\r
1166 InputFileNum,\r
1167 SectCompSubType,\r
1168 &OutFileBuffer\r
1169 );\r
1170 break;\r
1171\r
1172 case EFI_SECTION_GUID_DEFINED:\r
1173 Status = GenSectionGuidDefinedSection (\r
1174 InputFileName,\r
1175 InputFileNum,\r
1176 &VendorGuid,\r
1177 SectGuidAttribute,\r
1178 (UINT32) SectGuidHeaderLength,\r
1179 &OutFileBuffer\r
1180 );\r
1181 break;\r
1182\r
1183 case EFI_SECTION_VERSION:\r
1184 Index = sizeof (EFI_COMMON_SECTION_HEADER);\r
1185 //\r
1186 // 2 bytes for the build number UINT16\r
1187 //\r
1188 Index += 2;\r
1189 //\r
1190 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
1191 //\r
1192 Index += (strlen (StringBuffer) * 2) + 2;\r
1193 OutFileBuffer = (UINT8 *) malloc (Index);\r
1194 if (OutFileBuffer == NULL) {\r
1195 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1196 goto Finish;\r
1197 }\r
1198 VersionSect = (EFI_VERSION_SECTION *) OutFileBuffer;\r
1199 VersionSect->CommonHeader.Type = SectType;\r
1200 VersionSect->CommonHeader.Size[0] = (UINT8) (Index & 0xff);\r
1201 VersionSect->CommonHeader.Size[1] = (UINT8) ((Index & 0xff00) >> 8);\r
1202 VersionSect->CommonHeader.Size[2] = (UINT8) ((Index & 0xff0000) >> 16);\r
1203 VersionSect->BuildNumber = (UINT16) VersionNumber;\r
1204 Ascii2UnicodeString (StringBuffer, VersionSect->VersionString);\r
fd171542 1205 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);\r
30fdf114
LG
1206 break;\r
1207\r
1208 case EFI_SECTION_USER_INTERFACE:\r
1209 Index = sizeof (EFI_COMMON_SECTION_HEADER);\r
1210 //\r
1211 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
1212 //\r
1213 Index += (strlen (StringBuffer) * 2) + 2;\r
1214 OutFileBuffer = (UINT8 *) malloc (Index);\r
1215 if (OutFileBuffer == NULL) {\r
1216 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1217 goto Finish;\r
1218 }\r
1219 UiSect = (EFI_USER_INTERFACE_SECTION *) OutFileBuffer;\r
1220 UiSect->CommonHeader.Type = SectType;\r
1221 UiSect->CommonHeader.Size[0] = (UINT8) (Index & 0xff);\r
1222 UiSect->CommonHeader.Size[1] = (UINT8) ((Index & 0xff00) >> 8);\r
1223 UiSect->CommonHeader.Size[2] = (UINT8) ((Index & 0xff0000) >> 16);\r
1224 Ascii2UnicodeString (StringBuffer, UiSect->FileNameString);\r
fd171542 1225 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);\r
30fdf114
LG
1226 break;\r
1227\r
1228 case EFI_SECTION_ALL:\r
1229 //\r
1230 // read all input file contents into a buffer\r
1231 // first get the size of all file contents\r
1232 //\r
1233 Status = GetSectionContents (\r
1234 InputFileName,\r
1235 InputFileNum,\r
1236 OutFileBuffer,\r
1237 &InputLength\r
1238 );\r
1239 \r
1240 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1241 OutFileBuffer = (UINT8 *) malloc (InputLength);\r
1242 if (OutFileBuffer == NULL) {\r
1243 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1244 goto Finish;\r
1245 }\r
1246 //\r
1247 // read all input file contents into a buffer\r
1248 //\r
1249 Status = GetSectionContents (\r
1250 InputFileName,\r
1251 InputFileNum,\r
1252 OutFileBuffer,\r
1253 &InputLength\r
1254 );\r
1255 }\r
fd171542 1256 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength);\r
30fdf114
LG
1257 break;\r
1258 default:\r
1259 //\r
1260 // All other section types are caught by default (they're all the same)\r
1261 //\r
1262 Status = GenSectionCommonLeafSection (\r
1263 InputFileName,\r
1264 InputFileNum,\r
1265 SectType,\r
1266 &OutFileBuffer\r
1267 );\r
1268 break;\r
1269 }\r
1270 \r
1271 if (Status != EFI_SUCCESS || OutFileBuffer == NULL) {\r
fd171542 1272 Error (NULL, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status);\r
30fdf114
LG
1273 goto Finish;\r
1274 }\r
1275\r
1276 //\r
1277 // Get output file length\r
1278 //\r
1279 if (SectType != EFI_SECTION_ALL) {\r
1280 InputLength = SECTION_SIZE (OutFileBuffer);\r
1281 }\r
1282 \r
1283 //\r
1284 // Write the output file\r
1285 //\r
1286 OutFile = fopen (OutputFileName, "wb");\r
1287 if (OutFile == NULL) {\r
1288 Error (NULL, 0, 0001, "Error opening file for writing", OutputFileName);\r
1289 goto Finish;\r
1290 }\r
1291\r
1292 fwrite (OutFileBuffer, InputLength, 1, OutFile);\r
1293\r
1294Finish:\r
1295 if (InputFileName != NULL) {\r
1296 free (InputFileName);\r
1297 }\r
1298\r
1299 if (OutFileBuffer != NULL) {\r
1300 free (OutFileBuffer);\r
1301 }\r
1302\r
1303 if (OutFile != NULL) {\r
1304 fclose (OutFile);\r
1305 }\r
1306 \r
1307 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
1308\r
1309 return GetUtilityStatus ();\r
1310}\r