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