]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenSec/GenSec.c
BaseTools: Correct GenSec argument dummy free memory issue
[mirror_edk2.git] / BaseTools / Source / C / GenSec / GenSec.c
CommitLineData
30fdf114 1/** @file\r
97fa0ee9 2Creates output file that is a properly formed section per the PI spec.\r
30fdf114 3\r
6ecab5ad 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5This program and the accompanying materials \r
30fdf114
LG
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
30fdf114
LG
13**/\r
14\r
15#include <stdio.h>\r
16#include <stdlib.h>\r
17#include <string.h>\r
18#include <ctype.h>\r
19\r
20#include <Common/UefiBaseTypes.h>\r
21#include <Common/PiFirmwareFile.h>\r
22#include <Protocol/GuidedSectionExtraction.h>\r
52302d4d 23#include <IndustryStandard/PeImage.h>\r
30fdf114
LG
24\r
25#include "CommonLib.h"\r
26#include "Compress.h"\r
27#include "Crc32.h"\r
28#include "EfiUtilityMsgs.h"\r
29#include "ParseInf.h"\r
30\r
31//\r
32// GenSec Tool Information\r
33//\r
34#define UTILITY_NAME "GenSec"\r
35#define UTILITY_MAJOR_VERSION 0\r
36#define UTILITY_MINOR_VERSION 1\r
37\r
30fdf114
LG
38STATIC CHAR8 *mSectionTypeName[] = {\r
39 NULL, // 0x00 - reserved\r
40 "EFI_SECTION_COMPRESSION", // 0x01\r
41 "EFI_SECTION_GUID_DEFINED", // 0x02\r
42 NULL, // 0x03 - reserved\r
43 NULL, // 0x04 - reserved\r
44 NULL, // 0x05 - reserved\r
45 NULL, // 0x06 - reserved\r
46 NULL, // 0x07 - reserved\r
47 NULL, // 0x08 - reserved\r
48 NULL, // 0x09 - reserved\r
49 NULL, // 0x0A - reserved\r
50 NULL, // 0x0B - reserved\r
51 NULL, // 0x0C - reserved\r
52 NULL, // 0x0D - reserved\r
53 NULL, // 0x0E - reserved\r
54 NULL, // 0x0F - reserved\r
55 "EFI_SECTION_PE32", // 0x10\r
56 "EFI_SECTION_PIC", // 0x11\r
57 "EFI_SECTION_TE", // 0x12\r
58 "EFI_SECTION_DXE_DEPEX", // 0x13\r
59 "EFI_SECTION_VERSION", // 0x14\r
60 "EFI_SECTION_USER_INTERFACE", // 0x15\r
61 "EFI_SECTION_COMPATIBILITY16", // 0x16\r
62 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17\r
63 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18\r
64 "EFI_SECTION_RAW", // 0x19\r
65 NULL, // 0x1A\r
66 "EFI_SECTION_PEI_DEPEX", // 0x1B\r
67 "EFI_SECTION_SMM_DEPEX" // 0x1C\r
68};\r
69\r
70STATIC CHAR8 *mCompressionTypeName[] = { "PI_NONE", "PI_STD" };\r
71\r
72#define EFI_GUIDED_SECTION_NONE 0x80\r
73STATIC CHAR8 *mGUIDedSectionAttribue[] = { "NONE", "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};\r
74\r
52302d4d
LG
75STATIC CHAR8 *mAlignName[] = {\r
76 "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",\r
e921f58d
YZ
77 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",\r
78 "512K", "1M", "2M", "4M", "8M", "16M"\r
52302d4d
LG
79};\r
80\r
30fdf114
LG
81//\r
82// Crc32 GUID section related definitions.\r
83//\r
84typedef struct {\r
85 EFI_GUID_DEFINED_SECTION GuidSectionHeader;\r
86 UINT32 CRC32Checksum;\r
87} CRC32_SECTION_HEADER;\r
88\r
e8a47801
LG
89typedef struct {\r
90 EFI_GUID_DEFINED_SECTION2 GuidSectionHeader;\r
91 UINT32 CRC32Checksum;\r
92} CRC32_SECTION_HEADER2;\r
93\r
30fdf114
LG
94STATIC EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
95STATIC EFI_GUID mEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
96\r
97STATIC\r
98VOID \r
99Version (\r
100 VOID\r
101 )\r
102/*++\r
103\r
104Routine Description:\r
105\r
106 Print out version information for this utility.\r
107\r
108Arguments:\r
109\r
110 None\r
111 \r
112Returns:\r
113\r
114 None\r
115 \r
116--*/ \r
117{\r
b36d134f 118 fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
30fdf114
LG
119}\r
120\r
121STATIC\r
122VOID\r
123Usage (\r
124 VOID\r
125 )\r
126/*++\r
127\r
128Routine Description:\r
129\r
130 Print Help message.\r
131\r
132Arguments:\r
133\r
134 VOID\r
135\r
136Returns:\r
137\r
138 None\r
139\r
140--*/\r
141{\r
142 //\r
143 // Summary usage\r
144 //\r
145 fprintf (stdout, "\nUsage: %s [options] [input_file]\n\n", UTILITY_NAME);\r
146 \r
147 //\r
148 // Copyright declaration\r
149 // \r
67f3d099 150 fprintf (stdout, "Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.\n\n");\r
30fdf114
LG
151\r
152 //\r
153 // Details Option\r
154 //\r
155 fprintf (stdout, "Options:\n");\r
156 fprintf (stdout, " -o FileName, --outputfile FileName\n\\r
157 File is the SectionFile to be created.\n");\r
158 fprintf (stdout, " -s [SectionType], --sectiontype [SectionType]\n\\r
159 SectionType defined in PI spec is one type of\n\\r
160 EFI_SECTION_COMPRESSION, EFI_SECTION_GUID_DEFINED,\n\\r
161 EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE,\n\\r
162 EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16,\n\\r
163 EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION,\n\\r
164 EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW,\n\\r
165 EFI_SECTION_FREEFORM_SUBTYPE_GUID,\n\\r
fd171542 166 EFI_SECTION_PEI_DEPEX, EFI_SECTION_SMM_DEPEX.\n\\r
167 if -s option is not given, \n\\r
30fdf114
LG
168 EFI_SECTION_ALL is default section type.\n");\r
169 fprintf (stdout, " -c [Type], --compress [Type]\n\\r
170 Compress method type can be PI_NONE or PI_STD.\n\\r
171 if -c option is not given, PI_STD is default type.\n"); \r
172 fprintf (stdout, " -g GuidValue, --vendor GuidValue\n\\r
173 GuidValue is one specific vendor guid value.\n\\r
174 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
175 fprintf (stdout, " -l GuidHeaderLength, --HeaderLength GuidHeaderLength\n\\r
176 GuidHeaderLength is the size of header of guided data\n");\r
177 fprintf (stdout, " -r GuidAttr, --attributes GuidAttr\n\\r
178 GuidAttr is guid section atttributes, which may be\n\\r
179 PROCESSING_REQUIRED, AUTH_STATUS_VALID and NONE. \n\\r
180 if -r option is not given, default PROCESSING_REQUIRED\n");\r
181 fprintf (stdout, " -n String, --name String\n\\r
182 String is a NULL terminated string used in Ui section.\n");\r
183 fprintf (stdout, " -j Number, --buildnumber Number\n\\r
e8a47801 184 Number is an integer value between 0 and 65535\n\\r
30fdf114 185 used in Ver section.\n");\r
52302d4d
LG
186 fprintf (stdout, " --sectionalign SectionAlign\n\\r
187 SectionAlign points to section alignment, which support\n\\r
e921f58d 188 the alignment scope 1~16M. It is specified in same\n\\r
52302d4d 189 order that the section file is input.\n");\r
b37b108d
YZ
190 fprintf (stdout, " --dummy dummyfile\n\\r
191 compare dummpyfile with input_file to decide whether\n\\r
192 need to set PROCESSING_REQUIRED attribute.\n");\r
30fdf114
LG
193 fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
194 fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");\r
195 fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");\r
196 fprintf (stdout, " --version Show program's version number and exit.\n");\r
197 fprintf (stdout, " -h, --help Show this help message and exit.\n");\r
198}\r
199\r
200VOID\r
201Ascii2UnicodeString (\r
202 CHAR8 *String,\r
203 CHAR16 *UniString\r
204 )\r
205/*++\r
206\r
207Routine Description:\r
208\r
209 Write ascii string as unicode string format to FILE \r
210\r
211Arguments:\r
212\r
213 String - Pointer to string that is written to FILE.\r
214 UniString - Pointer to unicode string\r
215\r
216Returns:\r
217\r
218 NULL\r
219\r
220--*/\r
221{\r
222 while (*String != '\0') {\r
223 *(UniString++) = (CHAR16) *(String++);\r
224 }\r
225 //\r
226 // End the UniString with a NULL.\r
227 //\r
228 *UniString = '\0';\r
229} \r
230\r
231STATUS\r
232GenSectionCommonLeafSection (\r
233 CHAR8 **InputFileName,\r
234 UINT32 InputFileNum,\r
235 UINT8 SectionType,\r
236 UINT8 **OutFileBuffer\r
237 )\r
238/*++\r
239 \r
240Routine Description:\r
241 \r
242 Generate a leaf section of type other than EFI_SECTION_VERSION\r
243 and EFI_SECTION_USER_INTERFACE. Input file must be well formed.\r
244 The function won't validate the input file's contents. For\r
245 common leaf sections, the input file may be a binary file.\r
246 The utility will add section header to the file.\r
247 \r
248Arguments:\r
249 \r
250 InputFileName - Name of the input file.\r
251 \r
252 InputFileNum - Number of input files. Should be 1 for leaf section.\r
253\r
254 SectionType - A valid section type string\r
255\r
256 OutFileBuffer - Buffer pointer to Output file contents\r
257\r
258Returns:\r
259 \r
260 STATUS_ERROR - can't continue\r
261 STATUS_SUCCESS - successful return\r
262\r
263--*/\r
264{\r
265 UINT32 InputFileLength;\r
266 FILE *InFile;\r
267 UINT8 *Buffer;\r
268 UINT32 TotalLength;\r
e8a47801 269 UINT32 HeaderLength;\r
30fdf114
LG
270 EFI_COMMON_SECTION_HEADER *CommonSect;\r
271 STATUS Status;\r
272\r
273 if (InputFileNum > 1) {\r
99e55970 274 Error (NULL, 0, 2000, "Invalid parameter", "more than one input file specified");\r
30fdf114
LG
275 return STATUS_ERROR;\r
276 } else if (InputFileNum < 1) {\r
99e55970 277 Error (NULL, 0, 2000, "Invalid parameter", "no input file specified");\r
30fdf114
LG
278 return STATUS_ERROR;\r
279 }\r
280 //\r
281 // Open the input file\r
282 //\r
1be2ed90 283 InFile = fopen (LongFilePath (InputFileName[0]), "rb");\r
30fdf114
LG
284 if (InFile == NULL) {\r
285 Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
286 return STATUS_ERROR;\r
287 }\r
288\r
289 Status = STATUS_ERROR;\r
290 Buffer = NULL;\r
291 //\r
292 // Seek to the end of the input file so we can determine its size\r
293 //\r
294 fseek (InFile, 0, SEEK_END);\r
295 InputFileLength = ftell (InFile);\r
296 fseek (InFile, 0, SEEK_SET);\r
fd171542 297 DebugMsg (NULL, 0, 9, "Input file", "File name is %s and File size is %u bytes", InputFileName[0], (unsigned) InputFileLength);\r
30fdf114
LG
298 TotalLength = sizeof (EFI_COMMON_SECTION_HEADER) + InputFileLength;\r
299 //\r
300 // Size must fit in 3 bytes\r
301 //\r
e8a47801 302 //if (TotalLength >= MAX_SECTION_SIZE) {\r
99e55970 303 // Error (NULL, 0, 2000, "Invalid parameter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);\r
e8a47801
LG
304 // goto Done;\r
305 //}\r
306 HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER);\r
30fdf114 307 if (TotalLength >= MAX_SECTION_SIZE) {\r
e8a47801
LG
308 TotalLength = sizeof (EFI_COMMON_SECTION_HEADER2) + InputFileLength;\r
309 HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER2);\r
30fdf114 310 }\r
fd171542 311 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
30fdf114
LG
312 //\r
313 // Fill in the fields in the local section header structure\r
314 //\r
315 Buffer = (UINT8 *) malloc ((size_t) TotalLength);\r
316 if (Buffer == NULL) {\r
317 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); \r
318 goto Done;\r
319 }\r
320 CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;\r
321 CommonSect->Type = SectionType;\r
e8a47801
LG
322 if (TotalLength < MAX_SECTION_SIZE) {\r
323 CommonSect->Size[0] = (UINT8) (TotalLength & 0xff);\r
324 CommonSect->Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
325 CommonSect->Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
326 } else {\r
327 memset(CommonSect->Size, 0xff, sizeof(UINT8) * 3);\r
328 ((EFI_COMMON_SECTION_HEADER2 *)CommonSect)->ExtendedSize = TotalLength;\r
329 }\r
30fdf114
LG
330 \r
331 //\r
332 // read data from the input file.\r
333 //\r
334 if (InputFileLength != 0) {\r
e8a47801 335 if (fread (Buffer + HeaderLength, (size_t) InputFileLength, 1, InFile) != 1) {\r
30fdf114
LG
336 Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);\r
337 goto Done;\r
338 }\r
339 }\r
340\r
341 //\r
342 // Set OutFileBuffer \r
343 //\r
344 *OutFileBuffer = Buffer;\r
345 Status = STATUS_SUCCESS;\r
346\r
347Done:\r
348 fclose (InFile);\r
349\r
350 return Status;\r
351}\r
352\r
52302d4d
LG
353STATIC\r
354EFI_STATUS\r
355StringtoAlignment (\r
356 IN CHAR8 *AlignBuffer,\r
357 OUT UINT32 *AlignNumber\r
358 )\r
359/*++\r
360\r
361Routine Description:\r
362\r
e921f58d 363 Converts Align String to align value (1~16M).\r
52302d4d
LG
364\r
365Arguments:\r
366\r
367 AlignBuffer - Pointer to Align string.\r
368 AlignNumber - Pointer to Align value.\r
369\r
370Returns:\r
371\r
372 EFI_SUCCESS Successfully convert align string to align value.\r
373 EFI_INVALID_PARAMETER Align string is invalid or align value is not in scope.\r
374\r
375--*/\r
376{\r
377 UINT32 Index = 0;\r
378 //\r
379 // Check AlignBuffer\r
380 //\r
381 if (AlignBuffer == NULL) {\r
382 return EFI_INVALID_PARAMETER;\r
383 }\r
384 for (Index = 0; Index < sizeof (mAlignName) / sizeof (CHAR8 *); Index ++) {\r
385 if (stricmp (AlignBuffer, mAlignName [Index]) == 0) {\r
386 *AlignNumber = 1 << Index;\r
387 return EFI_SUCCESS;\r
388 }\r
389 }\r
390 return EFI_INVALID_PARAMETER;\r
391}\r
392\r
30fdf114
LG
393EFI_STATUS\r
394GetSectionContents (\r
395 CHAR8 **InputFileName,\r
52302d4d 396 UINT32 *InputFileAlign,\r
30fdf114
LG
397 UINT32 InputFileNum,\r
398 UINT8 *FileBuffer,\r
399 UINT32 *BufferLength\r
400 )\r
401/*++\r
402 \r
403Routine Description:\r
404 \r
405 Get the contents of all section files specified in InputFileName\r
406 into FileBuffer.\r
407 \r
408Arguments:\r
409 \r
410 InputFileName - Name of the input file.\r
52302d4d
LG
411\r
412 InputFileAlign - Alignment required by the input file data.\r
413\r
30fdf114
LG
414 InputFileNum - Number of input files. Should be at least 1.\r
415\r
416 FileBuffer - Output buffer to contain data\r
417\r
418 BufferLength - On input, this is size of the FileBuffer. \r
419 On output, this is the actual length of the data.\r
420\r
421Returns:\r
422 \r
423 EFI_SUCCESS on successful return\r
424 EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.\r
425 EFI_ABORTED if unable to open input file.\r
426 EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.\r
427--*/\r
428{\r
52302d4d
LG
429 UINT32 Size;\r
430 UINT32 Offset;\r
431 UINT32 FileSize;\r
432 UINT32 Index;\r
433 FILE *InFile;\r
434 EFI_COMMON_SECTION_HEADER *SectHeader;\r
e8a47801 435 EFI_COMMON_SECTION_HEADER2 TempSectHeader;\r
52302d4d
LG
436 EFI_TE_IMAGE_HEADER TeHeader;\r
437 UINT32 TeOffset;\r
438 EFI_GUID_DEFINED_SECTION GuidSectHeader;\r
e8a47801 439 EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;\r
52302d4d 440 UINT32 HeaderSize;\r
30fdf114
LG
441\r
442 if (InputFileNum < 1) {\r
99e55970 443 Error (NULL, 0, 2000, "Invalid parameter", "must specify at least one input file");\r
30fdf114
LG
444 return EFI_INVALID_PARAMETER;\r
445 }\r
446\r
447 if (BufferLength == NULL) {\r
99e55970 448 Error (NULL, 0, 2000, "Invalid parameter", "BufferLength can't be NULL");\r
30fdf114
LG
449 return EFI_INVALID_PARAMETER;\r
450 }\r
451\r
52302d4d
LG
452 Size = 0;\r
453 Offset = 0;\r
454 TeOffset = 0;\r
30fdf114
LG
455 //\r
456 // Go through our array of file names and copy their contents\r
457 // to the output buffer.\r
458 //\r
459 for (Index = 0; Index < InputFileNum; Index++) {\r
460 //\r
461 // make sure section ends on a DWORD boundary\r
462 //\r
463 while ((Size & 0x03) != 0) {\r
464 if (FileBuffer != NULL && Size < *BufferLength) {\r
465 FileBuffer[Size] = 0;\r
466 }\r
467 Size++;\r
468 }\r
469 \r
470 // \r
471 // Open file and read contents\r
472 //\r
1be2ed90 473 InFile = fopen (LongFilePath (InputFileName[Index]), "rb");\r
30fdf114
LG
474 if (InFile == NULL) {\r
475 Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);\r
476 return EFI_ABORTED;\r
477 }\r
478\r
479 fseek (InFile, 0, SEEK_END);\r
480 FileSize = ftell (InFile);\r
481 fseek (InFile, 0, SEEK_SET);\r
fd171542 482 DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); \r
52302d4d
LG
483 //\r
484 // Adjust section buffer when section alignment is required.\r
485 //\r
486 if (InputFileAlign != NULL) {\r
487 //\r
488 // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.\r
489 //\r
490 TeOffset = 0;\r
e8a47801
LG
491 //\r
492 // The section might be EFI_COMMON_SECTION_HEADER2\r
493 // But only Type needs to be checked\r
494 //\r
495 if (FileSize >= MAX_SECTION_SIZE) {\r
496 HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);\r
497 } else {\r
498 HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
499 }\r
500 fread (&TempSectHeader, 1, HeaderSize, InFile);\r
52302d4d
LG
501 if (TempSectHeader.Type == EFI_SECTION_TE) {\r
502 fread (&TeHeader, 1, sizeof (TeHeader), InFile);\r
503 if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
504 TeOffset = TeHeader.StrippedSize - sizeof (TeHeader);\r
505 }\r
506 } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {\r
507 fseek (InFile, 0, SEEK_SET);\r
e8a47801
LG
508 if (FileSize >= MAX_SECTION_SIZE) {\r
509 fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);\r
510 if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
511 HeaderSize = GuidSectHeader2.DataOffset;\r
512 }\r
513 } else {\r
514 fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);\r
515 if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
516 HeaderSize = GuidSectHeader.DataOffset;\r
517 }\r
52302d4d
LG
518 }\r
519 } \r
520\r
521 fseek (InFile, 0, SEEK_SET);\r
522\r
523 //\r
524 // Revert TeOffset to the converse value relative to Alignment\r
525 // This is to assure the original PeImage Header at Alignment.\r
526 //\r
527 if (TeOffset != 0) {\r
528 TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);\r
529 TeOffset = TeOffset % InputFileAlign [Index];\r
530 }\r
531\r
532 //\r
533 // make sure section data meet its alignment requirement by adding one raw pad section.\r
534 //\r
535 if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {\r
536 Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
537 Offset = Offset - Size - HeaderSize - TeOffset;\r
538 \r
539 if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
e8a47801
LG
540 //\r
541 // The maximal alignment is 64K, the raw section size must be less than 0xffffff\r
542 //\r
52302d4d
LG
543 memset (FileBuffer + Size, 0, Offset);\r
544 SectHeader = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);\r
545 SectHeader->Type = EFI_SECTION_RAW;\r
546 SectHeader->Size[0] = (UINT8) (Offset & 0xff);\r
547 SectHeader->Size[1] = (UINT8) ((Offset & 0xff00) >> 8);\r
548 SectHeader->Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);\r
549 }\r
550 DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment", "Pad Raw section size is %u", (unsigned) Offset);\r
551\r
552 Size = Size + Offset;\r
553 }\r
554 }\r
555\r
30fdf114
LG
556 //\r
557 // Now read the contents of the file into the buffer\r
558 // Buffer must be enough to contain the file content.\r
559 //\r
52302d4d 560 if ((FileSize > 0) && (FileBuffer != NULL) && ((Size + FileSize) <= *BufferLength)) {\r
30fdf114
LG
561 if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {\r
562 Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);\r
563 fclose (InFile);\r
564 return EFI_ABORTED;\r
565 }\r
566 }\r
567\r
568 fclose (InFile);\r
569 Size += FileSize;\r
570 }\r
571 \r
572 //\r
573 // Set the real required buffer size.\r
574 //\r
575 if (Size > *BufferLength) {\r
576 *BufferLength = Size;\r
577 return EFI_BUFFER_TOO_SMALL;\r
578 } else {\r
579 *BufferLength = Size;\r
580 return EFI_SUCCESS;\r
581 }\r
582}\r
583\r
584EFI_STATUS\r
585GenSectionCompressionSection (\r
586 CHAR8 **InputFileName,\r
52302d4d 587 UINT32 *InputFileAlign,\r
30fdf114
LG
588 UINT32 InputFileNum,\r
589 UINT8 SectCompSubType,\r
590 UINT8 **OutFileBuffer\r
591 )\r
592/*++\r
593 \r
594Routine Description:\r
595 \r
596 Generate an encapsulating section of type EFI_SECTION_COMPRESSION\r
597 Input file must be already sectioned. The function won't validate\r
598 the input files' contents. Caller should hand in files already \r
599 with section header.\r
600 \r
601Arguments:\r
602 \r
603 InputFileName - Name of the input file.\r
52302d4d
LG
604\r
605 InputFileAlign - Alignment required by the input file data.\r
606\r
30fdf114
LG
607 InputFileNum - Number of input files. Should be at least 1.\r
608\r
609 SectCompSubType - Specify the compression algorithm requested. \r
610 \r
611 OutFileBuffer - Buffer pointer to Output file contents\r
612\r
613Returns:\r
614 \r
615 EFI_SUCCESS on successful return\r
616 EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
617 EFI_ABORTED if unable to open input file.\r
618 EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
619--*/\r
620{\r
621 UINT32 TotalLength;\r
622 UINT32 InputLength;\r
623 UINT32 CompressedLength;\r
e8a47801 624 UINT32 HeaderLength;\r
30fdf114
LG
625 UINT8 *FileBuffer;\r
626 UINT8 *OutputBuffer;\r
627 EFI_STATUS Status;\r
628 EFI_COMPRESSION_SECTION *CompressionSect;\r
e8a47801 629 EFI_COMPRESSION_SECTION2 *CompressionSect2;\r
30fdf114
LG
630 COMPRESS_FUNCTION CompressFunction;\r
631\r
632 InputLength = 0;\r
633 FileBuffer = NULL;\r
634 OutputBuffer = NULL;\r
635 CompressedLength = 0;\r
e8a47801 636 TotalLength = 0;\r
30fdf114
LG
637 //\r
638 // read all input file contents into a buffer\r
639 // first get the size of all file contents\r
640 //\r
641 Status = GetSectionContents (\r
642 InputFileName,\r
52302d4d 643 InputFileAlign,\r
30fdf114
LG
644 InputFileNum,\r
645 FileBuffer,\r
646 &InputLength\r
647 );\r
648\r
649 if (Status == EFI_BUFFER_TOO_SMALL) {\r
650 FileBuffer = (UINT8 *) malloc (InputLength);\r
651 if (FileBuffer == NULL) {\r
652 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
653 return EFI_OUT_OF_RESOURCES;\r
654 }\r
655 //\r
656 // read all input file contents into a buffer\r
657 //\r
658 Status = GetSectionContents (\r
659 InputFileName,\r
52302d4d 660 InputFileAlign,\r
30fdf114
LG
661 InputFileNum,\r
662 FileBuffer,\r
663 &InputLength\r
664 );\r
665 }\r
666\r
667 if (EFI_ERROR (Status)) {\r
668 if (FileBuffer != NULL) {\r
669 free (FileBuffer);\r
670 }\r
671 return Status;\r
672 }\r
673\r
248fce03
HW
674 if (FileBuffer == NULL) {\r
675 return EFI_OUT_OF_RESOURCES;\r
676 }\r
677\r
30fdf114
LG
678 CompressFunction = NULL;\r
679\r
680 //\r
681 // Now data is in FileBuffer, compress the data\r
682 //\r
683 switch (SectCompSubType) {\r
684 case EFI_NOT_COMPRESSED:\r
685 CompressedLength = InputLength;\r
e8a47801
LG
686 HeaderLength = sizeof (EFI_COMPRESSION_SECTION);\r
687 if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {\r
688 HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);\r
689 }\r
690 TotalLength = CompressedLength + HeaderLength;\r
52302d4d
LG
691 //\r
692 // Copy file buffer to the none compressed data.\r
693 //\r
e8a47801 694 OutputBuffer = malloc (TotalLength);\r
52302d4d
LG
695 if (OutputBuffer == NULL) {\r
696 free (FileBuffer);\r
697 return EFI_OUT_OF_RESOURCES;\r
698 }\r
e8a47801
LG
699 memcpy (OutputBuffer + HeaderLength, FileBuffer, CompressedLength);\r
700 free (FileBuffer);\r
52302d4d 701 FileBuffer = OutputBuffer;\r
30fdf114
LG
702 break;\r
703\r
704 case EFI_STANDARD_COMPRESSION:\r
705 CompressFunction = (COMPRESS_FUNCTION) EfiCompress;\r
706 break;\r
707\r
708 default:\r
99e55970 709 Error (NULL, 0, 2000, "Invalid parameter", "unknown compression type");\r
30fdf114
LG
710 free (FileBuffer);\r
711 return EFI_ABORTED;\r
712 }\r
713\r
714 if (CompressFunction != NULL) {\r
715\r
716 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
717 if (Status == EFI_BUFFER_TOO_SMALL) {\r
e8a47801
LG
718 HeaderLength = sizeof (EFI_COMPRESSION_SECTION);\r
719 if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {\r
720 HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);\r
721 }\r
722 TotalLength = CompressedLength + HeaderLength;\r
723 OutputBuffer = malloc (TotalLength);\r
30fdf114
LG
724 if (!OutputBuffer) {\r
725 free (FileBuffer);\r
726 return EFI_OUT_OF_RESOURCES;\r
727 }\r
728\r
e8a47801 729 Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + HeaderLength, &CompressedLength);\r
30fdf114
LG
730 }\r
731\r
732 free (FileBuffer);\r
733 FileBuffer = OutputBuffer;\r
734\r
735 if (EFI_ERROR (Status)) {\r
736 if (FileBuffer != NULL) {\r
737 free (FileBuffer);\r
738 }\r
739\r
740 return Status;\r
741 }\r
248fce03
HW
742\r
743 if (FileBuffer == NULL) {\r
744 return EFI_OUT_OF_RESOURCES;\r
745 }\r
30fdf114
LG
746 }\r
747\r
748 DebugMsg (NULL, 0, 9, "comprss file size", \r
fd171542 749 "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);\r
e8a47801
LG
750\r
751 //if (TotalLength >= MAX_SECTION_SIZE) {\r
99e55970 752 // Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
e8a47801
LG
753 // if (FileBuffer != NULL) {\r
754 // free (FileBuffer);\r
755 // }\r
756 // if (OutputBuffer != NULL) {\r
757 // free (OutputBuffer);\r
758 // }\r
759 // return STATUS_ERROR;\r
760 //}\r
fd171542 761 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
30fdf114
LG
762\r
763 //\r
764 // Add the section header for the compressed data\r
765 //\r
e8a47801
LG
766 if (TotalLength >= MAX_SECTION_SIZE) {\r
767 CompressionSect2 = (EFI_COMPRESSION_SECTION2 *)FileBuffer;\r
768\r
769 memset(CompressionSect2->CommonHeader.Size, 0xff, sizeof(UINT8) * 3);\r
770 CompressionSect2->CommonHeader.Type = EFI_SECTION_COMPRESSION;\r
771 CompressionSect2->CommonHeader.ExtendedSize = TotalLength;\r
772 CompressionSect2->CompressionType = SectCompSubType;\r
773 CompressionSect2->UncompressedLength = InputLength;\r
774 } else {\r
775 CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
776 \r
777 CompressionSect->CommonHeader.Type = EFI_SECTION_COMPRESSION;\r
778 CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
779 CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
780 CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
781 CompressionSect->CompressionType = SectCompSubType;\r
782 CompressionSect->UncompressedLength = InputLength;\r
783 }\r
30fdf114
LG
784\r
785 //\r
786 // Set OutFileBuffer \r
787 //\r
788 *OutFileBuffer = FileBuffer;\r
789\r
790 return EFI_SUCCESS;\r
791}\r
792\r
793EFI_STATUS\r
794GenSectionGuidDefinedSection (\r
795 CHAR8 **InputFileName,\r
52302d4d 796 UINT32 *InputFileAlign,\r
30fdf114
LG
797 UINT32 InputFileNum,\r
798 EFI_GUID *VendorGuid,\r
799 UINT16 DataAttribute,\r
800 UINT32 DataHeaderSize,\r
801 UINT8 **OutFileBuffer\r
802 )\r
803/*++\r
804 \r
805Routine Description:\r
806 \r
807 Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED\r
808 Input file must be already sectioned. The function won't validate\r
809 the input files' contents. Caller should hand in files already \r
810 with section header.\r
811 \r
812Arguments:\r
813 \r
814 InputFileName - Name of the input file.\r
815 \r
52302d4d
LG
816 InputFileAlign - Alignment required by the input file data.\r
817\r
30fdf114
LG
818 InputFileNum - Number of input files. Should be at least 1.\r
819\r
820 VendorGuid - Specify vendor guid value.\r
821\r
822 DataAttribute - Specify attribute for the vendor guid data. \r
823 \r
824 DataHeaderSize- Guided Data Header Size\r
825 \r
826 OutFileBuffer - Buffer pointer to Output file contents\r
827\r
828Returns:\r
829 \r
830 EFI_SUCCESS on successful return\r
831 EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
832 EFI_ABORTED if unable to open input file.\r
833 EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
834\r
835--*/\r
836{\r
837 UINT32 TotalLength;\r
838 UINT32 InputLength;\r
839 UINT32 Offset;\r
840 UINT8 *FileBuffer;\r
841 UINT32 Crc32Checksum;\r
842 EFI_STATUS Status;\r
843 CRC32_SECTION_HEADER *Crc32GuidSect;\r
e8a47801 844 CRC32_SECTION_HEADER2 *Crc32GuidSect2;\r
30fdf114 845 EFI_GUID_DEFINED_SECTION *VendorGuidSect;\r
e8a47801 846 EFI_GUID_DEFINED_SECTION2 *VendorGuidSect2;\r
30fdf114
LG
847\r
848 InputLength = 0;\r
849 Offset = 0;\r
850 FileBuffer = NULL;\r
e8a47801 851 TotalLength = 0;\r
30fdf114
LG
852\r
853 //\r
854 // read all input file contents into a buffer\r
855 // first get the size of all file contents\r
856 //\r
857 Status = GetSectionContents (\r
858 InputFileName,\r
52302d4d 859 InputFileAlign,\r
30fdf114
LG
860 InputFileNum,\r
861 FileBuffer,\r
862 &InputLength\r
863 );\r
864\r
865 if (Status == EFI_BUFFER_TOO_SMALL) {\r
e8a47801
LG
866 if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {\r
867 Offset = sizeof (CRC32_SECTION_HEADER);\r
868 if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
869 Offset = sizeof (CRC32_SECTION_HEADER2);\r
870 }\r
871 } else {\r
872 Offset = sizeof (EFI_GUID_DEFINED_SECTION);\r
873 if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
874 Offset = sizeof (EFI_GUID_DEFINED_SECTION2);\r
875 }\r
876 }\r
877 TotalLength = InputLength + Offset;\r
878\r
30fdf114
LG
879 FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
880 if (FileBuffer == NULL) {\r
881 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
882 return EFI_OUT_OF_RESOURCES;\r
883 }\r
884 //\r
885 // read all input file contents into a buffer\r
886 //\r
887 Status = GetSectionContents (\r
888 InputFileName,\r
52302d4d 889 InputFileAlign,\r
30fdf114
LG
890 InputFileNum,\r
891 FileBuffer + Offset,\r
892 &InputLength\r
893 );\r
894 }\r
895\r
896 if (EFI_ERROR (Status)) {\r
897 if (FileBuffer != NULL) {\r
898 free (FileBuffer);\r
899 }\r
900 Error (NULL, 0, 0001, "Error opening file for reading", InputFileName[0]);\r
901 return Status;\r
902 }\r
903\r
904 if (InputLength == 0) {\r
c52f00d6
HW
905 if (FileBuffer != NULL) {\r
906 free (FileBuffer);\r
907 }\r
30fdf114
LG
908 Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
909 return EFI_NOT_FOUND;\r
910 }\r
911\r
c52f00d6
HW
912 //\r
913 // InputLength != 0, but FileBuffer == NULL means out of resources.\r
914 //\r
915 if (FileBuffer == NULL) {\r
916 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
917 return EFI_OUT_OF_RESOURCES;\r
918 }\r
919\r
30fdf114
LG
920 //\r
921 // Now data is in FileBuffer + Offset\r
922 //\r
25918452 923 if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {\r
30fdf114
LG
924 //\r
925 // Default Guid section is CRC32.\r
926 //\r
927 Crc32Checksum = 0;\r
928 CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);\r
e8a47801 929 \r
30fdf114 930 if (TotalLength >= MAX_SECTION_SIZE) {\r
e8a47801
LG
931 Crc32GuidSect2 = (CRC32_SECTION_HEADER2 *) FileBuffer;\r
932 Crc32GuidSect2->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
933 Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) 0xff;\r
934 Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) 0xff;\r
935 Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) 0xff;\r
936 Crc32GuidSect2->GuidSectionHeader.CommonHeader.ExtendedSize = TotalLength;\r
937 memcpy (&(Crc32GuidSect2->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
938 Crc32GuidSect2->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
939 Crc32GuidSect2->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER2);\r
940 Crc32GuidSect2->CRC32Checksum = Crc32Checksum;\r
941 DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2->GuidSectionHeader.DataOffset);\r
942 } else {\r
943 Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;\r
944 Crc32GuidSect->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
945 Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
946 Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
947 Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
948 memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
949 Crc32GuidSect->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
950 Crc32GuidSect->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);\r
951 Crc32GuidSect->CRC32Checksum = Crc32Checksum;\r
952 DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
30fdf114 953 }\r
30fdf114 954 } else {\r
30fdf114 955 if (TotalLength >= MAX_SECTION_SIZE) {\r
e8a47801
LG
956 VendorGuidSect2 = (EFI_GUID_DEFINED_SECTION2 *) FileBuffer;\r
957 VendorGuidSect2->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
958 VendorGuidSect2->CommonHeader.Size[0] = (UINT8) 0xff;\r
959 VendorGuidSect2->CommonHeader.Size[1] = (UINT8) 0xff;\r
960 VendorGuidSect2->CommonHeader.Size[2] = (UINT8) 0xff;\r
961 VendorGuidSect2->CommonHeader.ExtendedSize = InputLength + sizeof (EFI_GUID_DEFINED_SECTION2);\r
962 memcpy (&(VendorGuidSect2->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
963 VendorGuidSect2->Attributes = DataAttribute;\r
964 VendorGuidSect2->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION2) + DataHeaderSize);\r
965 DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2->DataOffset);\r
966 } else {\r
967 VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;\r
968 VendorGuidSect->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
969 VendorGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
970 VendorGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
971 VendorGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
972 memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
973 VendorGuidSect->Attributes = DataAttribute;\r
974 VendorGuidSect->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);\r
975 DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);\r
30fdf114 976 }\r
30fdf114 977 }\r
fd171542 978 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
30fdf114
LG
979 \r
980 //\r
981 // Set OutFileBuffer \r
982 //\r
983 *OutFileBuffer = FileBuffer;\r
984\r
985 return EFI_SUCCESS;\r
986}\r
987\r
988int\r
989main (\r
990 int argc,\r
991 char *argv[]\r
992 )\r
993/*++\r
994\r
995Routine Description:\r
996\r
997 Main\r
998\r
999Arguments:\r
1000\r
1001 command line parameters\r
1002\r
1003Returns:\r
1004\r
1005 EFI_SUCCESS Section header successfully generated and section concatenated.\r
1006 EFI_ABORTED Could not generate the section\r
1007 EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
1008\r
1009--*/\r
1010{\r
1011 UINT32 Index;\r
1012 UINT32 InputFileNum;\r
30fdf114
LG
1013 FILE *OutFile;\r
1014 CHAR8 **InputFileName;\r
1015 CHAR8 *OutputFileName;\r
1016 CHAR8 *SectionName;\r
1017 CHAR8 *CompressionName;\r
1018 CHAR8 *StringBuffer;\r
1019 EFI_GUID VendorGuid = mZeroGuid;\r
fd171542 1020 int VersionNumber;\r
30fdf114
LG
1021 UINT8 SectType;\r
1022 UINT8 SectCompSubType;\r
1023 UINT16 SectGuidAttribute; \r
1024 UINT64 SectGuidHeaderLength;\r
1025 EFI_VERSION_SECTION *VersionSect;\r
1026 EFI_USER_INTERFACE_SECTION *UiSect;\r
1027 UINT32 InputLength;\r
1028 UINT8 *OutFileBuffer;\r
1029 EFI_STATUS Status;\r
1030 UINT64 LogLevel;\r
52302d4d
LG
1031 UINT32 *InputFileAlign;\r
1032 UINT32 InputFileAlignNum;\r
e8a47801 1033 EFI_COMMON_SECTION_HEADER *SectionHeader;\r
b37b108d
YZ
1034 CHAR8 *DummyFileName;\r
1035 FILE *DummyFile;\r
1036 UINTN DummyFileSize;\r
1037 UINT8 *DummyFileBuffer;\r
1038 FILE *InFile;\r
1039 UINT8 *InFileBuffer;\r
1040 UINTN InFileSize;\r
52302d4d
LG
1041\r
1042 InputFileAlign = NULL;\r
1043 InputFileAlignNum = 0;\r
30fdf114
LG
1044 InputFileName = NULL;\r
1045 OutputFileName = NULL;\r
1046 SectionName = NULL;\r
1047 CompressionName = NULL;\r
1048 StringBuffer = "";\r
30fdf114
LG
1049 OutFile = NULL;\r
1050 VersionNumber = 0;\r
1051 InputFileNum = 0;\r
1052 SectType = EFI_SECTION_ALL;\r
1053 SectCompSubType = 0;\r
52302d4d 1054 SectGuidAttribute = EFI_GUIDED_SECTION_NONE;\r
30fdf114
LG
1055 OutFileBuffer = NULL;\r
1056 InputLength = 0;\r
1057 Status = STATUS_SUCCESS;\r
1058 LogLevel = 0;\r
1059 SectGuidHeaderLength = 0;\r
1060 VersionSect = NULL;\r
1061 UiSect = NULL;\r
b37b108d
YZ
1062 DummyFileSize = 0;\r
1063 DummyFileName = NULL;\r
1064 DummyFile = NULL;\r
1065 DummyFileBuffer = NULL;\r
1066 InFile = NULL;\r
1067 InFileSize = 0;\r
1068 InFileBuffer = NULL;\r
30fdf114
LG
1069 \r
1070 SetUtilityName (UTILITY_NAME);\r
1071 \r
1072 if (argc == 1) {\r
1073 Error (NULL, 0, 1001, "Missing options", "No options input");\r
1074 Usage ();\r
1075 return STATUS_ERROR;\r
1076 }\r
1077\r
1078 //\r
1079 // Parse command line\r
1080 //\r
1081 argc --;\r
1082 argv ++;\r
1083\r
1084 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
1085 Version ();\r
1086 Usage ();\r
1087 return STATUS_SUCCESS; \r
1088 }\r
1089\r
1090 if (stricmp (argv[0], "--version") == 0) {\r
1091 Version ();\r
1092 return STATUS_SUCCESS; \r
1093 }\r
1094\r
1095 while (argc > 0) {\r
1096 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--SectionType") == 0)) {\r
1097 SectionName = argv[1];\r
1098 if (SectionName == NULL) {\r
1099 Error (NULL, 0, 1003, "Invalid option value", "Section Type can't be NULL");\r
1100 goto Finish;\r
1101 }\r
1102 argc -= 2;\r
1103 argv += 2;\r
1104 continue; \r
1105 }\r
1106\r
1107 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
1108 OutputFileName = argv[1];\r
1109 if (OutputFileName == NULL) {\r
1110 Error (NULL, 0, 1003, "Invalid option value", "Output file can't be NULL");\r
1111 goto Finish;\r
1112 }\r
1113 argc -= 2;\r
1114 argv += 2;\r
1115 continue; \r
1116 }\r
1117\r
1118 if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--compress") == 0)) {\r
1119 CompressionName = argv[1];\r
1120 if (CompressionName == NULL) {\r
1121 Error (NULL, 0, 1003, "Invalid option value", "Compression Type can't be NULL");\r
1122 goto Finish;\r
1123 }\r
1124 argc -= 2;\r
1125 argv += 2;\r
1126 continue;\r
1127 }\r
1128\r
1129 if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--vendor") == 0)) {\r
1130 Status = StringToGuid (argv[1], &VendorGuid);\r
1131 if (EFI_ERROR (Status)) {\r
1132 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1133 goto Finish;\r
1134 }\r
1135 argc -= 2;\r
1136 argv += 2;\r
1137 continue;\r
1138 }\r
b37b108d
YZ
1139 if (stricmp (argv[0], "--dummy") == 0) {\r
1140 DummyFileName = argv[1];\r
1141 if (DummyFileName == NULL) {\r
1142 Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");\r
1143 goto Finish;\r
1144 }\r
1145 argc -= 2;\r
1146 argv += 2;\r
1147 continue;\r
1148 }\r
30fdf114
LG
1149\r
1150 if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {\r
67f3d099
YZ
1151 if (argv[1] == NULL) {\r
1152 Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");\r
1153 goto Finish;\r
1154 }\r
30fdf114
LG
1155 if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
1156 SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
1157 } else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
1158 SectGuidAttribute |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
1159 } else if (stricmp (argv[1], mGUIDedSectionAttribue[0]) == 0) {\r
1160 //\r
1161 // NONE attribute\r
1162 //\r
1163 SectGuidAttribute |= EFI_GUIDED_SECTION_NONE;\r
1164 } else {\r
1165 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1166 goto Finish;\r
1167 }\r
1168 argc -= 2;\r
1169 argv += 2;\r
1170 continue;\r
1171 }\r
1172\r
1173 if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--HeaderLength") == 0)) {\r
1174 Status = AsciiStringToUint64 (argv[1], FALSE, &SectGuidHeaderLength);\r
1175 if (EFI_ERROR (Status)) {\r
1176 Error (NULL, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv[0], argv[1]);\r
1177 goto Finish;\r
1178 }\r
1179 argc -= 2;\r
1180 argv += 2;\r
1181 continue;\r
1182 }\r
1183\r
1184 if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--name") == 0)) {\r
1185 StringBuffer = argv[1];\r
1186 if (StringBuffer == NULL) {\r
1187 Error (NULL, 0, 1003, "Invalid option value", "Name can't be NULL");\r
1188 goto Finish;\r
1189 }\r
1190 argc -= 2;\r
1191 argv += 2;\r
1192 continue;\r
1193 }\r
1194\r
1195 if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--buildnumber") == 0)) {\r
1196 if (argv[1] == NULL) {\r
1197 Error (NULL, 0, 1003, "Invalid option value", "build number can't be NULL");\r
1198 goto Finish;\r
1199 }\r
1200 //\r
1201 // Verify string is a integrator number\r
1202 //\r
1203 for (Index = 0; Index < strlen (argv[1]); Index++) {\r
a709adfa 1204 if ((argv[1][Index] != '-') && (isdigit ((int)argv[1][Index]) == 0)) {\r
30fdf114
LG
1205 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1206 goto Finish;\r
1207 }\r
1208 }\r
1209\r
1210 sscanf (argv[1], "%d", &VersionNumber);\r
1211 argc -= 2;\r
1212 argv += 2;\r
1213 continue;\r
1214 }\r
1215\r
1216 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
1217 SetPrintLevel (VERBOSE_LOG_LEVEL);\r
1218 VerboseMsg ("Verbose output Mode Set!");\r
1219 argc --;\r
1220 argv ++;\r
1221 continue;\r
1222 }\r
1223\r
1224 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
1225 SetPrintLevel (KEY_LOG_LEVEL);\r
1226 KeyMsg ("Quiet output Mode Set!");\r
1227 argc --;\r
1228 argv ++;\r
1229 continue;\r
1230 }\r
1231\r
1232 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
1233 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
1234 if (EFI_ERROR (Status)) {\r
1235 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1236 goto Finish;\r
1237 }\r
1238 if (LogLevel > 9) {\r
fd171542 1239 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0~9, currnt input level is %d", (int) LogLevel);\r
30fdf114
LG
1240 goto Finish;\r
1241 }\r
1242 SetPrintLevel (LogLevel);\r
1243 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
1244 argc -= 2;\r
1245 argv += 2;\r
1246 continue;\r
1247 }\r
1248\r
52302d4d
LG
1249 //\r
1250 // Section File alignment requirement\r
1251 //\r
1252 if (stricmp (argv[0], "--sectionalign") == 0) {\r
1253 if (InputFileAlignNum == 0) {\r
1254 InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
1255 if (InputFileAlign == NULL) {\r
1256 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
77e4cf5f 1257 goto Finish;\r
52302d4d
LG
1258 }\r
1259 memset (InputFileAlign, 1, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
1260 } else if (InputFileAlignNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
1261 InputFileAlign = (UINT32 *) realloc (\r
1262 InputFileAlign,\r
1263 (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)\r
1264 );\r
1265\r
1266 if (InputFileAlign == NULL) {\r
1267 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
77e4cf5f 1268 goto Finish;\r
52302d4d
LG
1269 }\r
1270 memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));\r
1271 }\r
1272 \r
1273 Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
1274 if (EFI_ERROR (Status)) {\r
1275 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1276 goto Finish;\r
1277 }\r
1278 argc -= 2;\r
1279 argv += 2;\r
1280 InputFileAlignNum ++;\r
1281 continue; \r
1282 }\r
1283\r
30fdf114
LG
1284 //\r
1285 // Get Input file name\r
1286 //\r
1287 if ((InputFileNum == 0) && (InputFileName == NULL)) {\r
1288 InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
1289 if (InputFileName == NULL) {\r
1290 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
77e4cf5f 1291 goto Finish;\r
30fdf114 1292 }\r
30fdf114
LG
1293 memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
1294 } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
1295 //\r
1296 // InputFileName buffer too small, need to realloc\r
1297 //\r
1298 InputFileName = (CHAR8 **) realloc (\r
1299 InputFileName,\r
1300 (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
1301 );\r
1302\r
1303 if (InputFileName == NULL) {\r
1304 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
77e4cf5f 1305 goto Finish;\r
30fdf114 1306 }\r
30fdf114
LG
1307 memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
1308 }\r
1309\r
1310 InputFileName[InputFileNum++] = argv[0];\r
1311 argc --;\r
1312 argv ++;\r
1313 }\r
1314\r
52302d4d
LG
1315 if (InputFileAlignNum > 0 && InputFileAlignNum != InputFileNum) {\r
1316 Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");\r
1317 goto Finish;\r
1318 }\r
1319\r
30fdf114
LG
1320 VerboseMsg ("%s tool start.", UTILITY_NAME);\r
1321\r
b37b108d
YZ
1322 if (DummyFileName != NULL) {\r
1323 //\r
1324 // Open file and read contents\r
1325 //\r
1326 DummyFile = fopen (LongFilePath (DummyFileName), "rb");\r
1327 if (DummyFile == NULL) {\r
1328 Error (NULL, 0, 0001, "Error opening file", DummyFileName);\r
1e6e6e18 1329 goto Finish;\r
b37b108d
YZ
1330 }\r
1331\r
1332 fseek (DummyFile, 0, SEEK_END);\r
1333 DummyFileSize = ftell (DummyFile);\r
1334 fseek (DummyFile, 0, SEEK_SET);\r
1335 DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);\r
c40dbe5e
HW
1336 if (DummyFileBuffer == NULL) {\r
1337 fclose(DummyFile);\r
1338 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1339 goto Finish;\r
1340 }\r
1341\r
b37b108d
YZ
1342 fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);\r
1343 fclose(DummyFile);\r
1344 DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);\r
1345\r
c40dbe5e
HW
1346 if (InputFileName == NULL) {\r
1347 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1348 goto Finish;\r
1349 }\r
b37b108d
YZ
1350 InFile = fopen(LongFilePath(InputFileName[0]), "rb");\r
1351 if (InFile == NULL) {\r
1352 Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
1e6e6e18 1353 goto Finish;\r
b37b108d
YZ
1354 }\r
1355\r
1356 fseek (InFile, 0, SEEK_END);\r
1357 InFileSize = ftell (InFile);\r
1358 fseek (InFile, 0, SEEK_SET);\r
1359 InFileBuffer = (UINT8 *) malloc (InFileSize);\r
c40dbe5e
HW
1360 if (InFileBuffer == NULL) {\r
1361 fclose(InFile);\r
1362 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1363 goto Finish;\r
1364 }\r
1365\r
b37b108d
YZ
1366 fread(InFileBuffer, 1, InFileSize, InFile);\r
1367 fclose(InFile);\r
1368 DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);\r
1369 if (InFileSize > DummyFileSize){\r
1e6e6e18 1370 if (stricmp((CHAR8 *)DummyFileBuffer, (CHAR8 *)(InFileBuffer + (InFileSize - DummyFileSize))) == 0){\r
b37b108d
YZ
1371 SectGuidHeaderLength = InFileSize - DummyFileSize;\r
1372 }\r
1373 }\r
1374 if (SectGuidHeaderLength == 0) {\r
1375 SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
1376 }\r
1377 if (DummyFileBuffer != NULL) {\r
1378 free (DummyFileBuffer);\r
6ecab5ad 1379 DummyFileBuffer = NULL;\r
b37b108d
YZ
1380 }\r
1381 if (InFileBuffer != NULL) {\r
1382 free (InFileBuffer);\r
1383 }\r
1384 }\r
1385\r
30fdf114
LG
1386 //\r
1387 // Parse all command line parameters to get the corresponding section type.\r
1388 //\r
1389 VerboseMsg ("Section type is %s", SectionName);\r
1390 if (SectionName == NULL) {\r
1391 //\r
1392 // No specified Section type, default is SECTION_ALL.\r
1393 //\r
1394 SectType = EFI_SECTION_ALL;\r
1395 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {\r
1396 SectType = EFI_SECTION_COMPRESSION;\r
1397 if (CompressionName == NULL) {\r
1398 //\r
1399 // Default is PI_STD compression algorithm.\r
1400 //\r
1401 SectCompSubType = EFI_STANDARD_COMPRESSION;\r
1402 } else if (stricmp (CompressionName, mCompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {\r
1403 SectCompSubType = EFI_NOT_COMPRESSED;\r
1404 } else if (stricmp (CompressionName, mCompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {\r
1405 SectCompSubType = EFI_STANDARD_COMPRESSION;\r
1406 } else {\r
1407 Error (NULL, 0, 1003, "Invalid option value", "--compress = %s", CompressionName);\r
1408 goto Finish;\r
1409 }\r
1410 VerboseMsg ("Compress method is %s", mCompressionTypeName [SectCompSubType]);\r
1411 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
1412 SectType = EFI_SECTION_GUID_DEFINED;\r
30fdf114 1413 \r
30fdf114
LG
1414 if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {\r
1415 //\r
1416 // NONE attribute, clear attribute value.\r
1417 //\r
52302d4d 1418 SectGuidAttribute = SectGuidAttribute & ~EFI_GUIDED_SECTION_NONE;\r
30fdf114
LG
1419 }\r
1420 VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
fd171542 1421 (unsigned) VendorGuid.Data1,\r
30fdf114
LG
1422 VendorGuid.Data2,\r
1423 VendorGuid.Data3,\r
1424 VendorGuid.Data4[0],\r
1425 VendorGuid.Data4[1],\r
1426 VendorGuid.Data4[2],\r
1427 VendorGuid.Data4[3],\r
1428 VendorGuid.Data4[4],\r
1429 VendorGuid.Data4[5],\r
1430 VendorGuid.Data4[6],\r
1431 VendorGuid.Data4[7]);\r
1432 if ((SectGuidAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {\r
1433 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]);\r
1434 }\r
1435 if ((SectGuidAttribute & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) {\r
1436 VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]);\r
1437 }\r
1438 if (SectGuidHeaderLength != 0) {\r
fd171542 1439 VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength);\r
30fdf114
LG
1440 }\r
1441 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PE32]) == 0) {\r
1442 SectType = EFI_SECTION_PE32;\r
1443 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PIC]) == 0) {\r
1444 SectType = EFI_SECTION_PIC;\r
1445 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_TE]) == 0) {\r
1446 SectType = EFI_SECTION_TE;\r
1447 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {\r
1448 SectType = EFI_SECTION_DXE_DEPEX;\r
fd171542 1449 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_SMM_DEPEX]) == 0) {\r
1450 SectType = EFI_SECTION_SMM_DEPEX;\r
30fdf114
LG
1451 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_VERSION]) == 0) {\r
1452 SectType = EFI_SECTION_VERSION;\r
e8a47801
LG
1453 if (VersionNumber < 0 || VersionNumber > 65535) {\r
1454 Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber);\r
30fdf114
LG
1455 goto Finish;\r
1456 }\r
1457 VerboseMsg ("Version section number is %d", VersionNumber);\r
1458 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {\r
1459 SectType = EFI_SECTION_USER_INTERFACE;\r
1460 if (StringBuffer[0] == '\0') {\r
1461 Error (NULL, 0, 1001, "Missing option", "user interface string");\r
1462 goto Finish;\r
1463 }\r
1464 VerboseMsg ("UI section string name is %s", StringBuffer);\r
1465 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {\r
1466 SectType = EFI_SECTION_COMPATIBILITY16;\r
1467 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {\r
1468 SectType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
1469 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {\r
1470 SectType = EFI_SECTION_FREEFORM_SUBTYPE_GUID;\r
1471 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_RAW]) == 0) {\r
1472 SectType = EFI_SECTION_RAW;\r
1473 } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {\r
1474 SectType = EFI_SECTION_PEI_DEPEX;\r
1475 } else {\r
1476 Error (NULL, 0, 1003, "Invalid option value", "SectionType = %s", SectionName);\r
1477 goto Finish;\r
1478 }\r
1479 \r
1480 //\r
1481 // GuidValue is only required by Guided section.\r
1482 //\r
248fce03
HW
1483 if ((SectType != EFI_SECTION_GUID_DEFINED) &&\r
1484 (SectionName != NULL) &&\r
1485 (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
30fdf114
LG
1486 fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
1487 }\r
1488 \r
1489 //\r
1490 // Check whether there is input file\r
1491 // \r
1492 if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {\r
1493 //\r
1494 // The input file are required for other section type.\r
1495 //\r
1496 if (InputFileNum == 0) {\r
1497 Error (NULL, 0, 1001, "Missing options", "Input files");\r
1498 goto Finish;\r
1499 }\r
1500 }\r
1501 //\r
1502 // Check whether there is output file\r
1503 //\r
1504 for (Index = 0; Index < InputFileNum; Index ++) {\r
fd171542 1505 VerboseMsg ("the %uth input file name is %s", (unsigned) Index, InputFileName[Index]);\r
30fdf114
LG
1506 }\r
1507 if (OutputFileName == NULL) {\r
1508 Error (NULL, 0, 1001, "Missing options", "Output file");\r
1509 goto Finish;\r
1510 // OutFile = stdout;\r
1511 }\r
1512 VerboseMsg ("Output file name is %s", OutputFileName);\r
1513\r
1514 //\r
1515 // At this point, we've fully validated the command line, and opened appropriate\r
1516 // files, so let's go and do what we've been asked to do...\r
1517 //\r
1518 //\r
1519 // Within this switch, build and write out the section header including any\r
1520 // section type specific pieces. If there's an input file, it's tacked on later\r
1521 //\r
1522 switch (SectType) {\r
1523 case EFI_SECTION_COMPRESSION:\r
52302d4d
LG
1524 if (InputFileAlign != NULL) {\r
1525 free (InputFileAlign);\r
1526 InputFileAlign = NULL;\r
1527 }\r
30fdf114
LG
1528 Status = GenSectionCompressionSection (\r
1529 InputFileName,\r
52302d4d 1530 InputFileAlign,\r
30fdf114
LG
1531 InputFileNum,\r
1532 SectCompSubType,\r
1533 &OutFileBuffer\r
1534 );\r
1535 break;\r
1536\r
1537 case EFI_SECTION_GUID_DEFINED:\r
25918452 1538 if (InputFileAlign != NULL && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
52302d4d
LG
1539 //\r
1540 // Only process alignment for the default known CRC32 guided section.\r
1541 // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.\r
1542 //\r
1543 free (InputFileAlign);\r
1544 InputFileAlign = NULL;\r
1545 }\r
30fdf114
LG
1546 Status = GenSectionGuidDefinedSection (\r
1547 InputFileName,\r
52302d4d 1548 InputFileAlign,\r
30fdf114
LG
1549 InputFileNum,\r
1550 &VendorGuid,\r
1551 SectGuidAttribute,\r
1552 (UINT32) SectGuidHeaderLength,\r
1553 &OutFileBuffer\r
1554 );\r
1555 break;\r
1556\r
1557 case EFI_SECTION_VERSION:\r
1558 Index = sizeof (EFI_COMMON_SECTION_HEADER);\r
1559 //\r
1560 // 2 bytes for the build number UINT16\r
1561 //\r
1562 Index += 2;\r
1563 //\r
1564 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
1565 //\r
1566 Index += (strlen (StringBuffer) * 2) + 2;\r
1567 OutFileBuffer = (UINT8 *) malloc (Index);\r
1568 if (OutFileBuffer == NULL) {\r
1569 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1570 goto Finish;\r
1571 }\r
1572 VersionSect = (EFI_VERSION_SECTION *) OutFileBuffer;\r
1573 VersionSect->CommonHeader.Type = SectType;\r
1574 VersionSect->CommonHeader.Size[0] = (UINT8) (Index & 0xff);\r
1575 VersionSect->CommonHeader.Size[1] = (UINT8) ((Index & 0xff00) >> 8);\r
1576 VersionSect->CommonHeader.Size[2] = (UINT8) ((Index & 0xff0000) >> 16);\r
1577 VersionSect->BuildNumber = (UINT16) VersionNumber;\r
1578 Ascii2UnicodeString (StringBuffer, VersionSect->VersionString);\r
fd171542 1579 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);\r
30fdf114
LG
1580 break;\r
1581\r
1582 case EFI_SECTION_USER_INTERFACE:\r
1583 Index = sizeof (EFI_COMMON_SECTION_HEADER);\r
1584 //\r
1585 // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
1586 //\r
1587 Index += (strlen (StringBuffer) * 2) + 2;\r
1588 OutFileBuffer = (UINT8 *) malloc (Index);\r
1589 if (OutFileBuffer == NULL) {\r
1590 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1591 goto Finish;\r
1592 }\r
1593 UiSect = (EFI_USER_INTERFACE_SECTION *) OutFileBuffer;\r
1594 UiSect->CommonHeader.Type = SectType;\r
1595 UiSect->CommonHeader.Size[0] = (UINT8) (Index & 0xff);\r
1596 UiSect->CommonHeader.Size[1] = (UINT8) ((Index & 0xff00) >> 8);\r
1597 UiSect->CommonHeader.Size[2] = (UINT8) ((Index & 0xff0000) >> 16);\r
1598 Ascii2UnicodeString (StringBuffer, UiSect->FileNameString);\r
fd171542 1599 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);\r
30fdf114
LG
1600 break;\r
1601\r
1602 case EFI_SECTION_ALL:\r
1603 //\r
1604 // read all input file contents into a buffer\r
1605 // first get the size of all file contents\r
1606 //\r
1607 Status = GetSectionContents (\r
1608 InputFileName,\r
52302d4d 1609 InputFileAlign,\r
30fdf114
LG
1610 InputFileNum,\r
1611 OutFileBuffer,\r
1612 &InputLength\r
1613 );\r
1614 \r
1615 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1616 OutFileBuffer = (UINT8 *) malloc (InputLength);\r
1617 if (OutFileBuffer == NULL) {\r
1618 Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
1619 goto Finish;\r
1620 }\r
1621 //\r
1622 // read all input file contents into a buffer\r
1623 //\r
1624 Status = GetSectionContents (\r
1625 InputFileName,\r
52302d4d 1626 InputFileAlign,\r
30fdf114
LG
1627 InputFileNum,\r
1628 OutFileBuffer,\r
1629 &InputLength\r
1630 );\r
1631 }\r
fd171542 1632 VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength);\r
30fdf114
LG
1633 break;\r
1634 default:\r
1635 //\r
1636 // All other section types are caught by default (they're all the same)\r
1637 //\r
1638 Status = GenSectionCommonLeafSection (\r
1639 InputFileName,\r
1640 InputFileNum,\r
1641 SectType,\r
1642 &OutFileBuffer\r
1643 );\r
1644 break;\r
1645 }\r
1646 \r
1647 if (Status != EFI_SUCCESS || OutFileBuffer == NULL) {\r
fd171542 1648 Error (NULL, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status);\r
30fdf114
LG
1649 goto Finish;\r
1650 }\r
1651\r
1652 //\r
1653 // Get output file length\r
1654 //\r
1655 if (SectType != EFI_SECTION_ALL) {\r
e8a47801
LG
1656 SectionHeader = (EFI_COMMON_SECTION_HEADER *)OutFileBuffer;\r
1657 InputLength = *(UINT32 *)SectionHeader->Size & 0x00ffffff;\r
1658 if (InputLength == 0xffffff) {\r
1659 InputLength = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;\r
1660 }\r
30fdf114
LG
1661 }\r
1662 \r
1663 //\r
1664 // Write the output file\r
1665 //\r
1be2ed90 1666 OutFile = fopen (LongFilePath (OutputFileName), "wb");\r
30fdf114
LG
1667 if (OutFile == NULL) {\r
1668 Error (NULL, 0, 0001, "Error opening file for writing", OutputFileName);\r
1669 goto Finish;\r
1670 }\r
1671\r
1672 fwrite (OutFileBuffer, InputLength, 1, OutFile);\r
1673\r
1674Finish:\r
1675 if (InputFileName != NULL) {\r
1676 free (InputFileName);\r
1677 }\r
1678\r
52302d4d
LG
1679 if (InputFileAlign != NULL) {\r
1680 free (InputFileAlign);\r
1681 }\r
1682\r
30fdf114
LG
1683 if (OutFileBuffer != NULL) {\r
1684 free (OutFileBuffer);\r
1685 }\r
1686\r
1687 if (OutFile != NULL) {\r
1688 fclose (OutFile);\r
1689 }\r
ae0fbb7f
HW
1690\r
1691 if (DummyFileBuffer != NULL) {\r
1692 free (DummyFileBuffer);\r
1693 }\r
1694\r
30fdf114
LG
1695 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
1696\r
1697 return GetUtilityStatus ();\r
1698}\r