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