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