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