]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VolInfo/VolInfo.c
BaseTools/VolInfo: Update OPENSSL_PATH to support space characters
[mirror_edk2.git] / BaseTools / Source / C / VolInfo / VolInfo.c
CommitLineData
f51461c8 1/** @file\r
97fa0ee9 2The tool dumps the contents of a firmware volume\r
f51461c8 3\r
a9b4ee43 4Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>\r
f51461c8
LG
5This program and the accompanying materials\r
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
f51461c8
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#include <assert.h>\r
868c9c35
YZ
20#ifdef __GNUC__\r
21#include <unistd.h>\r
9947f576
YZ
22#else\r
23#include <direct.h>\r
868c9c35 24#endif\r
f51461c8
LG
25\r
26#include <FvLib.h>\r
27#include <Common/UefiBaseTypes.h>\r
28#include <Common/UefiCapsule.h>\r
29#include <Common/PiFirmwareFile.h>\r
30#include <Common/PiFirmwareVolume.h>\r
31#include <Guid/PiFirmwareFileSystem.h>\r
32#include <IndustryStandard/PeImage.h>\r
33#include <Protocol/GuidedSectionExtraction.h>\r
34\r
35#include "Compress.h"\r
36#include "Decompress.h"\r
37#include "VolInfo.h"\r
38#include "CommonLib.h"\r
39#include "EfiUtilityMsgs.h"\r
40#include "FirmwareVolumeBufferLib.h"\r
41#include "OsPath.h"\r
42#include "ParseGuidedSectionTools.h"\r
43#include "StringFuncs.h"\r
730ffca1 44#include "ParseInf.h"\r
9947f576 45#include "PeCoffLib.h"\r
f51461c8
LG
46\r
47//\r
48// Utility global variables\r
49//\r
50\r
51EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
52\r
45258285
LG
53#define UTILITY_MAJOR_VERSION 1\r
54#define UTILITY_MINOR_VERSION 0\r
f51461c8
LG
55\r
56#define UTILITY_NAME "VolInfo"\r
57\r
58#define EFI_SECTION_ERROR EFIERR (100)\r
59\r
60#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable\r
61\r
62//\r
63// Structure to keep a list of guid-to-basenames\r
64//\r
65typedef struct _GUID_TO_BASENAME {\r
66 struct _GUID_TO_BASENAME *Next;\r
67 INT8 Guid[PRINTED_GUID_BUFFER_SIZE];\r
68 INT8 BaseName[MAX_BASENAME_LEN];\r
69} GUID_TO_BASENAME;\r
70\r
71static GUID_TO_BASENAME *mGuidBaseNameList = NULL;\r
72\r
73//\r
74// Store GUIDed Section guid->tool mapping\r
75//\r
76EFI_HANDLE mParsedGuidedSectionTools = NULL;\r
77\r
78CHAR8* mUtilityFilename = NULL;\r
79\r
9947f576
YZ
80BOOLEAN EnableHash = FALSE;\r
81CHAR8 *OpenSslPath = NULL;\r
82\r
f51461c8
LG
83EFI_STATUS\r
84ParseGuidBaseNameFile (\r
85 CHAR8 *FileName\r
86 );\r
87\r
88EFI_STATUS\r
89FreeGuidBaseNameList (\r
90 VOID\r
91 );\r
92\r
93EFI_STATUS\r
94PrintGuidName (\r
95 IN UINT8 *GuidStr\r
96 );\r
97\r
98EFI_STATUS\r
99ParseSection (\r
100 IN UINT8 *SectionBuffer,\r
101 IN UINT32 BufferLength\r
102 );\r
103\r
104EFI_STATUS\r
105DumpDepexSection (\r
106 IN UINT8 *Ptr,\r
107 IN UINT32 SectionLength\r
108 );\r
109\r
110STATIC\r
111EFI_STATUS\r
112ReadHeader (\r
113 IN FILE *InputFile,\r
114 OUT UINT32 *FvSize,\r
115 OUT BOOLEAN *ErasePolarity\r
116 );\r
117\r
118STATIC\r
119EFI_STATUS\r
120PrintFileInfo (\r
121 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
122 EFI_FFS_FILE_HEADER *FileHeader,\r
123 BOOLEAN ErasePolarity\r
124 );\r
125\r
126static\r
127EFI_STATUS\r
128PrintFvInfo (\r
129 IN VOID *Fv,\r
130 IN BOOLEAN IsChildFv\r
131 );\r
132\r
133static\r
134VOID\r
135LoadGuidedSectionToolsTxt (\r
136 IN CHAR8* FirmwareVolumeFilename\r
137 );\r
138\r
9947f576
YZ
139EFI_STATUS\r
140CombinePath (\r
141 IN CHAR8* DefaultPath,\r
142 IN CHAR8* AppendPath,\r
143 OUT CHAR8* NewPath\r
144);\r
145\r
f51461c8
LG
146void\r
147Usage (\r
148 VOID\r
149 );\r
150\r
3883e2cb
HW
151UINT32\r
152UnicodeStrLen (\r
153 IN CHAR16 *String\r
154 )\r
155 /*++\r
156\r
157 Routine Description:\r
158\r
159 Returns the length of a null-terminated unicode string.\r
160\r
161 Arguments:\r
162\r
163 String - The pointer to a null-terminated unicode string.\r
164\r
165 Returns:\r
166\r
167 N/A\r
168\r
169 --*/\r
170{\r
171 UINT32 Length;\r
172\r
173 for (Length = 0; *String != L'\0'; String++, Length++) {\r
174 ;\r
175 }\r
176 return Length;\r
177}\r
178\r
179VOID\r
180Unicode2AsciiString (\r
181 IN CHAR16 *Source,\r
182 OUT CHAR8 *Destination\r
183 )\r
184 /*++\r
185\r
186 Routine Description:\r
187\r
188 Convert a null-terminated unicode string to a null-terminated ascii string.\r
189\r
190 Arguments:\r
191\r
192 Source - The pointer to the null-terminated input unicode string.\r
193 Destination - The pointer to the null-terminated output ascii string.\r
194\r
195 Returns:\r
196\r
197 N/A\r
198\r
199 --*/\r
200{\r
201 while (*Source != '\0') {\r
202 *(Destination++) = (CHAR8) *(Source++);\r
203 }\r
204 //\r
205 // End the ascii with a NULL.\r
206 //\r
207 *Destination = '\0';\r
208}\r
209\r
f51461c8
LG
210int\r
211main (\r
212 int argc,\r
213 char *argv[]\r
214 )\r
215/*++\r
216\r
217Routine Description:\r
218\r
219 GC_TODO: Add function description\r
220\r
221Arguments:\r
222\r
223 argc - GC_TODO: add argument description\r
224 ] - GC_TODO: add argument description\r
225\r
226Returns:\r
227\r
228 GC_TODO: add return values\r
229\r
230--*/\r
231{\r
232 FILE *InputFile;\r
233 int BytesRead;\r
234 EFI_FIRMWARE_VOLUME_HEADER *FvImage;\r
235 UINT32 FvSize;\r
236 EFI_STATUS Status;\r
237 int Offset;\r
238 BOOLEAN ErasePolarity;\r
730ffca1 239 UINT64 LogLevel;\r
9947f576
YZ
240 CHAR8 *OpenSslEnv;\r
241 CHAR8 *OpenSslCommand;\r
f51461c8
LG
242\r
243 SetUtilityName (UTILITY_NAME);\r
244 //\r
245 // Print utility header\r
246 //\r
45258285 247 printf ("%s Version %d.%d Build %s\n",\r
f51461c8
LG
248 UTILITY_NAME,\r
249 UTILITY_MAJOR_VERSION,\r
250 UTILITY_MINOR_VERSION,\r
45258285 251 __BUILD_VERSION\r
f51461c8
LG
252 );\r
253\r
730ffca1
YZ
254 if (argc == 1) {\r
255 Usage ();\r
256 return -1;\r
257 }\r
258\r
f51461c8
LG
259 argc--;\r
260 argv++;\r
730ffca1 261 LogLevel = 0;\r
f51461c8
LG
262 Offset = 0;\r
263\r
730ffca1
YZ
264 //\r
265 // Look for help options\r
266 //\r
267 if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) ||\r
268 (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {\r
269 Usage();\r
270 return STATUS_SUCCESS;\r
271 }\r
272 //\r
273 // Version has already be printed, so just return success\r
274 //\r
275 if (strcmp(argv[0], "--version") == 0) {\r
276 return STATUS_SUCCESS;\r
277 }\r
278\r
f51461c8
LG
279 //\r
280 // If they specified -x xref guid/basename cross-reference files, process it.\r
281 // This will print the basename beside each file guid. To use it, specify\r
282 // -x xref_filename to processdsc, then use xref_filename as a parameter\r
283 // here.\r
284 //\r
730ffca1 285 while (argc > 0) {\r
f51461c8
LG
286 if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {\r
287 ParseGuidBaseNameFile (argv[1]);\r
288 printf("ParseGuidBaseNameFile: %s\n", argv[1]);\r
289 argc -= 2;\r
290 argv += 2;\r
730ffca1
YZ
291 continue;\r
292 }\r
293 if (strcmp(argv[0], "--offset") == 0) {\r
f51461c8
LG
294 //\r
295 // Hex or decimal?\r
296 //\r
297 if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {\r
298 if (sscanf (argv[1], "%x", &Offset) != 1) {\r
299 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
300 return GetUtilityStatus ();\r
301 }\r
302 } else {\r
303 if (sscanf (argv[1], "%d", &Offset) != 1) {\r
304 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
305 return GetUtilityStatus ();\r
306 }\r
307 //\r
308 // See if they said something like "64K"\r
309 //\r
310 if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {\r
311 Offset *= 1024;\r
312 }\r
313 }\r
314\r
315 argc -= 2;\r
316 argv += 2;\r
730ffca1 317 continue;\r
f51461c8 318 }\r
9947f576 319 if ((stricmp (argv[0], "--hash") == 0)) {\r
85006654
HW
320 if (EnableHash == TRUE) {\r
321 //\r
322 // --hash already given in the option, ignore this one\r
323 //\r
324 argc --;\r
325 argv ++;\r
326 continue;\r
327 }\r
9947f576
YZ
328 EnableHash = TRUE;\r
329 OpenSslCommand = "openssl";\r
330 OpenSslEnv = getenv("OPENSSL_PATH");\r
331 if (OpenSslEnv == NULL) {\r
332 OpenSslPath = OpenSslCommand;\r
333 } else {\r
3337eefb
YZ
334 //\r
335 // We add quotes to the Openssl Path in case it has space characters\r
336 //\r
337 OpenSslPath = malloc(2+strlen(OpenSslEnv)+strlen(OpenSslCommand)+1);\r
9dd00cb6
HW
338 if (OpenSslPath == NULL) {\r
339 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
340 return GetUtilityStatus ();\r
341 }\r
9947f576
YZ
342 CombinePath(OpenSslEnv, OpenSslCommand, OpenSslPath);\r
343 }\r
344 if (OpenSslPath == NULL){\r
345 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
346 return GetUtilityStatus ();\r
347 }\r
348 argc --;\r
349 argv ++;\r
350 continue;\r
351 }\r
730ffca1
YZ
352\r
353 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
354 SetPrintLevel (VERBOSE_LOG_LEVEL);\r
355 argc --;\r
356 argv ++;\r
357 continue;\r
358 }\r
359\r
360 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
361 SetPrintLevel (KEY_LOG_LEVEL);\r
362 argc --;\r
363 argv ++;\r
364 continue;\r
365 }\r
366\r
367 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
368 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
369 if (EFI_ERROR (Status)) {\r
370 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
371 return -1;\r
372 }\r
373 if (LogLevel > 9) {\r
374 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
375 return -1;\r
376 }\r
377 SetPrintLevel (LogLevel);\r
378 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
379 argc -= 2;\r
380 argv += 2;\r
381 continue;\r
382 }\r
383\r
384 mUtilityFilename = argv[0];\r
385 argc --;\r
386 argv ++;\r
f51461c8 387 }\r
730ffca1 388\r
f51461c8
LG
389 //\r
390 // Open the file containing the FV\r
391 //\r
730ffca1
YZ
392 if (mUtilityFilename == NULL) {\r
393 Error (NULL, 0, 1001, "Missing option", "Input files are not specified");\r
394 return GetUtilityStatus ();\r
395 }\r
396 InputFile = fopen (LongFilePath (mUtilityFilename), "rb");\r
f51461c8 397 if (InputFile == NULL) {\r
730ffca1 398 Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename);\r
f51461c8
LG
399 return GetUtilityStatus ();\r
400 }\r
401 //\r
402 // Skip over pad bytes if specified. This is used if they prepend 0xff\r
403 // data to the FV image binary.\r
404 //\r
405 if (Offset != 0) {\r
406 fseek (InputFile, Offset, SEEK_SET);\r
407 }\r
408 //\r
409 // Determine size of FV\r
410 //\r
411 Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);\r
412 if (EFI_ERROR (Status)) {\r
730ffca1 413 Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename);\r
f51461c8
LG
414 fclose (InputFile);\r
415 return GetUtilityStatus ();\r
416 }\r
417 //\r
418 // Allocate a buffer for the FV image\r
419 //\r
420 FvImage = malloc (FvSize);\r
421 if (FvImage == NULL) {\r
422 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);\r
423 fclose (InputFile);\r
424 return GetUtilityStatus ();\r
425 }\r
426 //\r
427 // Seek to the start of the image, then read the entire FV to the buffer\r
428 //\r
429 fseek (InputFile, Offset, SEEK_SET);\r
430 BytesRead = fread (FvImage, 1, FvSize, InputFile);\r
431 fclose (InputFile);\r
432 if ((unsigned int) BytesRead != FvSize) {\r
730ffca1 433 Error (NULL, 0, 0004, "error reading FvImage from", mUtilityFilename);\r
f51461c8
LG
434 free (FvImage);\r
435 return GetUtilityStatus ();\r
436 }\r
437\r
730ffca1 438 LoadGuidedSectionToolsTxt (mUtilityFilename);\r
f51461c8
LG
439\r
440 PrintFvInfo (FvImage, FALSE);\r
441\r
442 //\r
443 // Clean up\r
444 //\r
445 free (FvImage);\r
446 FreeGuidBaseNameList ();\r
447 return GetUtilityStatus ();\r
448}\r
449\r
450\r
451static\r
452EFI_STATUS\r
453PrintFvInfo (\r
454 IN VOID *Fv,\r
455 IN BOOLEAN IsChildFv\r
456 )\r
457/*++\r
458\r
459Routine Description:\r
460\r
461 GC_TODO: Add function description\r
462\r
463Arguments:\r
464\r
465 Fv - Firmware Volume to print information about\r
466 IsChildFv - Flag specifies whether the input FV is a child FV.\r
467\r
468Returns:\r
469\r
470 EFI_STATUS\r
471\r
472--*/\r
473{\r
474 EFI_STATUS Status;\r
475 UINTN NumberOfFiles;\r
476 BOOLEAN ErasePolarity;\r
477 UINTN FvSize;\r
478 EFI_FFS_FILE_HEADER *CurrentFile;\r
479 UINTN Key;\r
480\r
481 Status = FvBufGetSize (Fv, &FvSize);\r
482\r
483 NumberOfFiles = 0;\r
484 ErasePolarity =\r
485 (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?\r
486 TRUE : FALSE;\r
487\r
488 //\r
489 // Get the first file\r
490 //\r
491 Key = 0;\r
492 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
493 if (EFI_ERROR (Status)) {\r
494 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");\r
495 return GetUtilityStatus ();\r
496 }\r
497 //\r
498 // Display information about files found\r
499 //\r
500 while (CurrentFile != NULL) {\r
501 //\r
502 // Increment the number of files counter\r
503 //\r
504 NumberOfFiles++;\r
505\r
506 //\r
507 // Display info about this file\r
508 //\r
509 Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);\r
510 if (EFI_ERROR (Status)) {\r
511 Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");\r
512 return GetUtilityStatus ();\r
513 }\r
514 //\r
515 // Get the next file\r
516 //\r
517 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
518 if (Status == EFI_NOT_FOUND) {\r
519 CurrentFile = NULL;\r
520 } else if (EFI_ERROR (Status)) {\r
521 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");\r
522 return GetUtilityStatus ();\r
523 }\r
524 }\r
525\r
526 if (IsChildFv) {\r
527 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles);\r
528 } else {\r
529 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles);\r
530 }\r
531\r
532 return EFI_SUCCESS;\r
533}\r
534\r
535UINT32\r
536GetOccupiedSize (\r
537 IN UINT32 ActualSize,\r
538 IN UINT32 Alignment\r
539 )\r
540/*++\r
541\r
542Routine Description:\r
543\r
544 This function returns the next larger size that meets the alignment \r
545 requirement specified.\r
546\r
547Arguments:\r
548\r
549 ActualSize The size.\r
550 Alignment The desired alignment.\r
551 \r
552Returns:\r
553 \r
554 EFI_SUCCESS Function completed successfully.\r
555 EFI_ABORTED The function encountered an error.\r
556\r
557--*/\r
558{\r
559 UINT32 OccupiedSize;\r
560\r
561 OccupiedSize = ActualSize;\r
562 while ((OccupiedSize & (Alignment - 1)) != 0) {\r
563 OccupiedSize++;\r
564 }\r
565\r
566 return OccupiedSize;\r
567}\r
568\r
569static\r
570CHAR8 *\r
571SectionNameToStr (\r
572 IN EFI_SECTION_TYPE Type\r
573 )\r
574/*++\r
575\r
576Routine Description:\r
577\r
578 Converts EFI Section names to Strings\r
579\r
580Arguments:\r
581\r
582 Type - The EFI Section type\r
583\r
584Returns:\r
585\r
586 CHAR8* - Pointer to the String containing the section name.\r
587\r
588--*/\r
589{\r
590 CHAR8 *SectionStr;\r
591 CHAR8 *SectionTypeStringTable[] = {\r
592 //\r
593 // 0X00\r
594 //\r
595 "EFI_SECTION_ALL",\r
596 //\r
597 // 0x01\r
598 //\r
599 "EFI_SECTION_COMPRESSION",\r
600 //\r
601 // 0x02\r
602 //\r
603 "EFI_SECTION_GUID_DEFINED", \r
604 //\r
605 // 0x03\r
606 //\r
607 "Unknown section type - Reserved 0x03",\r
608 //\r
609 // 0x04\r
610 //\r
611 "Unknown section type - Reserved 0x04",\r
612 //\r
613 // 0x05\r
614 //\r
615 "Unknown section type - Reserved 0x05",\r
616 //\r
617 // 0x06\r
618 //\r
619 "Unknown section type - Reserved 0x06",\r
620 //\r
621 // 0x07\r
622 //\r
623 "Unknown section type - Reserved 0x07",\r
624 //\r
625 // 0x08\r
626 //\r
627 "Unknown section type - Reserved 0x08",\r
628 //\r
629 // 0x09\r
630 //\r
631 "Unknown section type - Reserved 0x09",\r
632 //\r
633 // 0x0A\r
634 //\r
635 "Unknown section type - Reserved 0x0A",\r
636 //\r
637 // 0x0B\r
638 //\r
639 "Unknown section type - Reserved 0x0B",\r
640 //\r
641 // 0x0C\r
642 //\r
643 "Unknown section type - Reserved 0x0C",\r
644 //\r
645 // 0x0D\r
646 //\r
647 "Unknown section type - Reserved 0x0D",\r
648 //\r
649 // 0x0E\r
650 //\r
651 "Unknown section type - Reserved 0x0E",\r
652 //\r
653 // 0x0F\r
654 //\r
655 "Unknown section type - Reserved 0x0E",\r
656 //\r
657 // 0x10\r
658 //\r
659 "EFI_SECTION_PE32",\r
660 //\r
661 // 0x11\r
662 //\r
663 "EFI_SECTION_PIC",\r
664 //\r
665 // 0x12\r
666 //\r
667 "EFI_SECTION_TE", \r
668 //\r
669 // 0x13\r
670 //\r
671 "EFI_SECTION_DXE_DEPEX", \r
672 //\r
673 // 0x14\r
674 //\r
675 "EFI_SECTION_VERSION",\r
676 //\r
677 // 0x15\r
678 //\r
679 "EFI_SECTION_USER_INTERFACE",\r
680 //\r
681 // 0x16\r
682 //\r
683 "EFI_SECTION_COMPATIBILITY16",\r
684 //\r
685 // 0x17\r
686 //\r
687 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",\r
688 //\r
689 // 0x18\r
690 //\r
691 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",\r
692 //\r
693 // 0x19\r
694 //\r
695 "EFI_SECTION_RAW",\r
696 //\r
697 // 0x1A\r
698 //\r
699 "Unknown section type - 0x1A",\r
700 //\r
701 // 0x1B\r
702 //\r
703 "EFI_SECTION_PEI_DEPEX",\r
704 //\r
705 // 0x1C\r
706 //\r
707 "EFI_SECTION_SMM_DEPEX",\r
708 //\r
709 // 0x1C+\r
710 //\r
711 "Unknown section type - Reserved - beyond last defined section"\r
712 };\r
713\r
714 if (Type > EFI_SECTION_LAST_SECTION_TYPE) {\r
715 Type = EFI_SECTION_LAST_SECTION_TYPE + 1;\r
716 }\r
717\r
718 SectionStr = malloc (100);\r
719 if (SectionStr == NULL) {\r
720 printf ("Error: Out of memory resources.\n");\r
721 return SectionStr;\r
722 }\r
723 strcpy (SectionStr, SectionTypeStringTable[Type]);\r
724 return SectionStr;\r
725}\r
726\r
727STATIC\r
728EFI_STATUS\r
729ReadHeader (\r
730 IN FILE *InputFile,\r
731 OUT UINT32 *FvSize,\r
732 OUT BOOLEAN *ErasePolarity\r
733 )\r
734/*++\r
735\r
736Routine Description:\r
737\r
738 This function determines the size of the FV and the erase polarity. The \r
739 erase polarity is the FALSE value for file state.\r
740\r
741Arguments:\r
742\r
743 InputFile The file that contains the FV image.\r
744 FvSize The size of the FV.\r
745 ErasePolarity The FV erase polarity.\r
746 \r
747Returns:\r
748 \r
749 EFI_SUCCESS Function completed successfully.\r
750 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.\r
751 EFI_ABORTED The function encountered an error.\r
752\r
753--*/\r
754{\r
755 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
756 EFI_FV_BLOCK_MAP_ENTRY BlockMap;\r
757 UINTN Signature[2];\r
758 UINTN BytesRead;\r
759 UINT32 Size;\r
760\r
761 BytesRead = 0;\r
762 Size = 0;\r
763 //\r
764 // Check input parameters\r
765 //\r
766 if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {\r
767 Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");\r
768 return EFI_INVALID_PARAMETER;\r
769 }\r
770 //\r
771 // Read the header\r
772 //\r
773 fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
774 BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
775 Signature[0] = VolumeHeader.Signature;\r
776 Signature[1] = 0;\r
777\r
778 //\r
779 // Print FV header information\r
780 //\r
781 printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);\r
782 printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);\r
783\r
784 if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {\r
785 printf (" EFI_FVB2_READ_DISABLED_CAP\n");\r
786 }\r
787\r
788 if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {\r
789 printf (" EFI_FVB2_READ_ENABLED_CAP\n");\r
790 }\r
791\r
792 if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {\r
793 printf (" EFI_FVB2_READ_STATUS\n");\r
794 }\r
795\r
796 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {\r
797 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");\r
798 }\r
799\r
800 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {\r
801 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");\r
802 }\r
803\r
804 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {\r
805 printf (" EFI_FVB2_WRITE_STATUS\n");\r
806 }\r
807\r
808 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {\r
809 printf (" EFI_FVB2_LOCK_CAP\n");\r
810 }\r
811\r
812 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {\r
813 printf (" EFI_FVB2_LOCK_STATUS\n");\r
814 }\r
815\r
816 if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {\r
817 printf (" EFI_FVB2_STICKY_WRITE\n");\r
818 }\r
819\r
820 if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {\r
821 printf (" EFI_FVB2_MEMORY_MAPPED\n");\r
822 }\r
823\r
824 if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {\r
825 printf (" EFI_FVB2_ERASE_POLARITY\n");\r
826 *ErasePolarity = TRUE;\r
827 }\r
828\r
829#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
830 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {\r
831 printf (" EFI_FVB2_ALIGNMENT\n");\r
832 }\r
833\r
834 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
835 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
836 }\r
837\r
838 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
839 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
840 }\r
841\r
842 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
843 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
844 }\r
845\r
846 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
847 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
848 }\r
849\r
850 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
851 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
852 }\r
853\r
854 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
855 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
856 }\r
857\r
858 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
859 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
860 }\r
861\r
862 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
863 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
864 }\r
865\r
866 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
867 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
868 }\r
869\r
870 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
871 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
872 }\r
873\r
874 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
875 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
876 }\r
877\r
878 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
879 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
880 }\r
881\r
882 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
883 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
884 }\r
885\r
886 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
887 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
888 }\r
889\r
890 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
891 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
892 }\r
893\r
894 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
895 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
896 }\r
897 \r
898#else\r
899\r
900 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {\r
901 printf (" EFI_FVB2_READ_LOCK_CAP\n");\r
902 }\r
903\r
904 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {\r
905 printf (" EFI_FVB2_READ_LOCK_STATUS\n");\r
906 }\r
907\r
908 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {\r
909 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");\r
910 }\r
911\r
912 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {\r
913 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");\r
914 }\r
915\r
916 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {\r
917 printf (" EFI_FVB2_ALIGNMENT_1\n");\r
918 }\r
919\r
920 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
921 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
922 }\r
923\r
924 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
925 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
926 }\r
927\r
928 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
929 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
930 }\r
931\r
932 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
933 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
934 }\r
935\r
936 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
937 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
938 }\r
939\r
940 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
941 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
942 }\r
943\r
944 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
945 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
946 }\r
947\r
948 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
949 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
950 }\r
951\r
952 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
953 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
954 }\r
955\r
956 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
957 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
958 }\r
959\r
960 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
961 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
962 }\r
963\r
964 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
965 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
966 }\r
967\r
968 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
969 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
970 }\r
971\r
972 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
973 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
974 }\r
975\r
976 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
977 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
978 }\r
979\r
980 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
981 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
982 }\r
983\r
984 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {\r
985 printf (" EFI_FVB2_ALIGNMENT_128K\n");\r
986 }\r
987\r
988 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {\r
989 printf (" EFI_FVB2_ALIGNMENT_256K\n");\r
990 }\r
991\r
992 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) {\r
993 printf (" EFI_FVB2_ALIGNMENT_512K\n");\r
994 }\r
995\r
996 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {\r
997 printf (" EFI_FVB2_ALIGNMENT_1M\n");\r
998 }\r
999\r
1000 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {\r
1001 printf (" EFI_FVB2_ALIGNMENT_2M\n");\r
1002 }\r
1003\r
1004 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {\r
1005 printf (" EFI_FVB2_ALIGNMENT_4M\n");\r
1006 }\r
1007\r
1008 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {\r
1009 printf (" EFI_FVB2_ALIGNMENT_8M\n");\r
1010 }\r
1011\r
1012 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {\r
1013 printf (" EFI_FVB2_ALIGNMENT_16M\n");\r
1014 }\r
1015\r
1016 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {\r
1017 printf (" EFI_FVB2_ALIGNMENT_32M\n");\r
1018 }\r
1019\r
1020 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
1021 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
1022 }\r
1023\r
1024 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
1025 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
1026 }\r
1027\r
1028 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
1029 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
1030 }\r
1031\r
1032 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
1033 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
1034 }\r
1035\r
1036 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {\r
1037 printf (" EFI_FVB2_ALIGNMENT_256M\n");\r
1038 }\r
1039\r
1040 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {\r
1041 printf (" EFI_FVB2_ALIGNMENT_512M\n");\r
1042 }\r
1043\r
1044 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {\r
1045 printf (" EFI_FVB2_ALIGNMENT_1G\n");\r
1046 }\r
1047\r
1048 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {\r
1049 printf (" EFI_FVB2_ALIGNMENT_2G\n");\r
1050 }\r
1051\r
1052#endif\r
1053 printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);\r
1054 printf ("File System ID: ");\r
1055 PrintGuid (&VolumeHeader.FileSystemGuid);\r
1056 //\r
1057 // printf ("\n");\r
1058 //\r
1059 printf ("Revision: 0x%04X\n", VolumeHeader.Revision);\r
1060\r
1061 do {\r
1062 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
1063 BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
1064\r
1065 if (BlockMap.NumBlocks != 0) {\r
1066 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);\r
1067 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);\r
1068 Size += BlockMap.NumBlocks * BlockMap.Length;\r
1069 }\r
1070\r
1071 } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));\r
1072\r
1073 if (BytesRead != VolumeHeader.HeaderLength) {\r
1074 printf ("ERROR: Header length not consistent with Block Maps!\n");\r
1075 return EFI_ABORTED;\r
1076 }\r
1077\r
1078 if (VolumeHeader.FvLength != Size) {\r
1079 printf ("ERROR: Volume Size not consistant with Block Maps!\n");\r
1080 return EFI_ABORTED;\r
1081 }\r
1082\r
1083 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);\r
1084\r
1085 *FvSize = Size;\r
1086\r
1087 //\r
1088 // rewind (InputFile);\r
1089 //\r
1090 return EFI_SUCCESS;\r
1091}\r
1092\r
1093STATIC\r
1094EFI_STATUS\r
1095PrintFileInfo (\r
1096 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
1097 EFI_FFS_FILE_HEADER *FileHeader,\r
1098 BOOLEAN ErasePolarity\r
1099 )\r
1100/*++\r
1101\r
1102Routine Description:\r
1103\r
1104 GC_TODO: Add function description\r
1105\r
1106Arguments:\r
1107\r
1108 FvImage - GC_TODO: add argument description\r
1109 FileHeader - GC_TODO: add argument description\r
1110 ErasePolarity - GC_TODO: add argument description\r
1111\r
1112Returns:\r
1113\r
1114 EFI_SUCCESS - GC_TODO: Add description for return value\r
1115 EFI_ABORTED - GC_TODO: Add description for return value\r
1116\r
1117--*/\r
1118{\r
1119 UINT32 FileLength;\r
1120 UINT8 FileState;\r
1121 UINT8 Checksum;\r
e4ac870f 1122 EFI_FFS_FILE_HEADER2 BlankHeader;\r
f51461c8
LG
1123 EFI_STATUS Status;\r
1124 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
e4ac870f 1125 UINT32 HeaderSize;\r
f51461c8
LG
1126#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
1127 UINT16 *Tail;\r
1128#endif\r
1129 //\r
1130 // Check if we have free space\r
1131 //\r
e4ac870f 1132 HeaderSize = FvBufGetFfsHeaderSize(FileHeader);\r
f51461c8 1133 if (ErasePolarity) {\r
e4ac870f 1134 memset (&BlankHeader, -1, HeaderSize);\r
f51461c8 1135 } else {\r
e4ac870f 1136 memset (&BlankHeader, 0, HeaderSize);\r
f51461c8
LG
1137 }\r
1138\r
e4ac870f 1139 if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {\r
f51461c8
LG
1140 return EFI_SUCCESS;\r
1141 }\r
1142 //\r
1143 // Print file information.\r
1144 //\r
1145 printf ("============================================================\n");\r
1146\r
1147 printf ("File Name: ");\r
1148 PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);\r
1149 printf ("%s ", GuidBuffer);\r
1150 PrintGuidName (GuidBuffer);\r
1151 printf ("\n");\r
1152\r
1153 //\r
1154 // PrintGuid (&FileHeader->Name);\r
1155 // printf ("\n");\r
1156 //\r
e4ac870f 1157 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1158 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));\r
1159 printf ("File Length: 0x%08X\n", (unsigned) FileLength);\r
1160 printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);\r
1161 printf ("File State: 0x%02X\n", FileHeader->State);\r
1162\r
1163 //\r
1164 // Print file state\r
1165 //\r
1166 FileState = GetFileState (ErasePolarity, FileHeader);\r
1167\r
1168 switch (FileState) {\r
1169\r
1170 case EFI_FILE_HEADER_CONSTRUCTION:\r
1171 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");\r
1172 return EFI_SUCCESS;\r
1173\r
1174 case EFI_FILE_HEADER_INVALID:\r
1175 printf (" EFI_FILE_HEADER_INVALID\n");\r
1176 return EFI_SUCCESS;\r
1177\r
1178 case EFI_FILE_HEADER_VALID:\r
1179 printf (" EFI_FILE_HEADER_VALID\n");\r
e4ac870f 1180 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1181 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1182 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1183 if (Checksum != 0) {\r
1184 printf ("ERROR: Header checksum invalid.\n");\r
1185 return EFI_ABORTED;\r
1186 }\r
1187\r
1188 return EFI_SUCCESS;\r
1189\r
1190 case EFI_FILE_DELETED:\r
1191 printf (" EFI_FILE_DELETED\n");\r
1192\r
1193 case EFI_FILE_MARKED_FOR_UPDATE:\r
1194 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");\r
1195\r
1196 case EFI_FILE_DATA_VALID:\r
1197 printf (" EFI_FILE_DATA_VALID\n");\r
1198\r
1199 //\r
1200 // Calculate header checksum\r
1201 //\r
e4ac870f 1202 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1203 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1204 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1205 if (Checksum != 0) {\r
1206 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);\r
1207 return EFI_ABORTED;\r
1208 }\r
1209\r
e4ac870f 1210 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1211\r
1212 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
1213 //\r
1214 // Calculate file checksum\r
1215 //\r
e4ac870f 1216 Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);\r
f51461c8
LG
1217 Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;\r
1218 if (Checksum != 0) {\r
1219 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);\r
1220 return EFI_ABORTED;\r
1221 }\r
1222 } else {\r
1223 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
1224 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum -- not set to fixed value of 0xAA", GuidBuffer);\r
1225 return EFI_ABORTED;\r
1226 }\r
1227 }\r
1228#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
1229 //\r
1230 // Verify tail if present\r
1231 //\r
1232 if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
1233 //\r
1234 // Verify tail is complement of integrity check field in the header.\r
1235 //\r
1236 Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));\r
1237 if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {\r
1238 Error (NULL, 0, 0003, "error parsing FFS file", \\r
1239 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);\r
1240 return EFI_ABORTED;\r
1241 }\r
1242 }\r
1243 #endif \r
1244 break;\r
1245\r
1246 default:\r
1247 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);\r
1248 return EFI_ABORTED;\r
1249 }\r
1250\r
1251 printf ("File Type: 0x%02X ", FileHeader->Type);\r
1252\r
1253 switch (FileHeader->Type) {\r
1254\r
1255 case EFI_FV_FILETYPE_RAW:\r
1256 printf ("EFI_FV_FILETYPE_RAW\n");\r
1257 break;\r
1258\r
1259 case EFI_FV_FILETYPE_FREEFORM:\r
1260 printf ("EFI_FV_FILETYPE_FREEFORM\n");\r
1261 break;\r
1262\r
1263 case EFI_FV_FILETYPE_SECURITY_CORE:\r
1264 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");\r
1265 break;\r
1266\r
1267 case EFI_FV_FILETYPE_PEI_CORE:\r
1268 printf ("EFI_FV_FILETYPE_PEI_CORE\n");\r
1269 break;\r
1270\r
1271 case EFI_FV_FILETYPE_DXE_CORE:\r
1272 printf ("EFI_FV_FILETYPE_DXE_CORE\n");\r
1273 break;\r
1274\r
1275 case EFI_FV_FILETYPE_PEIM:\r
1276 printf ("EFI_FV_FILETYPE_PEIM\n");\r
1277 break;\r
1278\r
1279 case EFI_FV_FILETYPE_DRIVER:\r
1280 printf ("EFI_FV_FILETYPE_DRIVER\n");\r
1281 break;\r
1282\r
1283 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
1284 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");\r
1285 break;\r
1286\r
1287 case EFI_FV_FILETYPE_APPLICATION:\r
1288 printf ("EFI_FV_FILETYPE_APPLICATION\n");\r
1289 break;\r
1290\r
1291 case EFI_FV_FILETYPE_SMM:\r
1292 printf ("EFI_FV_FILETYPE_SMM\n");\r
1293 break;\r
1294\r
1295 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
1296 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");\r
1297 break;\r
1298\r
1299 case EFI_FV_FILETYPE_COMBINED_SMM_DXE:\r
1300 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");\r
1301 break;\r
1302\r
1303 case EFI_FV_FILETYPE_SMM_CORE:\r
1304 printf ("EFI_FV_FILETYPE_SMM_CORE\n");\r
1305 break;\r
1306\r
1307 case EFI_FV_FILETYPE_FFS_PAD:\r
1308 printf ("EFI_FV_FILETYPE_FFS_PAD\n");\r
1309 break;\r
1310\r
1311 default:\r
1312 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);\r
1313 return EFI_ABORTED;\r
1314 break;\r
1315 }\r
1316\r
1317 switch (FileHeader->Type) {\r
1318\r
1319 case EFI_FV_FILETYPE_ALL:\r
1320 case EFI_FV_FILETYPE_RAW:\r
1321 case EFI_FV_FILETYPE_FFS_PAD:\r
1322 break;\r
1323\r
1324 default:\r
1325 //\r
1326 // All other files have sections\r
1327 //\r
1328 Status = ParseSection (\r
e4ac870f
LG
1329 (UINT8 *) ((UINTN) FileHeader + HeaderSize),\r
1330 FvBufGetFfsFileSize (FileHeader) - HeaderSize\r
f51461c8
LG
1331 );\r
1332 if (EFI_ERROR (Status)) {\r
1333 //\r
1334 // printf ("ERROR: Parsing the FFS file.\n");\r
1335 //\r
1336 return EFI_ABORTED;\r
1337 }\r
1338 break;\r
1339 }\r
1340\r
1341 return EFI_SUCCESS;\r
1342}\r
1343\r
9947f576
YZ
1344EFI_STATUS\r
1345RebaseImageRead (\r
1346 IN VOID *FileHandle,\r
1347 IN UINTN FileOffset,\r
1348 IN OUT UINT32 *ReadSize,\r
1349 OUT VOID *Buffer\r
1350 )\r
1351/*++\r
1352\r
1353Routine Description:\r
1354\r
1355 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
1356\r
1357Arguments:\r
1358\r
1359 FileHandle - The handle to the PE/COFF file\r
1360\r
1361 FileOffset - The offset, in bytes, into the file to read\r
1362\r
1363 ReadSize - The number of bytes to read from the file starting at FileOffset\r
1364\r
1365 Buffer - A pointer to the buffer to read the data into.\r
1366\r
1367Returns:\r
1368\r
1369 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
1370\r
1371--*/\r
1372{\r
1373 CHAR8 *Destination8;\r
1374 CHAR8 *Source8;\r
1375 UINT32 Length;\r
1376\r
1377 Destination8 = Buffer;\r
1378 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
1379 Length = *ReadSize;\r
1380 while (Length--) {\r
1381 *(Destination8++) = *(Source8++);\r
1382 }\r
1383\r
1384 return EFI_SUCCESS;\r
1385}\r
1386\r
1387EFI_STATUS\r
1388SetAddressToSectionHeader (\r
1389 IN CHAR8 *FileName,\r
1390 IN OUT UINT8 *FileBuffer,\r
1391 IN UINT64 NewPe32BaseAddress\r
1392 )\r
1393/*++\r
1394\r
1395Routine Description:\r
1396\r
1397 Set new base address into the section header of PeImage\r
1398\r
1399Arguments:\r
1400\r
1401 FileName - Name of file\r
1402 FileBuffer - Pointer to PeImage.\r
1403 NewPe32BaseAddress - New Base Address for PE image.\r
1404\r
1405Returns:\r
1406\r
1407 EFI_SUCCESS Set new base address into this image successfully.\r
1408\r
1409--*/\r
1410{\r
1411 EFI_STATUS Status;\r
1412 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1413 UINTN Index;\r
1414 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1415 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1416\r
1417 //\r
1418 // Initialize context\r
1419 //\r
1420 memset (&ImageContext, 0, sizeof (ImageContext));\r
1421 ImageContext.Handle = (VOID *) FileBuffer;\r
1422 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1423 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1424 if (EFI_ERROR (Status)) {\r
1425 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1426 return Status;\r
1427 }\r
1428\r
1429 if (ImageContext.RelocationsStripped) {\r
1430 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1431 return Status;\r
1432 }\r
1433\r
1434 //\r
1435 // Get PeHeader pointer\r
1436 //\r
1437 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1438\r
1439 //\r
1440 // Get section header list\r
1441 //\r
1442 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1443 (UINTN) ImgHdr +\r
1444 sizeof (UINT32) +\r
1445 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1446 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1447 );\r
1448\r
1449 //\r
1450 // Set base address into the first section header that doesn't point to code section.\r
1451 //\r
1452 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1453 if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
1454 *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;\r
1455 break;\r
1456 }\r
1457 }\r
1458\r
9947f576
YZ
1459 //\r
1460 // BaseAddress is set to section header.\r
1461 //\r
1462 return EFI_SUCCESS;\r
1463}\r
1464\r
1465EFI_STATUS\r
1466RebaseImage (\r
1467 IN CHAR8 *FileName,\r
1468 IN OUT UINT8 *FileBuffer,\r
1469 IN UINT64 NewPe32BaseAddress\r
1470 )\r
1471/*++\r
1472\r
1473Routine Description:\r
1474\r
1475 Set new base address into PeImage, and fix up PeImage based on new address.\r
1476\r
1477Arguments:\r
1478\r
1479 FileName - Name of file\r
1480 FileBuffer - Pointer to PeImage.\r
1481 NewPe32BaseAddress - New Base Address for PE image.\r
1482\r
1483Returns:\r
1484\r
1485 EFI_INVALID_PARAMETER - BaseAddress is not valid.\r
1486 EFI_SUCCESS - Update PeImage is correctly.\r
1487\r
1488--*/\r
1489{\r
1490 EFI_STATUS Status;\r
1491 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1492 UINTN Index;\r
1493 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1494 UINT8 *MemoryImagePointer;\r
1495 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1496\r
1497 //\r
1498 // Initialize context\r
1499 //\r
1500 memset (&ImageContext, 0, sizeof (ImageContext));\r
1501 ImageContext.Handle = (VOID *) FileBuffer;\r
1502 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1503 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1504 if (EFI_ERROR (Status)) {\r
1505 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1506 return Status;\r
1507 }\r
1508\r
1509 if (ImageContext.RelocationsStripped) {\r
1510 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1511 return Status;\r
1512 }\r
1513\r
1514 //\r
1515 // Get PeHeader pointer\r
1516 //\r
1517 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1518\r
1519 //\r
1520 // Load and Relocate Image Data\r
1521 //\r
1522 MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1523 if (MemoryImagePointer == NULL) {\r
1524 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
1525 return EFI_OUT_OF_RESOURCES;\r
1526 }\r
1527 memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1528 ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
1529\r
1530 Status = PeCoffLoaderLoadImage (&ImageContext);\r
1531 if (EFI_ERROR (Status)) {\r
1532 Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
1533 free ((VOID *) MemoryImagePointer);\r
1534 return Status;\r
1535 }\r
1536\r
1537 ImageContext.DestinationAddress = NewPe32BaseAddress;\r
1538 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
1539 if (EFI_ERROR (Status)) {\r
1540 Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
1541 free ((VOID *) MemoryImagePointer);\r
1542 return Status;\r
1543 }\r
1544\r
1545 //\r
1546 // Copy Relocated data to raw image file.\r
1547 //\r
1548 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1549 (UINTN) ImgHdr +\r
1550 sizeof (UINT32) +\r
1551 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1552 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1553 );\r
1554\r
1555 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1556 CopyMem (\r
1557 FileBuffer + SectionHeader->PointerToRawData,\r
1558 (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),\r
1559 SectionHeader->SizeOfRawData\r
1560 );\r
1561 }\r
1562\r
1563 free ((VOID *) MemoryImagePointer);\r
1564\r
1565 //\r
1566 // Update Image Base Address\r
1567 //\r
1568 if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
1569 ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
1570 } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
1571 ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
1572 } else {\r
1573 Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
1574 ImgHdr->Pe32.OptionalHeader.Magic,\r
1575 FileName\r
1576 );\r
1577 return EFI_ABORTED;\r
1578 }\r
1579\r
1580 //\r
1581 // Set new base address into section header\r
1582 //\r
1583 Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);\r
1584\r
1585 return Status;\r
1586}\r
1587\r
1588EFI_STATUS\r
1589CombinePath (\r
1590 IN CHAR8* DefaultPath,\r
1591 IN CHAR8* AppendPath,\r
1592 OUT CHAR8* NewPath\r
1593)\r
1594{\r
1595 UINT32 DefaultPathLen;\r
8994d2f9 1596 UINT64 Index;\r
3337eefb
YZ
1597 CHAR8 QuotesStr[] = "\"";\r
1598 strcpy(NewPath, QuotesStr);\r
9947f576 1599 DefaultPathLen = strlen(DefaultPath);\r
3337eefb 1600 strcat(NewPath, DefaultPath);\r
8994d2f9 1601 Index = 0;\r
3337eefb 1602 for (; Index < DefaultPathLen + 1; Index ++) {\r
9947f576
YZ
1603 if (NewPath[Index] == '\\' || NewPath[Index] == '/') {\r
1604 if (NewPath[Index + 1] != '\0') {\r
1605 NewPath[Index] = '/';\r
1606 }\r
1607 }\r
1608 }\r
1609 if (NewPath[Index -1] != '/') {\r
1610 NewPath[Index] = '/';\r
1611 NewPath[Index + 1] = '\0';\r
1612 }\r
1613 strcat(NewPath, AppendPath);\r
3337eefb 1614 strcat(NewPath, QuotesStr);\r
9947f576
YZ
1615 return EFI_SUCCESS;\r
1616}\r
1617\r
f51461c8
LG
1618EFI_STATUS\r
1619ParseSection (\r
1620 IN UINT8 *SectionBuffer,\r
1621 IN UINT32 BufferLength\r
1622 )\r
1623/*++\r
1624\r
1625Routine Description:\r
1626\r
1627 Parses EFI Sections\r
1628\r
1629Arguments:\r
1630\r
1631 SectionBuffer - Buffer containing the section to parse.\r
1632 BufferLength - Length of SectionBuffer\r
1633\r
1634Returns:\r
1635\r
1636 EFI_SECTION_ERROR - Problem with section parsing.\r
1637 (a) compression errors\r
1638 (b) unrecognized section \r
1639 EFI_UNSUPPORTED - Do not know how to parse the section.\r
1640 EFI_SUCCESS - Section successfully parsed.\r
1641 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1642\r
1643--*/\r
1644{\r
1645 EFI_SECTION_TYPE Type;\r
1646 UINT8 *Ptr;\r
1647 UINT32 SectionLength;\r
e4ac870f 1648 UINT32 SectionHeaderLen;\r
f51461c8
LG
1649 CHAR8 *SectionName;\r
1650 EFI_STATUS Status;\r
1651 UINT32 ParsedLength;\r
1652 UINT8 *CompressedBuffer;\r
1653 UINT32 CompressedLength;\r
1654 UINT8 *UncompressedBuffer;\r
1655 UINT32 UncompressedLength;\r
1656 UINT8 *ToolOutputBuffer;\r
1657 UINT32 ToolOutputLength;\r
1658 UINT8 CompressionType;\r
1659 UINT32 DstSize;\r
1660 UINT32 ScratchSize;\r
1661 UINT8 *ScratchBuffer;\r
1662 DECOMPRESS_FUNCTION DecompressFunction;\r
1663 GETINFO_FUNCTION GetInfoFunction;\r
1664 // CHAR16 *name;\r
1665 CHAR8 *ExtractionTool;\r
1666 CHAR8 *ToolInputFile;\r
1667 CHAR8 *ToolOutputFile;\r
f51461c8 1668 CHAR8 *SystemCommand;\r
e4ac870f
LG
1669 EFI_GUID *EfiGuid;\r
1670 UINT16 DataOffset;\r
1671 UINT16 Attributes;\r
1672 UINT32 RealHdrLen;\r
9947f576
YZ
1673 CHAR8 *ToolInputFileName;\r
1674 CHAR8 *ToolOutputFileName;\r
3883e2cb 1675 CHAR8 *UIFileName;\r
f51461c8
LG
1676\r
1677 ParsedLength = 0;\r
9947f576
YZ
1678 ToolInputFileName = NULL;\r
1679 ToolOutputFileName = NULL;\r
1680\r
f51461c8
LG
1681 while (ParsedLength < BufferLength) {\r
1682 Ptr = SectionBuffer + ParsedLength;\r
1683\r
1684 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
1685 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
1686\r
1687 //\r
1688 // This is sort of an odd check, but is necessary because FFS files are\r
1689 // padded to a QWORD boundary, meaning there is potentially a whole section\r
1690 // header worth of 0xFF bytes.\r
1691 //\r
1692 if (SectionLength == 0xffffff && Type == 0xff) {\r
1693 ParsedLength += 4;\r
1694 continue;\r
1695 }\r
1696\r
e4ac870f
LG
1697 //\r
1698 // Get real section file size\r
1699 //\r
1700 SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);\r
1701 SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1702\r
f51461c8 1703 SectionName = SectionNameToStr (Type);\r
9dd00cb6
HW
1704 if (SectionName != NULL) {\r
1705 printf ("------------------------------------------------------------\n");\r
1706 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);\r
1707 free (SectionName);\r
1708 }\r
f51461c8
LG
1709\r
1710 switch (Type) {\r
1711 case EFI_SECTION_RAW:\r
f51461c8
LG
1712 case EFI_SECTION_PIC:\r
1713 case EFI_SECTION_TE:\r
1714 // default is no more information\r
1715 break;\r
1716\r
9947f576
YZ
1717 case EFI_SECTION_PE32:\r
1718 if (EnableHash) {\r
1719 ToolInputFileName = "edk2Temp_InputEfi.tmp";\r
1720 ToolOutputFileName = "edk2Temp_OutputHash.tmp";\r
1721 RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);\r
1722 PutFileImage (\r
1723 ToolInputFileName,\r
1724 (CHAR8*)Ptr + SectionHeaderLen,\r
1725 SectionLength - SectionHeaderLen\r
1726 );\r
1727\r
9947f576 1728 SystemCommand = malloc (\r
aeadb1c4 1729 strlen (OPENSSL_COMMAND_FORMAT_STRING) +\r
9947f576
YZ
1730 strlen (OpenSslPath) +\r
1731 strlen (ToolInputFileName) +\r
1732 strlen (ToolOutputFileName) +\r
1733 1\r
1734 );\r
9dd00cb6
HW
1735 if (SystemCommand == NULL) {\r
1736 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1737 return EFI_OUT_OF_RESOURCES;\r
1738 }\r
9947f576
YZ
1739 sprintf (\r
1740 SystemCommand,\r
aeadb1c4 1741 OPENSSL_COMMAND_FORMAT_STRING,\r
9947f576
YZ
1742 OpenSslPath,\r
1743 ToolOutputFileName,\r
1744 ToolInputFileName\r
1745 );\r
1746\r
1747 if (system (SystemCommand) != EFI_SUCCESS) {\r
1748 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
1749 }\r
1750 else {\r
1751 FILE *fp;\r
1752 CHAR8 *StrLine;\r
1753 CHAR8 *NewStr;\r
1754 UINT32 nFileLen;\r
1755 if((fp = fopen(ToolOutputFileName,"r")) == NULL) {\r
1756 Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);\r
1757 }\r
1758 else {\r
1759 fseek(fp,0,SEEK_SET);\r
1760 fseek(fp,0,SEEK_END);\r
1761 nFileLen = ftell(fp);\r
1762 fseek(fp,0,SEEK_SET);\r
1763 StrLine = malloc(nFileLen);\r
9dd00cb6
HW
1764 if (StrLine == NULL) {\r
1765 fclose(fp);\r
1766 free (SystemCommand);\r
1767 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1768 return EFI_OUT_OF_RESOURCES;\r
1769 }\r
9947f576
YZ
1770 fgets(StrLine, nFileLen, fp);\r
1771 NewStr = strrchr (StrLine, '=');\r
1772 printf (" SHA1: %s\n", NewStr + 1);\r
1773 free (StrLine);\r
9dd00cb6 1774 fclose(fp);\r
9947f576 1775 }\r
9947f576
YZ
1776 }\r
1777 remove(ToolInputFileName);\r
1778 remove(ToolOutputFileName);\r
1779 free (SystemCommand);\r
1780 }\r
1781 break;\r
1782\r
f51461c8 1783 case EFI_SECTION_USER_INTERFACE:\r
3883e2cb
HW
1784 UIFileName = (CHAR8 *) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString) + 1);\r
1785 if (UIFileName == NULL) {\r
1786 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1787 return EFI_OUT_OF_RESOURCES;\r
1788 }\r
1789 Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UIFileName);\r
1790 printf (" String: %s\n", UIFileName);\r
1791 free (UIFileName);\r
f51461c8
LG
1792 break;\r
1793\r
1794 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
e4ac870f 1795 Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);\r
f51461c8
LG
1796 if (EFI_ERROR (Status)) {\r
1797 Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);\r
1798 return EFI_SECTION_ERROR;\r
1799 }\r
1800 break;\r
1801\r
1802 case EFI_SECTION_COMPATIBILITY16:\r
1803 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
1804 //\r
1805 // Section does not contain any further header information.\r
1806 //\r
1807 break;\r
1808\r
1809 case EFI_SECTION_PEI_DEPEX:\r
1810 case EFI_SECTION_DXE_DEPEX:\r
1811 case EFI_SECTION_SMM_DEPEX:\r
1812 DumpDepexSection (Ptr, SectionLength);\r
1813 break;\r
1814\r
1815 case EFI_SECTION_VERSION:\r
e4ac870f
LG
1816 printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));\r
1817 printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));\r
f51461c8
LG
1818 break;\r
1819\r
1820 case EFI_SECTION_COMPRESSION:\r
1821 UncompressedBuffer = NULL;\r
e4ac870f
LG
1822 if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1823 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);\r
1824 UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;\r
1825 CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;\r
1826 } else {\r
1827 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);\r
1828 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;\r
1829 CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;\r
1830 }\r
1831 CompressedLength = SectionLength - RealHdrLen;\r
f51461c8
LG
1832 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);\r
1833\r
1834 if (CompressionType == EFI_NOT_COMPRESSED) {\r
1835 printf (" Compression Type: EFI_NOT_COMPRESSED\n");\r
1836 if (CompressedLength != UncompressedLength) {\r
1837 Error (\r
1838 NULL,\r
1839 0,\r
1840 0,\r
1841 "file is not compressed, but the compressed length does not match the uncompressed length",\r
1842 NULL\r
1843 );\r
1844 return EFI_SECTION_ERROR;\r
1845 }\r
1846\r
e4ac870f 1847 UncompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1848 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1849 GetInfoFunction = EfiGetInfo;\r
1850 DecompressFunction = EfiDecompress;\r
1851 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");\r
1852\r
e4ac870f 1853 CompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1854\r
1855 Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);\r
1856 if (EFI_ERROR (Status)) {\r
1857 Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);\r
1858 return EFI_SECTION_ERROR;\r
1859 }\r
1860\r
1861 if (DstSize != UncompressedLength) {\r
1862 Error (NULL, 0, 0003, "compression error in the compression section", NULL);\r
1863 return EFI_SECTION_ERROR;\r
1864 }\r
1865\r
1866 ScratchBuffer = malloc (ScratchSize);\r
85006654
HW
1867 if (ScratchBuffer == NULL) {\r
1868 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1869 return EFI_OUT_OF_RESOURCES;\r
1870 }\r
f51461c8 1871 UncompressedBuffer = malloc (UncompressedLength);\r
85006654
HW
1872 if (UncompressedBuffer == NULL) {\r
1873 free (ScratchBuffer);\r
1874 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
f51461c8
LG
1875 return EFI_OUT_OF_RESOURCES;\r
1876 }\r
1877 Status = DecompressFunction (\r
1878 CompressedBuffer,\r
1879 CompressedLength,\r
1880 UncompressedBuffer,\r
1881 UncompressedLength,\r
1882 ScratchBuffer,\r
1883 ScratchSize\r
1884 );\r
1885 free (ScratchBuffer);\r
1886 if (EFI_ERROR (Status)) {\r
1887 Error (NULL, 0, 0003, "decompress failed", NULL);\r
1888 free (UncompressedBuffer);\r
1889 return EFI_SECTION_ERROR;\r
1890 }\r
1891 } else {\r
1892 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);\r
1893 return EFI_SECTION_ERROR;\r
1894 }\r
1895\r
1896 Status = ParseSection (UncompressedBuffer, UncompressedLength);\r
1897\r
1898 if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1899 //\r
1900 // We need to deallocate Buffer\r
1901 //\r
1902 free (UncompressedBuffer);\r
1903 }\r
1904\r
1905 if (EFI_ERROR (Status)) {\r
1906 Error (NULL, 0, 0003, "failed to parse section", NULL);\r
1907 return EFI_SECTION_ERROR;\r
1908 }\r
1909 break;\r
1910\r
1911 case EFI_SECTION_GUID_DEFINED:\r
e4ac870f
LG
1912 if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {\r
1913 EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;\r
1914 DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;\r
1915 Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;\r
1916 } else {\r
1917 EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;\r
1918 DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;\r
1919 Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;\r
1920 }\r
f51461c8 1921 printf (" SectionDefinitionGuid: ");\r
e4ac870f 1922 PrintGuid (EfiGuid);\r
f51461c8 1923 printf ("\n");\r
e4ac870f
LG
1924 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);\r
1925 printf (" Attributes: 0x%04X\n", (unsigned) Attributes);\r
f51461c8
LG
1926\r
1927 ExtractionTool =\r
1928 LookupGuidedSectionToolPath (\r
1929 mParsedGuidedSectionTools,\r
e4ac870f 1930 EfiGuid\r
f51461c8
LG
1931 );\r
1932\r
1933 if (ExtractionTool != NULL) {\r
868c9c35 1934 #ifndef __GNUC__\r
f51461c8
LG
1935 ToolInputFile = CloneString (tmpnam (NULL));\r
1936 ToolOutputFile = CloneString (tmpnam (NULL));\r
868c9c35
YZ
1937 #else\r
1938 char tmp1[] = "/tmp/fileXXXXXX";\r
1939 char tmp2[] = "/tmp/fileXXXXXX";\r
1940 int fd1;\r
1941 int fd2;\r
1942 fd1 = mkstemp(tmp1);\r
1943 fd2 = mkstemp(tmp2);\r
1944 ToolInputFile = CloneString(tmp1);\r
1945 ToolOutputFile = CloneString(tmp2);\r
1946 close(fd1);\r
1947 close(fd2);\r
1948 #endif\r
f51461c8 1949\r
9dd00cb6
HW
1950 if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) {\r
1951 if (ToolInputFile != NULL) {\r
1952 free (ToolInputFile);\r
1953 }\r
1954 if (ToolOutputFile != NULL) {\r
1955 free (ToolOutputFile);\r
1956 }\r
1957 free (ExtractionTool);\r
1958\r
1959 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1960 return EFI_OUT_OF_RESOURCES;\r
1961 }\r
1962\r
f51461c8
LG
1963 //\r
1964 // Construction 'system' command string\r
1965 //\r
f51461c8 1966 SystemCommand = malloc (\r
aeadb1c4 1967 strlen (EXTRACT_COMMAND_FORMAT_STRING) +\r
f51461c8
LG
1968 strlen (ExtractionTool) +\r
1969 strlen (ToolInputFile) +\r
1970 strlen (ToolOutputFile) +\r
1971 1\r
1972 );\r
9dd00cb6
HW
1973 if (SystemCommand == NULL) {\r
1974 free (ToolInputFile);\r
1975 free (ToolOutputFile);\r
1976 free (ExtractionTool);\r
1977\r
1978 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1979 return EFI_OUT_OF_RESOURCES;\r
1980 }\r
f51461c8
LG
1981 sprintf (\r
1982 SystemCommand,\r
aeadb1c4 1983 EXTRACT_COMMAND_FORMAT_STRING,\r
f51461c8
LG
1984 ExtractionTool,\r
1985 ToolOutputFile,\r
1986 ToolInputFile\r
1987 );\r
1988 free (ExtractionTool);\r
1989\r
1990 Status =\r
1991 PutFileImage (\r
1992 ToolInputFile,\r
e4ac870f
LG
1993 (CHAR8*) SectionBuffer + DataOffset,\r
1994 BufferLength - DataOffset\r
f51461c8
LG
1995 );\r
1996\r
1997 system (SystemCommand);\r
1998 remove (ToolInputFile);\r
1999 free (ToolInputFile);\r
2000\r
2001 Status =\r
2002 GetFileImage (\r
2003 ToolOutputFile,\r
2004 (CHAR8 **)&ToolOutputBuffer,\r
2005 &ToolOutputLength\r
2006 );\r
2007 remove (ToolOutputFile);\r
2008 free (ToolOutputFile);\r
9dd00cb6 2009 free (SystemCommand);\r
f51461c8
LG
2010 if (EFI_ERROR (Status)) {\r
2011 Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);\r
2012 return EFI_SECTION_ERROR;\r
2013 }\r
2014\r
2015 Status = ParseSection (\r
2016 ToolOutputBuffer,\r
2017 ToolOutputLength\r
2018 );\r
2019 if (EFI_ERROR (Status)) {\r
2020 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);\r
2021 return EFI_SECTION_ERROR;\r
2022 }\r
2023\r
2024 //\r
2025 // Check for CRC32 sections which we can handle internally if needed.\r
2026 //\r
2027 } else if (!CompareGuid (\r
e4ac870f 2028 EfiGuid,\r
f51461c8
LG
2029 &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
2030 )\r
2031 ) {\r
2032 //\r
2033 // CRC32 guided section\r
2034 //\r
2035 Status = ParseSection (\r
e4ac870f
LG
2036 SectionBuffer + DataOffset,\r
2037 BufferLength - DataOffset\r
f51461c8
LG
2038 );\r
2039 if (EFI_ERROR (Status)) {\r
2040 Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);\r
2041 return EFI_SECTION_ERROR;\r
2042 }\r
2043 } else {\r
2044 //\r
2045 // We don't know how to parse it now.\r
2046 //\r
2047 Error (NULL, 0, 0003, "Error parsing section", \\r
2048 "EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in GuidedSectionTools.txt (built in the FV directory).");\r
2049 return EFI_UNSUPPORTED;\r
2050 }\r
2051 break;\r
2052\r
2053 default:\r
2054 //\r
2055 // Unknown section, return error\r
2056 //\r
2057 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);\r
2058 return EFI_SECTION_ERROR;\r
2059 }\r
2060\r
2061 ParsedLength += SectionLength;\r
2062 //\r
2063 // We make then next section begin on a 4-byte boundary\r
2064 //\r
2065 ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
2066 }\r
2067\r
2068 if (ParsedLength < BufferLength) {\r
2069 Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);\r
2070 return EFI_SECTION_ERROR;\r
2071 }\r
2072\r
2073 return EFI_SUCCESS;\r
2074}\r
2075\r
2076EFI_STATUS\r
2077DumpDepexSection (\r
2078 IN UINT8 *Ptr,\r
2079 IN UINT32 SectionLength\r
2080 )\r
2081/*++\r
2082\r
2083Routine Description:\r
2084\r
2085 GC_TODO: Add function description\r
2086\r
2087Arguments:\r
2088\r
2089 Ptr - GC_TODO: add argument description\r
2090 SectionLength - GC_TODO: add argument description\r
2091\r
2092Returns:\r
2093\r
2094 EFI_SUCCESS - GC_TODO: Add description for return value\r
2095\r
2096--*/\r
2097{\r
2098 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
2099\r
2100 //\r
2101 // Need at least a section header + data\r
2102 //\r
2103 if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {\r
2104 return EFI_SUCCESS;\r
2105 }\r
2106\r
e4ac870f
LG
2107 Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
2108 SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
f51461c8
LG
2109 while (SectionLength > 0) {\r
2110 printf (" ");\r
2111 switch (*Ptr) {\r
2112 case EFI_DEP_BEFORE:\r
2113 printf ("BEFORE\n");\r
2114 Ptr++;\r
2115 SectionLength--;\r
2116 break;\r
2117\r
2118 case EFI_DEP_AFTER:\r
2119 printf ("AFTER\n");\r
2120 Ptr++;\r
2121 SectionLength--;\r
2122 break;\r
2123\r
2124 case EFI_DEP_PUSH:\r
2125 printf ("PUSH\n ");\r
2126 PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);\r
2127 printf ("%s ", GuidBuffer);\r
2128 PrintGuidName (GuidBuffer);\r
2129 printf ("\n");\r
2130 //\r
2131 // PrintGuid ((EFI_GUID *)(Ptr + 1));\r
2132 //\r
2133 Ptr += 17;\r
2134 SectionLength -= 17;\r
2135 break;\r
2136\r
2137 case EFI_DEP_AND:\r
2138 printf ("AND\n");\r
2139 Ptr++;\r
2140 SectionLength--;\r
2141 break;\r
2142\r
2143 case EFI_DEP_OR:\r
2144 printf ("OR\n");\r
2145 Ptr++;\r
2146 SectionLength--;\r
2147 break;\r
2148\r
2149 case EFI_DEP_NOT:\r
2150 printf ("NOT\n");\r
2151 Ptr++;\r
2152 SectionLength--;\r
2153 break;\r
2154\r
2155 case EFI_DEP_TRUE:\r
2156 printf ("TRUE\n");\r
2157 Ptr++;\r
2158 SectionLength--;\r
2159 break;\r
2160\r
2161 case EFI_DEP_FALSE:\r
2162 printf ("FALSE\n");\r
2163 Ptr++;\r
2164 SectionLength--;\r
2165 break;\r
2166\r
2167 case EFI_DEP_END:\r
2168 printf ("END DEPEX\n");\r
2169 Ptr++;\r
2170 SectionLength--;\r
2171 break;\r
2172\r
2173 case EFI_DEP_SOR:\r
2174 printf ("SOR\n");\r
2175 Ptr++;\r
2176 SectionLength--;\r
2177 break;\r
2178\r
2179 default:\r
2180 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);\r
2181 return EFI_SUCCESS;\r
2182 }\r
2183 }\r
2184\r
2185 return EFI_SUCCESS;\r
2186}\r
2187\r
2188EFI_STATUS\r
2189PrintGuidName (\r
2190 IN UINT8 *GuidStr\r
2191 )\r
2192/*++\r
2193\r
2194Routine Description:\r
2195\r
2196 GC_TODO: Add function description\r
2197\r
2198Arguments:\r
2199\r
2200 GuidStr - GC_TODO: add argument description\r
2201\r
2202Returns:\r
2203\r
2204 EFI_SUCCESS - GC_TODO: Add description for return value\r
2205 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
2206\r
2207--*/\r
2208{\r
2209 GUID_TO_BASENAME *GPtr;\r
2210 //\r
2211 // If we have a list of guid-to-basenames, then go through the list to\r
2212 // look for a guid string match. If found, print the basename to stdout,\r
2213 // otherwise return a failure.\r
2214 //\r
2215 GPtr = mGuidBaseNameList;\r
2216 while (GPtr != NULL) {\r
2217 if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {\r
2218 printf ("%s", GPtr->BaseName);\r
2219 return EFI_SUCCESS;\r
2220 }\r
2221\r
2222 GPtr = GPtr->Next;\r
2223 }\r
2224\r
2225 return EFI_INVALID_PARAMETER;\r
2226}\r
2227\r
2228EFI_STATUS\r
2229ParseGuidBaseNameFile (\r
2230 CHAR8 *FileName\r
2231 )\r
2232/*++\r
2233\r
2234Routine Description:\r
2235\r
2236 GC_TODO: Add function description\r
2237\r
2238Arguments:\r
2239\r
2240 FileName - GC_TODO: add argument description\r
2241\r
2242Returns:\r
2243\r
2244 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
2245 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value\r
2246 EFI_SUCCESS - GC_TODO: Add description for return value\r
2247\r
2248--*/\r
2249{\r
2250 FILE *Fptr;\r
2251 CHAR8 Line[MAX_LINE_LEN];\r
a9b4ee43 2252 CHAR8 FormatString[MAX_LINE_LEN];\r
f51461c8
LG
2253 GUID_TO_BASENAME *GPtr;\r
2254\r
97fa0ee9 2255 if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {\r
f51461c8
LG
2256 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);\r
2257 return EFI_DEVICE_ERROR;\r
2258 }\r
2259\r
d6a1ce3b
HW
2260 //\r
2261 // Generate the format string for fscanf\r
2262 //\r
a9b4ee43 2263 sprintf (\r
d6a1ce3b 2264 FormatString,\r
d6a1ce3b
HW
2265 "%%%us %%%us",\r
2266 (unsigned) sizeof (GPtr->Guid) - 1,\r
2267 (unsigned) sizeof (GPtr->BaseName) - 1\r
2268 );\r
2269\r
f51461c8
LG
2270 while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
2271 //\r
2272 // Allocate space for another guid/basename element\r
2273 //\r
2274 GPtr = malloc (sizeof (GUID_TO_BASENAME));\r
2275 if (GPtr == NULL) {\r
2a9afe80 2276 fclose (Fptr);\r
f51461c8
LG
2277 return EFI_OUT_OF_RESOURCES;\r
2278 }\r
2279\r
2280 memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));\r
d6a1ce3b 2281 if (sscanf (Line, FormatString, GPtr->Guid, GPtr->BaseName) == 2) {\r
f51461c8
LG
2282 GPtr->Next = mGuidBaseNameList;\r
2283 mGuidBaseNameList = GPtr;\r
2284 } else {\r
2285 //\r
2286 // Some sort of error. Just continue.\r
2287 //\r
2288 free (GPtr);\r
2289 }\r
2290 }\r
2291\r
2292 fclose (Fptr);\r
2293 return EFI_SUCCESS;\r
2294}\r
2295\r
2296EFI_STATUS\r
2297FreeGuidBaseNameList (\r
2298 VOID\r
2299 )\r
2300/*++\r
2301\r
2302Routine Description:\r
2303\r
2304 GC_TODO: Add function description\r
2305\r
2306Arguments:\r
2307\r
2308 None\r
2309\r
2310Returns:\r
2311\r
2312 EFI_SUCCESS - GC_TODO: Add description for return value\r
2313\r
2314--*/\r
2315{\r
2316 GUID_TO_BASENAME *Next;\r
2317\r
2318 while (mGuidBaseNameList != NULL) {\r
2319 Next = mGuidBaseNameList->Next;\r
2320 free (mGuidBaseNameList);\r
2321 mGuidBaseNameList = Next;\r
2322 }\r
2323\r
2324 return EFI_SUCCESS;\r
2325}\r
2326\r
2327\r
2328static\r
2329VOID\r
2330LoadGuidedSectionToolsTxt (\r
2331 IN CHAR8* FirmwareVolumeFilename\r
2332 )\r
2333{\r
2334 CHAR8* PeerFilename;\r
2335 CHAR8* Places[] = {\r
2336 NULL,\r
2337 //NULL,\r
2338 };\r
2339 UINTN Index;\r
2340\r
2341 Places[0] = FirmwareVolumeFilename;\r
2342 //Places[1] = mUtilityFilename;\r
2343\r
2344 mParsedGuidedSectionTools = NULL;\r
2345\r
2346 for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {\r
2347 PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");\r
2348 //printf("Loading %s...\n", PeerFilename);\r
2349 if (OsPathExists (PeerFilename)) {\r
2350 mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);\r
2351 }\r
2352 free (PeerFilename);\r
2353 if (mParsedGuidedSectionTools != NULL) {\r
2354 return;\r
2355 }\r
2356 }\r
2357}\r
2358\r
2359\r
2360void\r
2361Usage (\r
2362 VOID\r
2363 )\r
2364/*++\r
2365\r
2366Routine Description:\r
2367\r
2368 GC_TODO: Add function description\r
2369\r
2370Arguments:\r
2371\r
2372 None\r
2373\r
2374Returns:\r
2375\r
2376 GC_TODO: add return values\r
2377\r
2378--*/\r
2379{\r
2380 //\r
2381 // Summary usage\r
2382 //\r
2383 fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);\r
2384\r
2385 //\r
2386 // Copyright declaration\r
2387 // \r
45258285 2388 fprintf (stdout, "Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.\n\n");\r
f4260465 2389 fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");\r
f51461c8
LG
2390\r
2391 //\r
2392 // Details Option\r
2393 //\r
730ffca1 2394 fprintf (stdout, "optional arguments:\n");\r
f51461c8 2395 fprintf (stdout, " -h, --help\n\\r
730ffca1
YZ
2396 Show this help message and exit\n");\r
2397 fprintf (stdout, " --version\n\\r
2398 Show program's version number and exit\n");\r
2399 fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\\r
2400 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");\r
2401 fprintf (stdout, " -v, --verbose\n\\r
2402 Print informational statements\n");\r
2403 fprintf (stdout, " -q, --quiet\n\\r
2404 Returns the exit code, error messages will be displayed\n");\r
2405 fprintf (stdout, " -s, --silent\n\\r
2406 Returns only the exit code; informational and error\n\\r
2407 messages are not displayed\n");\r
2408 fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\\r
2409 Parse the basename to file-guid cross reference file(s)\n");\r
2410 fprintf (stdout, " -f OFFSET, --offset OFFSET\n\\r
2411 The offset from the start of the input file to start \n\\r
2412 processing an FV\n");\r
9947f576
YZ
2413 fprintf (stdout, " --hash\n\\r
2414 Generate HASH value of the entire PE image\n");\r
730ffca1
YZ
2415 fprintf (stdout, " --sfo\n\\r
2416 Reserved for future use\n");\r
f51461c8
LG
2417}\r
2418\r