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