]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VolInfo/VolInfo.c
BaseTools/VolInfo: Update EFI FV FILETYPES for new MM types.
[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
cb004eb0
EG
1307 case EFI_FV_FILETYPE_MM_STANDALONE:\r
1308 printf ("EFI_FV_FILETYPE_MM_STANDALONE\n");\r
1309 break;\r
1310\r
1311 case EFI_FV_FILETYPE_MM_CORE_STANDALONE:\r
1312 printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n");\r
1313 break;\r
1314\r
f51461c8
LG
1315 case EFI_FV_FILETYPE_FFS_PAD:\r
1316 printf ("EFI_FV_FILETYPE_FFS_PAD\n");\r
1317 break;\r
1318\r
1319 default:\r
1320 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);\r
1321 return EFI_ABORTED;\r
1322 break;\r
1323 }\r
1324\r
1325 switch (FileHeader->Type) {\r
1326\r
1327 case EFI_FV_FILETYPE_ALL:\r
1328 case EFI_FV_FILETYPE_RAW:\r
1329 case EFI_FV_FILETYPE_FFS_PAD:\r
1330 break;\r
1331\r
1332 default:\r
1333 //\r
1334 // All other files have sections\r
1335 //\r
1336 Status = ParseSection (\r
e4ac870f
LG
1337 (UINT8 *) ((UINTN) FileHeader + HeaderSize),\r
1338 FvBufGetFfsFileSize (FileHeader) - HeaderSize\r
f51461c8
LG
1339 );\r
1340 if (EFI_ERROR (Status)) {\r
1341 //\r
1342 // printf ("ERROR: Parsing the FFS file.\n");\r
1343 //\r
1344 return EFI_ABORTED;\r
1345 }\r
1346 break;\r
1347 }\r
1348\r
1349 return EFI_SUCCESS;\r
1350}\r
1351\r
9947f576
YZ
1352EFI_STATUS\r
1353RebaseImageRead (\r
1354 IN VOID *FileHandle,\r
1355 IN UINTN FileOffset,\r
1356 IN OUT UINT32 *ReadSize,\r
1357 OUT VOID *Buffer\r
1358 )\r
1359/*++\r
1360\r
1361Routine Description:\r
1362\r
1363 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
1364\r
1365Arguments:\r
1366\r
1367 FileHandle - The handle to the PE/COFF file\r
1368\r
1369 FileOffset - The offset, in bytes, into the file to read\r
1370\r
1371 ReadSize - The number of bytes to read from the file starting at FileOffset\r
1372\r
1373 Buffer - A pointer to the buffer to read the data into.\r
1374\r
1375Returns:\r
1376\r
1377 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
1378\r
1379--*/\r
1380{\r
1381 CHAR8 *Destination8;\r
1382 CHAR8 *Source8;\r
1383 UINT32 Length;\r
1384\r
1385 Destination8 = Buffer;\r
1386 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
1387 Length = *ReadSize;\r
1388 while (Length--) {\r
1389 *(Destination8++) = *(Source8++);\r
1390 }\r
1391\r
1392 return EFI_SUCCESS;\r
1393}\r
1394\r
1395EFI_STATUS\r
1396SetAddressToSectionHeader (\r
1397 IN CHAR8 *FileName,\r
1398 IN OUT UINT8 *FileBuffer,\r
1399 IN UINT64 NewPe32BaseAddress\r
1400 )\r
1401/*++\r
1402\r
1403Routine Description:\r
1404\r
1405 Set new base address into the section header of PeImage\r
1406\r
1407Arguments:\r
1408\r
1409 FileName - Name of file\r
1410 FileBuffer - Pointer to PeImage.\r
1411 NewPe32BaseAddress - New Base Address for PE image.\r
1412\r
1413Returns:\r
1414\r
1415 EFI_SUCCESS Set new base address into this image successfully.\r
1416\r
1417--*/\r
1418{\r
1419 EFI_STATUS Status;\r
1420 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1421 UINTN Index;\r
1422 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1423 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1424\r
1425 //\r
1426 // Initialize context\r
1427 //\r
1428 memset (&ImageContext, 0, sizeof (ImageContext));\r
1429 ImageContext.Handle = (VOID *) FileBuffer;\r
1430 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1431 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1432 if (EFI_ERROR (Status)) {\r
1433 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1434 return Status;\r
1435 }\r
1436\r
1437 if (ImageContext.RelocationsStripped) {\r
1438 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1439 return Status;\r
1440 }\r
1441\r
1442 //\r
1443 // Get PeHeader pointer\r
1444 //\r
1445 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1446\r
1447 //\r
1448 // Get section header list\r
1449 //\r
1450 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1451 (UINTN) ImgHdr +\r
1452 sizeof (UINT32) +\r
1453 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1454 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1455 );\r
1456\r
1457 //\r
1458 // Set base address into the first section header that doesn't point to code section.\r
1459 //\r
1460 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1461 if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
1462 *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;\r
1463 break;\r
1464 }\r
1465 }\r
1466\r
9947f576
YZ
1467 //\r
1468 // BaseAddress is set to section header.\r
1469 //\r
1470 return EFI_SUCCESS;\r
1471}\r
1472\r
1473EFI_STATUS\r
1474RebaseImage (\r
1475 IN CHAR8 *FileName,\r
1476 IN OUT UINT8 *FileBuffer,\r
1477 IN UINT64 NewPe32BaseAddress\r
1478 )\r
1479/*++\r
1480\r
1481Routine Description:\r
1482\r
1483 Set new base address into PeImage, and fix up PeImage based on new address.\r
1484\r
1485Arguments:\r
1486\r
1487 FileName - Name of file\r
1488 FileBuffer - Pointer to PeImage.\r
1489 NewPe32BaseAddress - New Base Address for PE image.\r
1490\r
1491Returns:\r
1492\r
1493 EFI_INVALID_PARAMETER - BaseAddress is not valid.\r
1494 EFI_SUCCESS - Update PeImage is correctly.\r
1495\r
1496--*/\r
1497{\r
1498 EFI_STATUS Status;\r
1499 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1500 UINTN Index;\r
1501 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1502 UINT8 *MemoryImagePointer;\r
1503 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1504\r
1505 //\r
1506 // Initialize context\r
1507 //\r
1508 memset (&ImageContext, 0, sizeof (ImageContext));\r
1509 ImageContext.Handle = (VOID *) FileBuffer;\r
1510 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1511 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1512 if (EFI_ERROR (Status)) {\r
1513 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1514 return Status;\r
1515 }\r
1516\r
1517 if (ImageContext.RelocationsStripped) {\r
1518 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1519 return Status;\r
1520 }\r
1521\r
1522 //\r
1523 // Get PeHeader pointer\r
1524 //\r
1525 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1526\r
1527 //\r
1528 // Load and Relocate Image Data\r
1529 //\r
1530 MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1531 if (MemoryImagePointer == NULL) {\r
1532 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
1533 return EFI_OUT_OF_RESOURCES;\r
1534 }\r
1535 memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1536 ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
1537\r
1538 Status = PeCoffLoaderLoadImage (&ImageContext);\r
1539 if (EFI_ERROR (Status)) {\r
1540 Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
1541 free ((VOID *) MemoryImagePointer);\r
1542 return Status;\r
1543 }\r
1544\r
1545 ImageContext.DestinationAddress = NewPe32BaseAddress;\r
1546 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
1547 if (EFI_ERROR (Status)) {\r
1548 Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
1549 free ((VOID *) MemoryImagePointer);\r
1550 return Status;\r
1551 }\r
1552\r
1553 //\r
1554 // Copy Relocated data to raw image file.\r
1555 //\r
1556 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1557 (UINTN) ImgHdr +\r
1558 sizeof (UINT32) +\r
1559 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1560 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1561 );\r
1562\r
1563 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1564 CopyMem (\r
1565 FileBuffer + SectionHeader->PointerToRawData,\r
1566 (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),\r
1567 SectionHeader->SizeOfRawData\r
1568 );\r
1569 }\r
1570\r
1571 free ((VOID *) MemoryImagePointer);\r
1572\r
1573 //\r
1574 // Update Image Base Address\r
1575 //\r
1576 if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
1577 ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
1578 } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
1579 ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
1580 } else {\r
1581 Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
1582 ImgHdr->Pe32.OptionalHeader.Magic,\r
1583 FileName\r
1584 );\r
1585 return EFI_ABORTED;\r
1586 }\r
1587\r
1588 //\r
1589 // Set new base address into section header\r
1590 //\r
1591 Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);\r
1592\r
1593 return Status;\r
1594}\r
1595\r
1596EFI_STATUS\r
1597CombinePath (\r
1598 IN CHAR8* DefaultPath,\r
1599 IN CHAR8* AppendPath,\r
1600 OUT CHAR8* NewPath\r
1601)\r
1602{\r
1603 UINT32 DefaultPathLen;\r
8994d2f9 1604 UINT64 Index;\r
3337eefb
YZ
1605 CHAR8 QuotesStr[] = "\"";\r
1606 strcpy(NewPath, QuotesStr);\r
9947f576 1607 DefaultPathLen = strlen(DefaultPath);\r
3337eefb 1608 strcat(NewPath, DefaultPath);\r
8994d2f9 1609 Index = 0;\r
3337eefb 1610 for (; Index < DefaultPathLen + 1; Index ++) {\r
9947f576
YZ
1611 if (NewPath[Index] == '\\' || NewPath[Index] == '/') {\r
1612 if (NewPath[Index + 1] != '\0') {\r
1613 NewPath[Index] = '/';\r
1614 }\r
1615 }\r
1616 }\r
1617 if (NewPath[Index -1] != '/') {\r
1618 NewPath[Index] = '/';\r
1619 NewPath[Index + 1] = '\0';\r
1620 }\r
1621 strcat(NewPath, AppendPath);\r
3337eefb 1622 strcat(NewPath, QuotesStr);\r
9947f576
YZ
1623 return EFI_SUCCESS;\r
1624}\r
1625\r
f51461c8
LG
1626EFI_STATUS\r
1627ParseSection (\r
1628 IN UINT8 *SectionBuffer,\r
1629 IN UINT32 BufferLength\r
1630 )\r
1631/*++\r
1632\r
1633Routine Description:\r
1634\r
1635 Parses EFI Sections\r
1636\r
1637Arguments:\r
1638\r
1639 SectionBuffer - Buffer containing the section to parse.\r
1640 BufferLength - Length of SectionBuffer\r
1641\r
1642Returns:\r
1643\r
1644 EFI_SECTION_ERROR - Problem with section parsing.\r
1645 (a) compression errors\r
1646 (b) unrecognized section \r
1647 EFI_UNSUPPORTED - Do not know how to parse the section.\r
1648 EFI_SUCCESS - Section successfully parsed.\r
1649 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1650\r
1651--*/\r
1652{\r
1653 EFI_SECTION_TYPE Type;\r
1654 UINT8 *Ptr;\r
1655 UINT32 SectionLength;\r
e4ac870f 1656 UINT32 SectionHeaderLen;\r
f51461c8
LG
1657 CHAR8 *SectionName;\r
1658 EFI_STATUS Status;\r
1659 UINT32 ParsedLength;\r
1660 UINT8 *CompressedBuffer;\r
1661 UINT32 CompressedLength;\r
1662 UINT8 *UncompressedBuffer;\r
1663 UINT32 UncompressedLength;\r
1664 UINT8 *ToolOutputBuffer;\r
1665 UINT32 ToolOutputLength;\r
1666 UINT8 CompressionType;\r
1667 UINT32 DstSize;\r
1668 UINT32 ScratchSize;\r
1669 UINT8 *ScratchBuffer;\r
1670 DECOMPRESS_FUNCTION DecompressFunction;\r
1671 GETINFO_FUNCTION GetInfoFunction;\r
1672 // CHAR16 *name;\r
1673 CHAR8 *ExtractionTool;\r
1674 CHAR8 *ToolInputFile;\r
1675 CHAR8 *ToolOutputFile;\r
f51461c8 1676 CHAR8 *SystemCommand;\r
e4ac870f
LG
1677 EFI_GUID *EfiGuid;\r
1678 UINT16 DataOffset;\r
1679 UINT16 Attributes;\r
1680 UINT32 RealHdrLen;\r
9947f576
YZ
1681 CHAR8 *ToolInputFileName;\r
1682 CHAR8 *ToolOutputFileName;\r
3883e2cb 1683 CHAR8 *UIFileName;\r
f51461c8
LG
1684\r
1685 ParsedLength = 0;\r
9947f576
YZ
1686 ToolInputFileName = NULL;\r
1687 ToolOutputFileName = NULL;\r
1688\r
f51461c8
LG
1689 while (ParsedLength < BufferLength) {\r
1690 Ptr = SectionBuffer + ParsedLength;\r
1691\r
1692 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
1693 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
1694\r
1695 //\r
1696 // This is sort of an odd check, but is necessary because FFS files are\r
1697 // padded to a QWORD boundary, meaning there is potentially a whole section\r
1698 // header worth of 0xFF bytes.\r
1699 //\r
1700 if (SectionLength == 0xffffff && Type == 0xff) {\r
1701 ParsedLength += 4;\r
1702 continue;\r
1703 }\r
1704\r
e4ac870f
LG
1705 //\r
1706 // Get real section file size\r
1707 //\r
1708 SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);\r
1709 SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1710\r
f51461c8 1711 SectionName = SectionNameToStr (Type);\r
9dd00cb6
HW
1712 if (SectionName != NULL) {\r
1713 printf ("------------------------------------------------------------\n");\r
1714 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);\r
1715 free (SectionName);\r
1716 }\r
f51461c8
LG
1717\r
1718 switch (Type) {\r
1719 case EFI_SECTION_RAW:\r
f51461c8
LG
1720 case EFI_SECTION_PIC:\r
1721 case EFI_SECTION_TE:\r
1722 // default is no more information\r
1723 break;\r
1724\r
9947f576
YZ
1725 case EFI_SECTION_PE32:\r
1726 if (EnableHash) {\r
1727 ToolInputFileName = "edk2Temp_InputEfi.tmp";\r
1728 ToolOutputFileName = "edk2Temp_OutputHash.tmp";\r
1729 RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);\r
1730 PutFileImage (\r
1731 ToolInputFileName,\r
1732 (CHAR8*)Ptr + SectionHeaderLen,\r
1733 SectionLength - SectionHeaderLen\r
1734 );\r
1735\r
9947f576 1736 SystemCommand = malloc (\r
aeadb1c4 1737 strlen (OPENSSL_COMMAND_FORMAT_STRING) +\r
9947f576
YZ
1738 strlen (OpenSslPath) +\r
1739 strlen (ToolInputFileName) +\r
1740 strlen (ToolOutputFileName) +\r
1741 1\r
1742 );\r
9dd00cb6
HW
1743 if (SystemCommand == NULL) {\r
1744 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1745 return EFI_OUT_OF_RESOURCES;\r
1746 }\r
9947f576
YZ
1747 sprintf (\r
1748 SystemCommand,\r
aeadb1c4 1749 OPENSSL_COMMAND_FORMAT_STRING,\r
9947f576
YZ
1750 OpenSslPath,\r
1751 ToolOutputFileName,\r
1752 ToolInputFileName\r
1753 );\r
1754\r
1755 if (system (SystemCommand) != EFI_SUCCESS) {\r
1756 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
1757 }\r
1758 else {\r
1759 FILE *fp;\r
1760 CHAR8 *StrLine;\r
1761 CHAR8 *NewStr;\r
1762 UINT32 nFileLen;\r
1763 if((fp = fopen(ToolOutputFileName,"r")) == NULL) {\r
1764 Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);\r
1765 }\r
1766 else {\r
1767 fseek(fp,0,SEEK_SET);\r
1768 fseek(fp,0,SEEK_END);\r
1769 nFileLen = ftell(fp);\r
1770 fseek(fp,0,SEEK_SET);\r
1771 StrLine = malloc(nFileLen);\r
9dd00cb6
HW
1772 if (StrLine == NULL) {\r
1773 fclose(fp);\r
1774 free (SystemCommand);\r
1775 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1776 return EFI_OUT_OF_RESOURCES;\r
1777 }\r
9947f576
YZ
1778 fgets(StrLine, nFileLen, fp);\r
1779 NewStr = strrchr (StrLine, '=');\r
1780 printf (" SHA1: %s\n", NewStr + 1);\r
1781 free (StrLine);\r
9dd00cb6 1782 fclose(fp);\r
9947f576 1783 }\r
9947f576
YZ
1784 }\r
1785 remove(ToolInputFileName);\r
1786 remove(ToolOutputFileName);\r
1787 free (SystemCommand);\r
1788 }\r
1789 break;\r
1790\r
f51461c8 1791 case EFI_SECTION_USER_INTERFACE:\r
3883e2cb
HW
1792 UIFileName = (CHAR8 *) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString) + 1);\r
1793 if (UIFileName == NULL) {\r
1794 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1795 return EFI_OUT_OF_RESOURCES;\r
1796 }\r
1797 Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UIFileName);\r
1798 printf (" String: %s\n", UIFileName);\r
1799 free (UIFileName);\r
f51461c8
LG
1800 break;\r
1801\r
1802 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
e4ac870f 1803 Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);\r
f51461c8
LG
1804 if (EFI_ERROR (Status)) {\r
1805 Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);\r
1806 return EFI_SECTION_ERROR;\r
1807 }\r
1808 break;\r
1809\r
1810 case EFI_SECTION_COMPATIBILITY16:\r
1811 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
1812 //\r
1813 // Section does not contain any further header information.\r
1814 //\r
1815 break;\r
1816\r
1817 case EFI_SECTION_PEI_DEPEX:\r
1818 case EFI_SECTION_DXE_DEPEX:\r
1819 case EFI_SECTION_SMM_DEPEX:\r
1820 DumpDepexSection (Ptr, SectionLength);\r
1821 break;\r
1822\r
1823 case EFI_SECTION_VERSION:\r
e4ac870f
LG
1824 printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));\r
1825 printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));\r
f51461c8
LG
1826 break;\r
1827\r
1828 case EFI_SECTION_COMPRESSION:\r
1829 UncompressedBuffer = NULL;\r
e4ac870f
LG
1830 if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1831 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);\r
1832 UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;\r
1833 CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;\r
1834 } else {\r
1835 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);\r
1836 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;\r
1837 CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;\r
1838 }\r
1839 CompressedLength = SectionLength - RealHdrLen;\r
f51461c8
LG
1840 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);\r
1841\r
1842 if (CompressionType == EFI_NOT_COMPRESSED) {\r
1843 printf (" Compression Type: EFI_NOT_COMPRESSED\n");\r
1844 if (CompressedLength != UncompressedLength) {\r
1845 Error (\r
1846 NULL,\r
1847 0,\r
1848 0,\r
1849 "file is not compressed, but the compressed length does not match the uncompressed length",\r
1850 NULL\r
1851 );\r
1852 return EFI_SECTION_ERROR;\r
1853 }\r
1854\r
e4ac870f 1855 UncompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1856 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1857 GetInfoFunction = EfiGetInfo;\r
1858 DecompressFunction = EfiDecompress;\r
1859 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");\r
1860\r
e4ac870f 1861 CompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1862\r
1863 Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);\r
1864 if (EFI_ERROR (Status)) {\r
1865 Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);\r
1866 return EFI_SECTION_ERROR;\r
1867 }\r
1868\r
1869 if (DstSize != UncompressedLength) {\r
1870 Error (NULL, 0, 0003, "compression error in the compression section", NULL);\r
1871 return EFI_SECTION_ERROR;\r
1872 }\r
1873\r
1874 ScratchBuffer = malloc (ScratchSize);\r
85006654
HW
1875 if (ScratchBuffer == NULL) {\r
1876 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1877 return EFI_OUT_OF_RESOURCES;\r
1878 }\r
f51461c8 1879 UncompressedBuffer = malloc (UncompressedLength);\r
85006654
HW
1880 if (UncompressedBuffer == NULL) {\r
1881 free (ScratchBuffer);\r
1882 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
f51461c8
LG
1883 return EFI_OUT_OF_RESOURCES;\r
1884 }\r
1885 Status = DecompressFunction (\r
1886 CompressedBuffer,\r
1887 CompressedLength,\r
1888 UncompressedBuffer,\r
1889 UncompressedLength,\r
1890 ScratchBuffer,\r
1891 ScratchSize\r
1892 );\r
1893 free (ScratchBuffer);\r
1894 if (EFI_ERROR (Status)) {\r
1895 Error (NULL, 0, 0003, "decompress failed", NULL);\r
1896 free (UncompressedBuffer);\r
1897 return EFI_SECTION_ERROR;\r
1898 }\r
1899 } else {\r
1900 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);\r
1901 return EFI_SECTION_ERROR;\r
1902 }\r
1903\r
1904 Status = ParseSection (UncompressedBuffer, UncompressedLength);\r
1905\r
1906 if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1907 //\r
1908 // We need to deallocate Buffer\r
1909 //\r
1910 free (UncompressedBuffer);\r
1911 }\r
1912\r
1913 if (EFI_ERROR (Status)) {\r
1914 Error (NULL, 0, 0003, "failed to parse section", NULL);\r
1915 return EFI_SECTION_ERROR;\r
1916 }\r
1917 break;\r
1918\r
1919 case EFI_SECTION_GUID_DEFINED:\r
e4ac870f
LG
1920 if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {\r
1921 EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;\r
1922 DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;\r
1923 Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;\r
1924 } else {\r
1925 EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;\r
1926 DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;\r
1927 Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;\r
1928 }\r
f51461c8 1929 printf (" SectionDefinitionGuid: ");\r
e4ac870f 1930 PrintGuid (EfiGuid);\r
f51461c8 1931 printf ("\n");\r
e4ac870f
LG
1932 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);\r
1933 printf (" Attributes: 0x%04X\n", (unsigned) Attributes);\r
f51461c8
LG
1934\r
1935 ExtractionTool =\r
1936 LookupGuidedSectionToolPath (\r
1937 mParsedGuidedSectionTools,\r
e4ac870f 1938 EfiGuid\r
f51461c8
LG
1939 );\r
1940\r
1941 if (ExtractionTool != NULL) {\r
868c9c35 1942 #ifndef __GNUC__\r
f51461c8
LG
1943 ToolInputFile = CloneString (tmpnam (NULL));\r
1944 ToolOutputFile = CloneString (tmpnam (NULL));\r
868c9c35
YZ
1945 #else\r
1946 char tmp1[] = "/tmp/fileXXXXXX";\r
1947 char tmp2[] = "/tmp/fileXXXXXX";\r
1948 int fd1;\r
1949 int fd2;\r
1950 fd1 = mkstemp(tmp1);\r
1951 fd2 = mkstemp(tmp2);\r
1952 ToolInputFile = CloneString(tmp1);\r
1953 ToolOutputFile = CloneString(tmp2);\r
1954 close(fd1);\r
1955 close(fd2);\r
1956 #endif\r
f51461c8 1957\r
9dd00cb6
HW
1958 if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) {\r
1959 if (ToolInputFile != NULL) {\r
1960 free (ToolInputFile);\r
1961 }\r
1962 if (ToolOutputFile != NULL) {\r
1963 free (ToolOutputFile);\r
1964 }\r
1965 free (ExtractionTool);\r
1966\r
1967 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1968 return EFI_OUT_OF_RESOURCES;\r
1969 }\r
1970\r
f51461c8
LG
1971 //\r
1972 // Construction 'system' command string\r
1973 //\r
f51461c8 1974 SystemCommand = malloc (\r
aeadb1c4 1975 strlen (EXTRACT_COMMAND_FORMAT_STRING) +\r
f51461c8
LG
1976 strlen (ExtractionTool) +\r
1977 strlen (ToolInputFile) +\r
1978 strlen (ToolOutputFile) +\r
1979 1\r
1980 );\r
9dd00cb6
HW
1981 if (SystemCommand == NULL) {\r
1982 free (ToolInputFile);\r
1983 free (ToolOutputFile);\r
1984 free (ExtractionTool);\r
1985\r
1986 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1987 return EFI_OUT_OF_RESOURCES;\r
1988 }\r
f51461c8
LG
1989 sprintf (\r
1990 SystemCommand,\r
aeadb1c4 1991 EXTRACT_COMMAND_FORMAT_STRING,\r
f51461c8
LG
1992 ExtractionTool,\r
1993 ToolOutputFile,\r
1994 ToolInputFile\r
1995 );\r
1996 free (ExtractionTool);\r
1997\r
1998 Status =\r
1999 PutFileImage (\r
2000 ToolInputFile,\r
e4ac870f
LG
2001 (CHAR8*) SectionBuffer + DataOffset,\r
2002 BufferLength - DataOffset\r
f51461c8
LG
2003 );\r
2004\r
2005 system (SystemCommand);\r
2006 remove (ToolInputFile);\r
2007 free (ToolInputFile);\r
2008\r
2009 Status =\r
2010 GetFileImage (\r
2011 ToolOutputFile,\r
2012 (CHAR8 **)&ToolOutputBuffer,\r
2013 &ToolOutputLength\r
2014 );\r
2015 remove (ToolOutputFile);\r
2016 free (ToolOutputFile);\r
9dd00cb6 2017 free (SystemCommand);\r
f51461c8
LG
2018 if (EFI_ERROR (Status)) {\r
2019 Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);\r
2020 return EFI_SECTION_ERROR;\r
2021 }\r
2022\r
2023 Status = ParseSection (\r
2024 ToolOutputBuffer,\r
2025 ToolOutputLength\r
2026 );\r
2027 if (EFI_ERROR (Status)) {\r
2028 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);\r
2029 return EFI_SECTION_ERROR;\r
2030 }\r
2031\r
2032 //\r
2033 // Check for CRC32 sections which we can handle internally if needed.\r
2034 //\r
2035 } else if (!CompareGuid (\r
e4ac870f 2036 EfiGuid,\r
f51461c8
LG
2037 &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
2038 )\r
2039 ) {\r
2040 //\r
2041 // CRC32 guided section\r
2042 //\r
2043 Status = ParseSection (\r
e4ac870f
LG
2044 SectionBuffer + DataOffset,\r
2045 BufferLength - DataOffset\r
f51461c8
LG
2046 );\r
2047 if (EFI_ERROR (Status)) {\r
2048 Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);\r
2049 return EFI_SECTION_ERROR;\r
2050 }\r
2051 } else {\r
2052 //\r
2053 // We don't know how to parse it now.\r
2054 //\r
2055 Error (NULL, 0, 0003, "Error parsing section", \\r
2056 "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
2057 return EFI_UNSUPPORTED;\r
2058 }\r
2059 break;\r
2060\r
2061 default:\r
2062 //\r
2063 // Unknown section, return error\r
2064 //\r
2065 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);\r
2066 return EFI_SECTION_ERROR;\r
2067 }\r
2068\r
2069 ParsedLength += SectionLength;\r
2070 //\r
2071 // We make then next section begin on a 4-byte boundary\r
2072 //\r
2073 ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
2074 }\r
2075\r
2076 if (ParsedLength < BufferLength) {\r
2077 Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);\r
2078 return EFI_SECTION_ERROR;\r
2079 }\r
2080\r
2081 return EFI_SUCCESS;\r
2082}\r
2083\r
2084EFI_STATUS\r
2085DumpDepexSection (\r
2086 IN UINT8 *Ptr,\r
2087 IN UINT32 SectionLength\r
2088 )\r
2089/*++\r
2090\r
2091Routine Description:\r
2092\r
2093 GC_TODO: Add function description\r
2094\r
2095Arguments:\r
2096\r
2097 Ptr - GC_TODO: add argument description\r
2098 SectionLength - GC_TODO: add argument description\r
2099\r
2100Returns:\r
2101\r
2102 EFI_SUCCESS - GC_TODO: Add description for return value\r
2103\r
2104--*/\r
2105{\r
2106 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
2107\r
2108 //\r
2109 // Need at least a section header + data\r
2110 //\r
2111 if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {\r
2112 return EFI_SUCCESS;\r
2113 }\r
2114\r
e4ac870f
LG
2115 Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
2116 SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
f51461c8
LG
2117 while (SectionLength > 0) {\r
2118 printf (" ");\r
2119 switch (*Ptr) {\r
2120 case EFI_DEP_BEFORE:\r
2121 printf ("BEFORE\n");\r
2122 Ptr++;\r
2123 SectionLength--;\r
2124 break;\r
2125\r
2126 case EFI_DEP_AFTER:\r
2127 printf ("AFTER\n");\r
2128 Ptr++;\r
2129 SectionLength--;\r
2130 break;\r
2131\r
2132 case EFI_DEP_PUSH:\r
2133 printf ("PUSH\n ");\r
2134 PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);\r
2135 printf ("%s ", GuidBuffer);\r
2136 PrintGuidName (GuidBuffer);\r
2137 printf ("\n");\r
2138 //\r
2139 // PrintGuid ((EFI_GUID *)(Ptr + 1));\r
2140 //\r
2141 Ptr += 17;\r
2142 SectionLength -= 17;\r
2143 break;\r
2144\r
2145 case EFI_DEP_AND:\r
2146 printf ("AND\n");\r
2147 Ptr++;\r
2148 SectionLength--;\r
2149 break;\r
2150\r
2151 case EFI_DEP_OR:\r
2152 printf ("OR\n");\r
2153 Ptr++;\r
2154 SectionLength--;\r
2155 break;\r
2156\r
2157 case EFI_DEP_NOT:\r
2158 printf ("NOT\n");\r
2159 Ptr++;\r
2160 SectionLength--;\r
2161 break;\r
2162\r
2163 case EFI_DEP_TRUE:\r
2164 printf ("TRUE\n");\r
2165 Ptr++;\r
2166 SectionLength--;\r
2167 break;\r
2168\r
2169 case EFI_DEP_FALSE:\r
2170 printf ("FALSE\n");\r
2171 Ptr++;\r
2172 SectionLength--;\r
2173 break;\r
2174\r
2175 case EFI_DEP_END:\r
2176 printf ("END DEPEX\n");\r
2177 Ptr++;\r
2178 SectionLength--;\r
2179 break;\r
2180\r
2181 case EFI_DEP_SOR:\r
2182 printf ("SOR\n");\r
2183 Ptr++;\r
2184 SectionLength--;\r
2185 break;\r
2186\r
2187 default:\r
2188 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);\r
2189 return EFI_SUCCESS;\r
2190 }\r
2191 }\r
2192\r
2193 return EFI_SUCCESS;\r
2194}\r
2195\r
2196EFI_STATUS\r
2197PrintGuidName (\r
2198 IN UINT8 *GuidStr\r
2199 )\r
2200/*++\r
2201\r
2202Routine Description:\r
2203\r
2204 GC_TODO: Add function description\r
2205\r
2206Arguments:\r
2207\r
2208 GuidStr - GC_TODO: add argument description\r
2209\r
2210Returns:\r
2211\r
2212 EFI_SUCCESS - GC_TODO: Add description for return value\r
2213 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
2214\r
2215--*/\r
2216{\r
2217 GUID_TO_BASENAME *GPtr;\r
2218 //\r
2219 // If we have a list of guid-to-basenames, then go through the list to\r
2220 // look for a guid string match. If found, print the basename to stdout,\r
2221 // otherwise return a failure.\r
2222 //\r
2223 GPtr = mGuidBaseNameList;\r
2224 while (GPtr != NULL) {\r
2225 if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {\r
2226 printf ("%s", GPtr->BaseName);\r
2227 return EFI_SUCCESS;\r
2228 }\r
2229\r
2230 GPtr = GPtr->Next;\r
2231 }\r
2232\r
2233 return EFI_INVALID_PARAMETER;\r
2234}\r
2235\r
2236EFI_STATUS\r
2237ParseGuidBaseNameFile (\r
2238 CHAR8 *FileName\r
2239 )\r
2240/*++\r
2241\r
2242Routine Description:\r
2243\r
2244 GC_TODO: Add function description\r
2245\r
2246Arguments:\r
2247\r
2248 FileName - GC_TODO: add argument description\r
2249\r
2250Returns:\r
2251\r
2252 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
2253 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value\r
2254 EFI_SUCCESS - GC_TODO: Add description for return value\r
2255\r
2256--*/\r
2257{\r
2258 FILE *Fptr;\r
2259 CHAR8 Line[MAX_LINE_LEN];\r
a9b4ee43 2260 CHAR8 FormatString[MAX_LINE_LEN];\r
f51461c8
LG
2261 GUID_TO_BASENAME *GPtr;\r
2262\r
97fa0ee9 2263 if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {\r
f51461c8
LG
2264 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);\r
2265 return EFI_DEVICE_ERROR;\r
2266 }\r
2267\r
d6a1ce3b
HW
2268 //\r
2269 // Generate the format string for fscanf\r
2270 //\r
a9b4ee43 2271 sprintf (\r
d6a1ce3b 2272 FormatString,\r
d6a1ce3b
HW
2273 "%%%us %%%us",\r
2274 (unsigned) sizeof (GPtr->Guid) - 1,\r
2275 (unsigned) sizeof (GPtr->BaseName) - 1\r
2276 );\r
2277\r
f51461c8
LG
2278 while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
2279 //\r
2280 // Allocate space for another guid/basename element\r
2281 //\r
2282 GPtr = malloc (sizeof (GUID_TO_BASENAME));\r
2283 if (GPtr == NULL) {\r
2a9afe80 2284 fclose (Fptr);\r
f51461c8
LG
2285 return EFI_OUT_OF_RESOURCES;\r
2286 }\r
2287\r
2288 memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));\r
d6a1ce3b 2289 if (sscanf (Line, FormatString, GPtr->Guid, GPtr->BaseName) == 2) {\r
f51461c8
LG
2290 GPtr->Next = mGuidBaseNameList;\r
2291 mGuidBaseNameList = GPtr;\r
2292 } else {\r
2293 //\r
2294 // Some sort of error. Just continue.\r
2295 //\r
2296 free (GPtr);\r
2297 }\r
2298 }\r
2299\r
2300 fclose (Fptr);\r
2301 return EFI_SUCCESS;\r
2302}\r
2303\r
2304EFI_STATUS\r
2305FreeGuidBaseNameList (\r
2306 VOID\r
2307 )\r
2308/*++\r
2309\r
2310Routine Description:\r
2311\r
2312 GC_TODO: Add function description\r
2313\r
2314Arguments:\r
2315\r
2316 None\r
2317\r
2318Returns:\r
2319\r
2320 EFI_SUCCESS - GC_TODO: Add description for return value\r
2321\r
2322--*/\r
2323{\r
2324 GUID_TO_BASENAME *Next;\r
2325\r
2326 while (mGuidBaseNameList != NULL) {\r
2327 Next = mGuidBaseNameList->Next;\r
2328 free (mGuidBaseNameList);\r
2329 mGuidBaseNameList = Next;\r
2330 }\r
2331\r
2332 return EFI_SUCCESS;\r
2333}\r
2334\r
2335\r
2336static\r
2337VOID\r
2338LoadGuidedSectionToolsTxt (\r
2339 IN CHAR8* FirmwareVolumeFilename\r
2340 )\r
2341{\r
2342 CHAR8* PeerFilename;\r
2343 CHAR8* Places[] = {\r
2344 NULL,\r
2345 //NULL,\r
2346 };\r
2347 UINTN Index;\r
2348\r
2349 Places[0] = FirmwareVolumeFilename;\r
2350 //Places[1] = mUtilityFilename;\r
2351\r
2352 mParsedGuidedSectionTools = NULL;\r
2353\r
2354 for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {\r
2355 PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");\r
2356 //printf("Loading %s...\n", PeerFilename);\r
2357 if (OsPathExists (PeerFilename)) {\r
2358 mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);\r
2359 }\r
2360 free (PeerFilename);\r
2361 if (mParsedGuidedSectionTools != NULL) {\r
2362 return;\r
2363 }\r
2364 }\r
2365}\r
2366\r
2367\r
2368void\r
2369Usage (\r
2370 VOID\r
2371 )\r
2372/*++\r
2373\r
2374Routine Description:\r
2375\r
2376 GC_TODO: Add function description\r
2377\r
2378Arguments:\r
2379\r
2380 None\r
2381\r
2382Returns:\r
2383\r
2384 GC_TODO: add return values\r
2385\r
2386--*/\r
2387{\r
2388 //\r
2389 // Summary usage\r
2390 //\r
2391 fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);\r
2392\r
2393 //\r
2394 // Copyright declaration\r
2395 // \r
45258285 2396 fprintf (stdout, "Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.\n\n");\r
f4260465 2397 fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");\r
f51461c8
LG
2398\r
2399 //\r
2400 // Details Option\r
2401 //\r
730ffca1 2402 fprintf (stdout, "optional arguments:\n");\r
f51461c8 2403 fprintf (stdout, " -h, --help\n\\r
730ffca1
YZ
2404 Show this help message and exit\n");\r
2405 fprintf (stdout, " --version\n\\r
2406 Show program's version number and exit\n");\r
2407 fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\\r
2408 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");\r
2409 fprintf (stdout, " -v, --verbose\n\\r
2410 Print informational statements\n");\r
2411 fprintf (stdout, " -q, --quiet\n\\r
2412 Returns the exit code, error messages will be displayed\n");\r
2413 fprintf (stdout, " -s, --silent\n\\r
2414 Returns only the exit code; informational and error\n\\r
2415 messages are not displayed\n");\r
2416 fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\\r
2417 Parse the basename to file-guid cross reference file(s)\n");\r
2418 fprintf (stdout, " -f OFFSET, --offset OFFSET\n\\r
2419 The offset from the start of the input file to start \n\\r
2420 processing an FV\n");\r
9947f576
YZ
2421 fprintf (stdout, " --hash\n\\r
2422 Generate HASH value of the entire PE image\n");\r
730ffca1
YZ
2423 fprintf (stdout, " --sfo\n\\r
2424 Reserved for future use\n");\r
f51461c8
LG
2425}\r
2426\r