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