]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VolInfo/VolInfo.c
BaseTools: Change source files to DOS format.
[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
45258285 4Copyright (c) 1999 - 2016, 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
22#endif\r
f51461c8
LG
23\r
24#include <FvLib.h>\r
25#include <Common/UefiBaseTypes.h>\r
26#include <Common/UefiCapsule.h>\r
27#include <Common/PiFirmwareFile.h>\r
28#include <Common/PiFirmwareVolume.h>\r
29#include <Guid/PiFirmwareFileSystem.h>\r
30#include <IndustryStandard/PeImage.h>\r
31#include <Protocol/GuidedSectionExtraction.h>\r
32\r
33#include "Compress.h"\r
34#include "Decompress.h"\r
35#include "VolInfo.h"\r
36#include "CommonLib.h"\r
37#include "EfiUtilityMsgs.h"\r
38#include "FirmwareVolumeBufferLib.h"\r
39#include "OsPath.h"\r
40#include "ParseGuidedSectionTools.h"\r
41#include "StringFuncs.h"\r
730ffca1 42#include "ParseInf.h"\r
f51461c8
LG
43\r
44//\r
45// Utility global variables\r
46//\r
47\r
48EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
49\r
45258285
LG
50#define UTILITY_MAJOR_VERSION 1\r
51#define UTILITY_MINOR_VERSION 0\r
f51461c8
LG
52\r
53#define UTILITY_NAME "VolInfo"\r
54\r
55#define EFI_SECTION_ERROR EFIERR (100)\r
56\r
57#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable\r
58\r
59//\r
60// Structure to keep a list of guid-to-basenames\r
61//\r
62typedef struct _GUID_TO_BASENAME {\r
63 struct _GUID_TO_BASENAME *Next;\r
64 INT8 Guid[PRINTED_GUID_BUFFER_SIZE];\r
65 INT8 BaseName[MAX_BASENAME_LEN];\r
66} GUID_TO_BASENAME;\r
67\r
68static GUID_TO_BASENAME *mGuidBaseNameList = NULL;\r
69\r
70//\r
71// Store GUIDed Section guid->tool mapping\r
72//\r
73EFI_HANDLE mParsedGuidedSectionTools = NULL;\r
74\r
75CHAR8* mUtilityFilename = NULL;\r
76\r
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
133void\r
134Usage (\r
135 VOID\r
136 );\r
137\r
138int\r
139main (\r
140 int argc,\r
141 char *argv[]\r
142 )\r
143/*++\r
144\r
145Routine Description:\r
146\r
147 GC_TODO: Add function description\r
148\r
149Arguments:\r
150\r
151 argc - GC_TODO: add argument description\r
152 ] - GC_TODO: add argument description\r
153\r
154Returns:\r
155\r
156 GC_TODO: add return values\r
157\r
158--*/\r
159{\r
160 FILE *InputFile;\r
161 int BytesRead;\r
162 EFI_FIRMWARE_VOLUME_HEADER *FvImage;\r
163 UINT32 FvSize;\r
164 EFI_STATUS Status;\r
165 int Offset;\r
166 BOOLEAN ErasePolarity;\r
730ffca1 167 UINT64 LogLevel;\r
f51461c8
LG
168\r
169 SetUtilityName (UTILITY_NAME);\r
170 //\r
171 // Print utility header\r
172 //\r
45258285 173 printf ("%s Version %d.%d Build %s\n",\r
f51461c8
LG
174 UTILITY_NAME,\r
175 UTILITY_MAJOR_VERSION,\r
176 UTILITY_MINOR_VERSION,\r
45258285 177 __BUILD_VERSION\r
f51461c8
LG
178 );\r
179\r
730ffca1
YZ
180 if (argc == 1) {\r
181 Usage ();\r
182 return -1;\r
183 }\r
184\r
f51461c8
LG
185 argc--;\r
186 argv++;\r
730ffca1 187 LogLevel = 0;\r
f51461c8
LG
188 Offset = 0;\r
189\r
730ffca1
YZ
190 //\r
191 // Look for help options\r
192 //\r
193 if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) ||\r
194 (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {\r
195 Usage();\r
196 return STATUS_SUCCESS;\r
197 }\r
198 //\r
199 // Version has already be printed, so just return success\r
200 //\r
201 if (strcmp(argv[0], "--version") == 0) {\r
202 return STATUS_SUCCESS;\r
203 }\r
204\r
f51461c8
LG
205 //\r
206 // If they specified -x xref guid/basename cross-reference files, process it.\r
207 // This will print the basename beside each file guid. To use it, specify\r
208 // -x xref_filename to processdsc, then use xref_filename as a parameter\r
209 // here.\r
210 //\r
730ffca1 211 while (argc > 0) {\r
f51461c8
LG
212 if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {\r
213 ParseGuidBaseNameFile (argv[1]);\r
214 printf("ParseGuidBaseNameFile: %s\n", argv[1]);\r
215 argc -= 2;\r
216 argv += 2;\r
730ffca1
YZ
217 continue;\r
218 }\r
219 if (strcmp(argv[0], "--offset") == 0) {\r
f51461c8
LG
220 //\r
221 // Hex or decimal?\r
222 //\r
223 if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {\r
224 if (sscanf (argv[1], "%x", &Offset) != 1) {\r
225 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
226 return GetUtilityStatus ();\r
227 }\r
228 } else {\r
229 if (sscanf (argv[1], "%d", &Offset) != 1) {\r
230 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
231 return GetUtilityStatus ();\r
232 }\r
233 //\r
234 // See if they said something like "64K"\r
235 //\r
236 if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {\r
237 Offset *= 1024;\r
238 }\r
239 }\r
240\r
241 argc -= 2;\r
242 argv += 2;\r
730ffca1 243 continue;\r
f51461c8 244 }\r
730ffca1
YZ
245\r
246 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
247 SetPrintLevel (VERBOSE_LOG_LEVEL);\r
248 argc --;\r
249 argv ++;\r
250 continue;\r
251 }\r
252\r
253 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
254 SetPrintLevel (KEY_LOG_LEVEL);\r
255 argc --;\r
256 argv ++;\r
257 continue;\r
258 }\r
259\r
260 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
261 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
262 if (EFI_ERROR (Status)) {\r
263 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
264 return -1;\r
265 }\r
266 if (LogLevel > 9) {\r
267 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
268 return -1;\r
269 }\r
270 SetPrintLevel (LogLevel);\r
271 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
272 argc -= 2;\r
273 argv += 2;\r
274 continue;\r
275 }\r
276\r
277 mUtilityFilename = argv[0];\r
278 argc --;\r
279 argv ++;\r
f51461c8 280 }\r
730ffca1 281\r
f51461c8
LG
282 //\r
283 // Open the file containing the FV\r
284 //\r
730ffca1
YZ
285 if (mUtilityFilename == NULL) {\r
286 Error (NULL, 0, 1001, "Missing option", "Input files are not specified");\r
287 return GetUtilityStatus ();\r
288 }\r
289 InputFile = fopen (LongFilePath (mUtilityFilename), "rb");\r
f51461c8 290 if (InputFile == NULL) {\r
730ffca1 291 Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename);\r
f51461c8
LG
292 return GetUtilityStatus ();\r
293 }\r
294 //\r
295 // Skip over pad bytes if specified. This is used if they prepend 0xff\r
296 // data to the FV image binary.\r
297 //\r
298 if (Offset != 0) {\r
299 fseek (InputFile, Offset, SEEK_SET);\r
300 }\r
301 //\r
302 // Determine size of FV\r
303 //\r
304 Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);\r
305 if (EFI_ERROR (Status)) {\r
730ffca1 306 Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename);\r
f51461c8
LG
307 fclose (InputFile);\r
308 return GetUtilityStatus ();\r
309 }\r
310 //\r
311 // Allocate a buffer for the FV image\r
312 //\r
313 FvImage = malloc (FvSize);\r
314 if (FvImage == NULL) {\r
315 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);\r
316 fclose (InputFile);\r
317 return GetUtilityStatus ();\r
318 }\r
319 //\r
320 // Seek to the start of the image, then read the entire FV to the buffer\r
321 //\r
322 fseek (InputFile, Offset, SEEK_SET);\r
323 BytesRead = fread (FvImage, 1, FvSize, InputFile);\r
324 fclose (InputFile);\r
325 if ((unsigned int) BytesRead != FvSize) {\r
730ffca1 326 Error (NULL, 0, 0004, "error reading FvImage from", mUtilityFilename);\r
f51461c8
LG
327 free (FvImage);\r
328 return GetUtilityStatus ();\r
329 }\r
330\r
730ffca1 331 LoadGuidedSectionToolsTxt (mUtilityFilename);\r
f51461c8
LG
332\r
333 PrintFvInfo (FvImage, FALSE);\r
334\r
335 //\r
336 // Clean up\r
337 //\r
338 free (FvImage);\r
339 FreeGuidBaseNameList ();\r
340 return GetUtilityStatus ();\r
341}\r
342\r
343\r
344static\r
345EFI_STATUS\r
346PrintFvInfo (\r
347 IN VOID *Fv,\r
348 IN BOOLEAN IsChildFv\r
349 )\r
350/*++\r
351\r
352Routine Description:\r
353\r
354 GC_TODO: Add function description\r
355\r
356Arguments:\r
357\r
358 Fv - Firmware Volume to print information about\r
359 IsChildFv - Flag specifies whether the input FV is a child FV.\r
360\r
361Returns:\r
362\r
363 EFI_STATUS\r
364\r
365--*/\r
366{\r
367 EFI_STATUS Status;\r
368 UINTN NumberOfFiles;\r
369 BOOLEAN ErasePolarity;\r
370 UINTN FvSize;\r
371 EFI_FFS_FILE_HEADER *CurrentFile;\r
372 UINTN Key;\r
373\r
374 Status = FvBufGetSize (Fv, &FvSize);\r
375\r
376 NumberOfFiles = 0;\r
377 ErasePolarity =\r
378 (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?\r
379 TRUE : FALSE;\r
380\r
381 //\r
382 // Get the first file\r
383 //\r
384 Key = 0;\r
385 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
386 if (EFI_ERROR (Status)) {\r
387 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");\r
388 return GetUtilityStatus ();\r
389 }\r
390 //\r
391 // Display information about files found\r
392 //\r
393 while (CurrentFile != NULL) {\r
394 //\r
395 // Increment the number of files counter\r
396 //\r
397 NumberOfFiles++;\r
398\r
399 //\r
400 // Display info about this file\r
401 //\r
402 Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);\r
403 if (EFI_ERROR (Status)) {\r
404 Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");\r
405 return GetUtilityStatus ();\r
406 }\r
407 //\r
408 // Get the next file\r
409 //\r
410 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
411 if (Status == EFI_NOT_FOUND) {\r
412 CurrentFile = NULL;\r
413 } else if (EFI_ERROR (Status)) {\r
414 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");\r
415 return GetUtilityStatus ();\r
416 }\r
417 }\r
418\r
419 if (IsChildFv) {\r
420 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles);\r
421 } else {\r
422 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles);\r
423 }\r
424\r
425 return EFI_SUCCESS;\r
426}\r
427\r
428UINT32\r
429GetOccupiedSize (\r
430 IN UINT32 ActualSize,\r
431 IN UINT32 Alignment\r
432 )\r
433/*++\r
434\r
435Routine Description:\r
436\r
437 This function returns the next larger size that meets the alignment \r
438 requirement specified.\r
439\r
440Arguments:\r
441\r
442 ActualSize The size.\r
443 Alignment The desired alignment.\r
444 \r
445Returns:\r
446 \r
447 EFI_SUCCESS Function completed successfully.\r
448 EFI_ABORTED The function encountered an error.\r
449\r
450--*/\r
451{\r
452 UINT32 OccupiedSize;\r
453\r
454 OccupiedSize = ActualSize;\r
455 while ((OccupiedSize & (Alignment - 1)) != 0) {\r
456 OccupiedSize++;\r
457 }\r
458\r
459 return OccupiedSize;\r
460}\r
461\r
462static\r
463CHAR8 *\r
464SectionNameToStr (\r
465 IN EFI_SECTION_TYPE Type\r
466 )\r
467/*++\r
468\r
469Routine Description:\r
470\r
471 Converts EFI Section names to Strings\r
472\r
473Arguments:\r
474\r
475 Type - The EFI Section type\r
476\r
477Returns:\r
478\r
479 CHAR8* - Pointer to the String containing the section name.\r
480\r
481--*/\r
482{\r
483 CHAR8 *SectionStr;\r
484 CHAR8 *SectionTypeStringTable[] = {\r
485 //\r
486 // 0X00\r
487 //\r
488 "EFI_SECTION_ALL",\r
489 //\r
490 // 0x01\r
491 //\r
492 "EFI_SECTION_COMPRESSION",\r
493 //\r
494 // 0x02\r
495 //\r
496 "EFI_SECTION_GUID_DEFINED", \r
497 //\r
498 // 0x03\r
499 //\r
500 "Unknown section type - Reserved 0x03",\r
501 //\r
502 // 0x04\r
503 //\r
504 "Unknown section type - Reserved 0x04",\r
505 //\r
506 // 0x05\r
507 //\r
508 "Unknown section type - Reserved 0x05",\r
509 //\r
510 // 0x06\r
511 //\r
512 "Unknown section type - Reserved 0x06",\r
513 //\r
514 // 0x07\r
515 //\r
516 "Unknown section type - Reserved 0x07",\r
517 //\r
518 // 0x08\r
519 //\r
520 "Unknown section type - Reserved 0x08",\r
521 //\r
522 // 0x09\r
523 //\r
524 "Unknown section type - Reserved 0x09",\r
525 //\r
526 // 0x0A\r
527 //\r
528 "Unknown section type - Reserved 0x0A",\r
529 //\r
530 // 0x0B\r
531 //\r
532 "Unknown section type - Reserved 0x0B",\r
533 //\r
534 // 0x0C\r
535 //\r
536 "Unknown section type - Reserved 0x0C",\r
537 //\r
538 // 0x0D\r
539 //\r
540 "Unknown section type - Reserved 0x0D",\r
541 //\r
542 // 0x0E\r
543 //\r
544 "Unknown section type - Reserved 0x0E",\r
545 //\r
546 // 0x0F\r
547 //\r
548 "Unknown section type - Reserved 0x0E",\r
549 //\r
550 // 0x10\r
551 //\r
552 "EFI_SECTION_PE32",\r
553 //\r
554 // 0x11\r
555 //\r
556 "EFI_SECTION_PIC",\r
557 //\r
558 // 0x12\r
559 //\r
560 "EFI_SECTION_TE", \r
561 //\r
562 // 0x13\r
563 //\r
564 "EFI_SECTION_DXE_DEPEX", \r
565 //\r
566 // 0x14\r
567 //\r
568 "EFI_SECTION_VERSION",\r
569 //\r
570 // 0x15\r
571 //\r
572 "EFI_SECTION_USER_INTERFACE",\r
573 //\r
574 // 0x16\r
575 //\r
576 "EFI_SECTION_COMPATIBILITY16",\r
577 //\r
578 // 0x17\r
579 //\r
580 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",\r
581 //\r
582 // 0x18\r
583 //\r
584 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",\r
585 //\r
586 // 0x19\r
587 //\r
588 "EFI_SECTION_RAW",\r
589 //\r
590 // 0x1A\r
591 //\r
592 "Unknown section type - 0x1A",\r
593 //\r
594 // 0x1B\r
595 //\r
596 "EFI_SECTION_PEI_DEPEX",\r
597 //\r
598 // 0x1C\r
599 //\r
600 "EFI_SECTION_SMM_DEPEX",\r
601 //\r
602 // 0x1C+\r
603 //\r
604 "Unknown section type - Reserved - beyond last defined section"\r
605 };\r
606\r
607 if (Type > EFI_SECTION_LAST_SECTION_TYPE) {\r
608 Type = EFI_SECTION_LAST_SECTION_TYPE + 1;\r
609 }\r
610\r
611 SectionStr = malloc (100);\r
612 if (SectionStr == NULL) {\r
613 printf ("Error: Out of memory resources.\n");\r
614 return SectionStr;\r
615 }\r
616 strcpy (SectionStr, SectionTypeStringTable[Type]);\r
617 return SectionStr;\r
618}\r
619\r
620STATIC\r
621EFI_STATUS\r
622ReadHeader (\r
623 IN FILE *InputFile,\r
624 OUT UINT32 *FvSize,\r
625 OUT BOOLEAN *ErasePolarity\r
626 )\r
627/*++\r
628\r
629Routine Description:\r
630\r
631 This function determines the size of the FV and the erase polarity. The \r
632 erase polarity is the FALSE value for file state.\r
633\r
634Arguments:\r
635\r
636 InputFile The file that contains the FV image.\r
637 FvSize The size of the FV.\r
638 ErasePolarity The FV erase polarity.\r
639 \r
640Returns:\r
641 \r
642 EFI_SUCCESS Function completed successfully.\r
643 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.\r
644 EFI_ABORTED The function encountered an error.\r
645\r
646--*/\r
647{\r
648 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
649 EFI_FV_BLOCK_MAP_ENTRY BlockMap;\r
650 UINTN Signature[2];\r
651 UINTN BytesRead;\r
652 UINT32 Size;\r
653\r
654 BytesRead = 0;\r
655 Size = 0;\r
656 //\r
657 // Check input parameters\r
658 //\r
659 if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {\r
660 Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");\r
661 return EFI_INVALID_PARAMETER;\r
662 }\r
663 //\r
664 // Read the header\r
665 //\r
666 fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
667 BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
668 Signature[0] = VolumeHeader.Signature;\r
669 Signature[1] = 0;\r
670\r
671 //\r
672 // Print FV header information\r
673 //\r
674 printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);\r
675 printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);\r
676\r
677 if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {\r
678 printf (" EFI_FVB2_READ_DISABLED_CAP\n");\r
679 }\r
680\r
681 if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {\r
682 printf (" EFI_FVB2_READ_ENABLED_CAP\n");\r
683 }\r
684\r
685 if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {\r
686 printf (" EFI_FVB2_READ_STATUS\n");\r
687 }\r
688\r
689 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {\r
690 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");\r
691 }\r
692\r
693 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {\r
694 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");\r
695 }\r
696\r
697 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {\r
698 printf (" EFI_FVB2_WRITE_STATUS\n");\r
699 }\r
700\r
701 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {\r
702 printf (" EFI_FVB2_LOCK_CAP\n");\r
703 }\r
704\r
705 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {\r
706 printf (" EFI_FVB2_LOCK_STATUS\n");\r
707 }\r
708\r
709 if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {\r
710 printf (" EFI_FVB2_STICKY_WRITE\n");\r
711 }\r
712\r
713 if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {\r
714 printf (" EFI_FVB2_MEMORY_MAPPED\n");\r
715 }\r
716\r
717 if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {\r
718 printf (" EFI_FVB2_ERASE_POLARITY\n");\r
719 *ErasePolarity = TRUE;\r
720 }\r
721\r
722#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
723 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {\r
724 printf (" EFI_FVB2_ALIGNMENT\n");\r
725 }\r
726\r
727 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
728 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
729 }\r
730\r
731 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
732 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
733 }\r
734\r
735 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
736 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
737 }\r
738\r
739 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
740 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
741 }\r
742\r
743 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
744 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
745 }\r
746\r
747 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
748 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
749 }\r
750\r
751 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
752 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
753 }\r
754\r
755 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
756 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
757 }\r
758\r
759 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
760 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
761 }\r
762\r
763 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
764 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
765 }\r
766\r
767 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
768 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
769 }\r
770\r
771 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
772 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
773 }\r
774\r
775 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
776 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
777 }\r
778\r
779 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
780 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
781 }\r
782\r
783 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
784 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
785 }\r
786\r
787 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
788 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
789 }\r
790 \r
791#else\r
792\r
793 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {\r
794 printf (" EFI_FVB2_READ_LOCK_CAP\n");\r
795 }\r
796\r
797 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {\r
798 printf (" EFI_FVB2_READ_LOCK_STATUS\n");\r
799 }\r
800\r
801 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {\r
802 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");\r
803 }\r
804\r
805 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {\r
806 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");\r
807 }\r
808\r
809 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {\r
810 printf (" EFI_FVB2_ALIGNMENT_1\n");\r
811 }\r
812\r
813 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
814 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
815 }\r
816\r
817 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
818 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
819 }\r
820\r
821 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
822 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
823 }\r
824\r
825 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
826 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
827 }\r
828\r
829 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
830 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
831 }\r
832\r
833 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
834 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
835 }\r
836\r
837 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
838 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
839 }\r
840\r
841 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
842 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
843 }\r
844\r
845 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
846 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
847 }\r
848\r
849 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
850 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
851 }\r
852\r
853 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
854 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
855 }\r
856\r
857 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
858 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
859 }\r
860\r
861 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
862 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
863 }\r
864\r
865 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
866 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
867 }\r
868\r
869 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
870 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
871 }\r
872\r
873 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
874 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
875 }\r
876\r
877 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {\r
878 printf (" EFI_FVB2_ALIGNMENT_128K\n");\r
879 }\r
880\r
881 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {\r
882 printf (" EFI_FVB2_ALIGNMENT_256K\n");\r
883 }\r
884\r
885 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) {\r
886 printf (" EFI_FVB2_ALIGNMENT_512K\n");\r
887 }\r
888\r
889 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {\r
890 printf (" EFI_FVB2_ALIGNMENT_1M\n");\r
891 }\r
892\r
893 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {\r
894 printf (" EFI_FVB2_ALIGNMENT_2M\n");\r
895 }\r
896\r
897 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {\r
898 printf (" EFI_FVB2_ALIGNMENT_4M\n");\r
899 }\r
900\r
901 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {\r
902 printf (" EFI_FVB2_ALIGNMENT_8M\n");\r
903 }\r
904\r
905 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {\r
906 printf (" EFI_FVB2_ALIGNMENT_16M\n");\r
907 }\r
908\r
909 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {\r
910 printf (" EFI_FVB2_ALIGNMENT_32M\n");\r
911 }\r
912\r
913 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
914 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
915 }\r
916\r
917 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
918 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
919 }\r
920\r
921 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
922 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
923 }\r
924\r
925 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
926 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
927 }\r
928\r
929 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {\r
930 printf (" EFI_FVB2_ALIGNMENT_256M\n");\r
931 }\r
932\r
933 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {\r
934 printf (" EFI_FVB2_ALIGNMENT_512M\n");\r
935 }\r
936\r
937 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {\r
938 printf (" EFI_FVB2_ALIGNMENT_1G\n");\r
939 }\r
940\r
941 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {\r
942 printf (" EFI_FVB2_ALIGNMENT_2G\n");\r
943 }\r
944\r
945#endif\r
946 printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);\r
947 printf ("File System ID: ");\r
948 PrintGuid (&VolumeHeader.FileSystemGuid);\r
949 //\r
950 // printf ("\n");\r
951 //\r
952 printf ("Revision: 0x%04X\n", VolumeHeader.Revision);\r
953\r
954 do {\r
955 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
956 BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
957\r
958 if (BlockMap.NumBlocks != 0) {\r
959 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);\r
960 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);\r
961 Size += BlockMap.NumBlocks * BlockMap.Length;\r
962 }\r
963\r
964 } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));\r
965\r
966 if (BytesRead != VolumeHeader.HeaderLength) {\r
967 printf ("ERROR: Header length not consistent with Block Maps!\n");\r
968 return EFI_ABORTED;\r
969 }\r
970\r
971 if (VolumeHeader.FvLength != Size) {\r
972 printf ("ERROR: Volume Size not consistant with Block Maps!\n");\r
973 return EFI_ABORTED;\r
974 }\r
975\r
976 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);\r
977\r
978 *FvSize = Size;\r
979\r
980 //\r
981 // rewind (InputFile);\r
982 //\r
983 return EFI_SUCCESS;\r
984}\r
985\r
986STATIC\r
987EFI_STATUS\r
988PrintFileInfo (\r
989 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
990 EFI_FFS_FILE_HEADER *FileHeader,\r
991 BOOLEAN ErasePolarity\r
992 )\r
993/*++\r
994\r
995Routine Description:\r
996\r
997 GC_TODO: Add function description\r
998\r
999Arguments:\r
1000\r
1001 FvImage - GC_TODO: add argument description\r
1002 FileHeader - GC_TODO: add argument description\r
1003 ErasePolarity - GC_TODO: add argument description\r
1004\r
1005Returns:\r
1006\r
1007 EFI_SUCCESS - GC_TODO: Add description for return value\r
1008 EFI_ABORTED - GC_TODO: Add description for return value\r
1009\r
1010--*/\r
1011{\r
1012 UINT32 FileLength;\r
1013 UINT8 FileState;\r
1014 UINT8 Checksum;\r
e4ac870f 1015 EFI_FFS_FILE_HEADER2 BlankHeader;\r
f51461c8
LG
1016 EFI_STATUS Status;\r
1017 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
e4ac870f 1018 UINT32 HeaderSize;\r
f51461c8
LG
1019#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
1020 UINT16 *Tail;\r
1021#endif\r
1022 //\r
1023 // Check if we have free space\r
1024 //\r
e4ac870f 1025 HeaderSize = FvBufGetFfsHeaderSize(FileHeader);\r
f51461c8 1026 if (ErasePolarity) {\r
e4ac870f 1027 memset (&BlankHeader, -1, HeaderSize);\r
f51461c8 1028 } else {\r
e4ac870f 1029 memset (&BlankHeader, 0, HeaderSize);\r
f51461c8
LG
1030 }\r
1031\r
e4ac870f 1032 if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {\r
f51461c8
LG
1033 return EFI_SUCCESS;\r
1034 }\r
1035 //\r
1036 // Print file information.\r
1037 //\r
1038 printf ("============================================================\n");\r
1039\r
1040 printf ("File Name: ");\r
1041 PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);\r
1042 printf ("%s ", GuidBuffer);\r
1043 PrintGuidName (GuidBuffer);\r
1044 printf ("\n");\r
1045\r
1046 //\r
1047 // PrintGuid (&FileHeader->Name);\r
1048 // printf ("\n");\r
1049 //\r
e4ac870f 1050 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1051 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));\r
1052 printf ("File Length: 0x%08X\n", (unsigned) FileLength);\r
1053 printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);\r
1054 printf ("File State: 0x%02X\n", FileHeader->State);\r
1055\r
1056 //\r
1057 // Print file state\r
1058 //\r
1059 FileState = GetFileState (ErasePolarity, FileHeader);\r
1060\r
1061 switch (FileState) {\r
1062\r
1063 case EFI_FILE_HEADER_CONSTRUCTION:\r
1064 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");\r
1065 return EFI_SUCCESS;\r
1066\r
1067 case EFI_FILE_HEADER_INVALID:\r
1068 printf (" EFI_FILE_HEADER_INVALID\n");\r
1069 return EFI_SUCCESS;\r
1070\r
1071 case EFI_FILE_HEADER_VALID:\r
1072 printf (" EFI_FILE_HEADER_VALID\n");\r
e4ac870f 1073 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1074 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1075 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1076 if (Checksum != 0) {\r
1077 printf ("ERROR: Header checksum invalid.\n");\r
1078 return EFI_ABORTED;\r
1079 }\r
1080\r
1081 return EFI_SUCCESS;\r
1082\r
1083 case EFI_FILE_DELETED:\r
1084 printf (" EFI_FILE_DELETED\n");\r
1085\r
1086 case EFI_FILE_MARKED_FOR_UPDATE:\r
1087 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");\r
1088\r
1089 case EFI_FILE_DATA_VALID:\r
1090 printf (" EFI_FILE_DATA_VALID\n");\r
1091\r
1092 //\r
1093 // Calculate header checksum\r
1094 //\r
e4ac870f 1095 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1096 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1097 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1098 if (Checksum != 0) {\r
1099 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);\r
1100 return EFI_ABORTED;\r
1101 }\r
1102\r
e4ac870f 1103 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1104\r
1105 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
1106 //\r
1107 // Calculate file checksum\r
1108 //\r
e4ac870f 1109 Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);\r
f51461c8
LG
1110 Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;\r
1111 if (Checksum != 0) {\r
1112 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);\r
1113 return EFI_ABORTED;\r
1114 }\r
1115 } else {\r
1116 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
1117 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
1118 return EFI_ABORTED;\r
1119 }\r
1120 }\r
1121#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
1122 //\r
1123 // Verify tail if present\r
1124 //\r
1125 if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
1126 //\r
1127 // Verify tail is complement of integrity check field in the header.\r
1128 //\r
1129 Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));\r
1130 if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {\r
1131 Error (NULL, 0, 0003, "error parsing FFS file", \\r
1132 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);\r
1133 return EFI_ABORTED;\r
1134 }\r
1135 }\r
1136 #endif \r
1137 break;\r
1138\r
1139 default:\r
1140 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);\r
1141 return EFI_ABORTED;\r
1142 }\r
1143\r
1144 printf ("File Type: 0x%02X ", FileHeader->Type);\r
1145\r
1146 switch (FileHeader->Type) {\r
1147\r
1148 case EFI_FV_FILETYPE_RAW:\r
1149 printf ("EFI_FV_FILETYPE_RAW\n");\r
1150 break;\r
1151\r
1152 case EFI_FV_FILETYPE_FREEFORM:\r
1153 printf ("EFI_FV_FILETYPE_FREEFORM\n");\r
1154 break;\r
1155\r
1156 case EFI_FV_FILETYPE_SECURITY_CORE:\r
1157 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");\r
1158 break;\r
1159\r
1160 case EFI_FV_FILETYPE_PEI_CORE:\r
1161 printf ("EFI_FV_FILETYPE_PEI_CORE\n");\r
1162 break;\r
1163\r
1164 case EFI_FV_FILETYPE_DXE_CORE:\r
1165 printf ("EFI_FV_FILETYPE_DXE_CORE\n");\r
1166 break;\r
1167\r
1168 case EFI_FV_FILETYPE_PEIM:\r
1169 printf ("EFI_FV_FILETYPE_PEIM\n");\r
1170 break;\r
1171\r
1172 case EFI_FV_FILETYPE_DRIVER:\r
1173 printf ("EFI_FV_FILETYPE_DRIVER\n");\r
1174 break;\r
1175\r
1176 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
1177 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");\r
1178 break;\r
1179\r
1180 case EFI_FV_FILETYPE_APPLICATION:\r
1181 printf ("EFI_FV_FILETYPE_APPLICATION\n");\r
1182 break;\r
1183\r
1184 case EFI_FV_FILETYPE_SMM:\r
1185 printf ("EFI_FV_FILETYPE_SMM\n");\r
1186 break;\r
1187\r
1188 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
1189 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");\r
1190 break;\r
1191\r
1192 case EFI_FV_FILETYPE_COMBINED_SMM_DXE:\r
1193 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");\r
1194 break;\r
1195\r
1196 case EFI_FV_FILETYPE_SMM_CORE:\r
1197 printf ("EFI_FV_FILETYPE_SMM_CORE\n");\r
1198 break;\r
1199\r
1200 case EFI_FV_FILETYPE_FFS_PAD:\r
1201 printf ("EFI_FV_FILETYPE_FFS_PAD\n");\r
1202 break;\r
1203\r
1204 default:\r
1205 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);\r
1206 return EFI_ABORTED;\r
1207 break;\r
1208 }\r
1209\r
1210 switch (FileHeader->Type) {\r
1211\r
1212 case EFI_FV_FILETYPE_ALL:\r
1213 case EFI_FV_FILETYPE_RAW:\r
1214 case EFI_FV_FILETYPE_FFS_PAD:\r
1215 break;\r
1216\r
1217 default:\r
1218 //\r
1219 // All other files have sections\r
1220 //\r
1221 Status = ParseSection (\r
e4ac870f
LG
1222 (UINT8 *) ((UINTN) FileHeader + HeaderSize),\r
1223 FvBufGetFfsFileSize (FileHeader) - HeaderSize\r
f51461c8
LG
1224 );\r
1225 if (EFI_ERROR (Status)) {\r
1226 //\r
1227 // printf ("ERROR: Parsing the FFS file.\n");\r
1228 //\r
1229 return EFI_ABORTED;\r
1230 }\r
1231 break;\r
1232 }\r
1233\r
1234 return EFI_SUCCESS;\r
1235}\r
1236\r
1237EFI_STATUS\r
1238ParseSection (\r
1239 IN UINT8 *SectionBuffer,\r
1240 IN UINT32 BufferLength\r
1241 )\r
1242/*++\r
1243\r
1244Routine Description:\r
1245\r
1246 Parses EFI Sections\r
1247\r
1248Arguments:\r
1249\r
1250 SectionBuffer - Buffer containing the section to parse.\r
1251 BufferLength - Length of SectionBuffer\r
1252\r
1253Returns:\r
1254\r
1255 EFI_SECTION_ERROR - Problem with section parsing.\r
1256 (a) compression errors\r
1257 (b) unrecognized section \r
1258 EFI_UNSUPPORTED - Do not know how to parse the section.\r
1259 EFI_SUCCESS - Section successfully parsed.\r
1260 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1261\r
1262--*/\r
1263{\r
1264 EFI_SECTION_TYPE Type;\r
1265 UINT8 *Ptr;\r
1266 UINT32 SectionLength;\r
e4ac870f 1267 UINT32 SectionHeaderLen;\r
f51461c8
LG
1268 CHAR8 *SectionName;\r
1269 EFI_STATUS Status;\r
1270 UINT32 ParsedLength;\r
1271 UINT8 *CompressedBuffer;\r
1272 UINT32 CompressedLength;\r
1273 UINT8 *UncompressedBuffer;\r
1274 UINT32 UncompressedLength;\r
1275 UINT8 *ToolOutputBuffer;\r
1276 UINT32 ToolOutputLength;\r
1277 UINT8 CompressionType;\r
1278 UINT32 DstSize;\r
1279 UINT32 ScratchSize;\r
1280 UINT8 *ScratchBuffer;\r
1281 DECOMPRESS_FUNCTION DecompressFunction;\r
1282 GETINFO_FUNCTION GetInfoFunction;\r
1283 // CHAR16 *name;\r
1284 CHAR8 *ExtractionTool;\r
1285 CHAR8 *ToolInputFile;\r
1286 CHAR8 *ToolOutputFile;\r
1287 CHAR8 *SystemCommandFormatString;\r
1288 CHAR8 *SystemCommand;\r
e4ac870f
LG
1289 EFI_GUID *EfiGuid;\r
1290 UINT16 DataOffset;\r
1291 UINT16 Attributes;\r
1292 UINT32 RealHdrLen;\r
f51461c8
LG
1293\r
1294 ParsedLength = 0;\r
1295 while (ParsedLength < BufferLength) {\r
1296 Ptr = SectionBuffer + ParsedLength;\r
1297\r
1298 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
1299 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
1300\r
1301 //\r
1302 // This is sort of an odd check, but is necessary because FFS files are\r
1303 // padded to a QWORD boundary, meaning there is potentially a whole section\r
1304 // header worth of 0xFF bytes.\r
1305 //\r
1306 if (SectionLength == 0xffffff && Type == 0xff) {\r
1307 ParsedLength += 4;\r
1308 continue;\r
1309 }\r
1310\r
e4ac870f
LG
1311 //\r
1312 // Get real section file size\r
1313 //\r
1314 SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);\r
1315 SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1316\r
f51461c8
LG
1317 SectionName = SectionNameToStr (Type);\r
1318 printf ("------------------------------------------------------------\n");\r
1319 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);\r
1320 free (SectionName);\r
1321\r
1322 switch (Type) {\r
1323 case EFI_SECTION_RAW:\r
1324 case EFI_SECTION_PE32:\r
1325 case EFI_SECTION_PIC:\r
1326 case EFI_SECTION_TE:\r
1327 // default is no more information\r
1328 break;\r
1329\r
1330 case EFI_SECTION_USER_INTERFACE:\r
730ffca1 1331 printf (" String: %ls\n", (CHAR16 *) &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString);\r
f51461c8
LG
1332 break;\r
1333\r
1334 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
e4ac870f 1335 Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);\r
f51461c8
LG
1336 if (EFI_ERROR (Status)) {\r
1337 Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);\r
1338 return EFI_SECTION_ERROR;\r
1339 }\r
1340 break;\r
1341\r
1342 case EFI_SECTION_COMPATIBILITY16:\r
1343 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
1344 //\r
1345 // Section does not contain any further header information.\r
1346 //\r
1347 break;\r
1348\r
1349 case EFI_SECTION_PEI_DEPEX:\r
1350 case EFI_SECTION_DXE_DEPEX:\r
1351 case EFI_SECTION_SMM_DEPEX:\r
1352 DumpDepexSection (Ptr, SectionLength);\r
1353 break;\r
1354\r
1355 case EFI_SECTION_VERSION:\r
e4ac870f
LG
1356 printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));\r
1357 printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));\r
f51461c8
LG
1358 break;\r
1359\r
1360 case EFI_SECTION_COMPRESSION:\r
1361 UncompressedBuffer = NULL;\r
e4ac870f
LG
1362 if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1363 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);\r
1364 UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;\r
1365 CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;\r
1366 } else {\r
1367 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);\r
1368 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;\r
1369 CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;\r
1370 }\r
1371 CompressedLength = SectionLength - RealHdrLen;\r
f51461c8
LG
1372 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);\r
1373\r
1374 if (CompressionType == EFI_NOT_COMPRESSED) {\r
1375 printf (" Compression Type: EFI_NOT_COMPRESSED\n");\r
1376 if (CompressedLength != UncompressedLength) {\r
1377 Error (\r
1378 NULL,\r
1379 0,\r
1380 0,\r
1381 "file is not compressed, but the compressed length does not match the uncompressed length",\r
1382 NULL\r
1383 );\r
1384 return EFI_SECTION_ERROR;\r
1385 }\r
1386\r
e4ac870f 1387 UncompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1388 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1389 GetInfoFunction = EfiGetInfo;\r
1390 DecompressFunction = EfiDecompress;\r
1391 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");\r
1392\r
e4ac870f 1393 CompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1394\r
1395 Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);\r
1396 if (EFI_ERROR (Status)) {\r
1397 Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);\r
1398 return EFI_SECTION_ERROR;\r
1399 }\r
1400\r
1401 if (DstSize != UncompressedLength) {\r
1402 Error (NULL, 0, 0003, "compression error in the compression section", NULL);\r
1403 return EFI_SECTION_ERROR;\r
1404 }\r
1405\r
1406 ScratchBuffer = malloc (ScratchSize);\r
1407 UncompressedBuffer = malloc (UncompressedLength);\r
1408 if ((ScratchBuffer == NULL) || (UncompressedBuffer == NULL)) {\r
1409 return EFI_OUT_OF_RESOURCES;\r
1410 }\r
1411 Status = DecompressFunction (\r
1412 CompressedBuffer,\r
1413 CompressedLength,\r
1414 UncompressedBuffer,\r
1415 UncompressedLength,\r
1416 ScratchBuffer,\r
1417 ScratchSize\r
1418 );\r
1419 free (ScratchBuffer);\r
1420 if (EFI_ERROR (Status)) {\r
1421 Error (NULL, 0, 0003, "decompress failed", NULL);\r
1422 free (UncompressedBuffer);\r
1423 return EFI_SECTION_ERROR;\r
1424 }\r
1425 } else {\r
1426 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);\r
1427 return EFI_SECTION_ERROR;\r
1428 }\r
1429\r
1430 Status = ParseSection (UncompressedBuffer, UncompressedLength);\r
1431\r
1432 if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1433 //\r
1434 // We need to deallocate Buffer\r
1435 //\r
1436 free (UncompressedBuffer);\r
1437 }\r
1438\r
1439 if (EFI_ERROR (Status)) {\r
1440 Error (NULL, 0, 0003, "failed to parse section", NULL);\r
1441 return EFI_SECTION_ERROR;\r
1442 }\r
1443 break;\r
1444\r
1445 case EFI_SECTION_GUID_DEFINED:\r
e4ac870f
LG
1446 if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {\r
1447 EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;\r
1448 DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;\r
1449 Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;\r
1450 } else {\r
1451 EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;\r
1452 DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;\r
1453 Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;\r
1454 }\r
f51461c8 1455 printf (" SectionDefinitionGuid: ");\r
e4ac870f 1456 PrintGuid (EfiGuid);\r
f51461c8 1457 printf ("\n");\r
e4ac870f
LG
1458 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);\r
1459 printf (" Attributes: 0x%04X\n", (unsigned) Attributes);\r
f51461c8
LG
1460\r
1461 ExtractionTool =\r
1462 LookupGuidedSectionToolPath (\r
1463 mParsedGuidedSectionTools,\r
e4ac870f 1464 EfiGuid\r
f51461c8
LG
1465 );\r
1466\r
1467 if (ExtractionTool != NULL) {\r
868c9c35 1468 #ifndef __GNUC__\r
f51461c8
LG
1469 ToolInputFile = CloneString (tmpnam (NULL));\r
1470 ToolOutputFile = CloneString (tmpnam (NULL));\r
868c9c35
YZ
1471 #else\r
1472 char tmp1[] = "/tmp/fileXXXXXX";\r
1473 char tmp2[] = "/tmp/fileXXXXXX";\r
1474 int fd1;\r
1475 int fd2;\r
1476 fd1 = mkstemp(tmp1);\r
1477 fd2 = mkstemp(tmp2);\r
1478 ToolInputFile = CloneString(tmp1);\r
1479 ToolOutputFile = CloneString(tmp2);\r
1480 close(fd1);\r
1481 close(fd2);\r
1482 #endif\r
f51461c8
LG
1483\r
1484 //\r
1485 // Construction 'system' command string\r
1486 //\r
1487 SystemCommandFormatString = "%s -d -o %s %s";\r
1488 SystemCommand = malloc (\r
1489 strlen (SystemCommandFormatString) +\r
1490 strlen (ExtractionTool) +\r
1491 strlen (ToolInputFile) +\r
1492 strlen (ToolOutputFile) +\r
1493 1\r
1494 );\r
1495 sprintf (\r
1496 SystemCommand,\r
1497 SystemCommandFormatString,\r
1498 ExtractionTool,\r
1499 ToolOutputFile,\r
1500 ToolInputFile\r
1501 );\r
1502 free (ExtractionTool);\r
1503\r
1504 Status =\r
1505 PutFileImage (\r
1506 ToolInputFile,\r
e4ac870f
LG
1507 (CHAR8*) SectionBuffer + DataOffset,\r
1508 BufferLength - DataOffset\r
f51461c8
LG
1509 );\r
1510\r
1511 system (SystemCommand);\r
1512 remove (ToolInputFile);\r
1513 free (ToolInputFile);\r
1514\r
1515 Status =\r
1516 GetFileImage (\r
1517 ToolOutputFile,\r
1518 (CHAR8 **)&ToolOutputBuffer,\r
1519 &ToolOutputLength\r
1520 );\r
1521 remove (ToolOutputFile);\r
1522 free (ToolOutputFile);\r
1523 if (EFI_ERROR (Status)) {\r
1524 Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);\r
1525 return EFI_SECTION_ERROR;\r
1526 }\r
1527\r
1528 Status = ParseSection (\r
1529 ToolOutputBuffer,\r
1530 ToolOutputLength\r
1531 );\r
1532 if (EFI_ERROR (Status)) {\r
1533 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);\r
1534 return EFI_SECTION_ERROR;\r
1535 }\r
1536\r
1537 //\r
1538 // Check for CRC32 sections which we can handle internally if needed.\r
1539 //\r
1540 } else if (!CompareGuid (\r
e4ac870f 1541 EfiGuid,\r
f51461c8
LG
1542 &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
1543 )\r
1544 ) {\r
1545 //\r
1546 // CRC32 guided section\r
1547 //\r
1548 Status = ParseSection (\r
e4ac870f
LG
1549 SectionBuffer + DataOffset,\r
1550 BufferLength - DataOffset\r
f51461c8
LG
1551 );\r
1552 if (EFI_ERROR (Status)) {\r
1553 Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);\r
1554 return EFI_SECTION_ERROR;\r
1555 }\r
1556 } else {\r
1557 //\r
1558 // We don't know how to parse it now.\r
1559 //\r
1560 Error (NULL, 0, 0003, "Error parsing section", \\r
1561 "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
1562 return EFI_UNSUPPORTED;\r
1563 }\r
1564 break;\r
1565\r
1566 default:\r
1567 //\r
1568 // Unknown section, return error\r
1569 //\r
1570 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);\r
1571 return EFI_SECTION_ERROR;\r
1572 }\r
1573\r
1574 ParsedLength += SectionLength;\r
1575 //\r
1576 // We make then next section begin on a 4-byte boundary\r
1577 //\r
1578 ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
1579 }\r
1580\r
1581 if (ParsedLength < BufferLength) {\r
1582 Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);\r
1583 return EFI_SECTION_ERROR;\r
1584 }\r
1585\r
1586 return EFI_SUCCESS;\r
1587}\r
1588\r
1589EFI_STATUS\r
1590DumpDepexSection (\r
1591 IN UINT8 *Ptr,\r
1592 IN UINT32 SectionLength\r
1593 )\r
1594/*++\r
1595\r
1596Routine Description:\r
1597\r
1598 GC_TODO: Add function description\r
1599\r
1600Arguments:\r
1601\r
1602 Ptr - GC_TODO: add argument description\r
1603 SectionLength - GC_TODO: add argument description\r
1604\r
1605Returns:\r
1606\r
1607 EFI_SUCCESS - GC_TODO: Add description for return value\r
1608\r
1609--*/\r
1610{\r
1611 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
1612\r
1613 //\r
1614 // Need at least a section header + data\r
1615 //\r
1616 if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1617 return EFI_SUCCESS;\r
1618 }\r
1619\r
e4ac870f
LG
1620 Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1621 SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
f51461c8
LG
1622 while (SectionLength > 0) {\r
1623 printf (" ");\r
1624 switch (*Ptr) {\r
1625 case EFI_DEP_BEFORE:\r
1626 printf ("BEFORE\n");\r
1627 Ptr++;\r
1628 SectionLength--;\r
1629 break;\r
1630\r
1631 case EFI_DEP_AFTER:\r
1632 printf ("AFTER\n");\r
1633 Ptr++;\r
1634 SectionLength--;\r
1635 break;\r
1636\r
1637 case EFI_DEP_PUSH:\r
1638 printf ("PUSH\n ");\r
1639 PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);\r
1640 printf ("%s ", GuidBuffer);\r
1641 PrintGuidName (GuidBuffer);\r
1642 printf ("\n");\r
1643 //\r
1644 // PrintGuid ((EFI_GUID *)(Ptr + 1));\r
1645 //\r
1646 Ptr += 17;\r
1647 SectionLength -= 17;\r
1648 break;\r
1649\r
1650 case EFI_DEP_AND:\r
1651 printf ("AND\n");\r
1652 Ptr++;\r
1653 SectionLength--;\r
1654 break;\r
1655\r
1656 case EFI_DEP_OR:\r
1657 printf ("OR\n");\r
1658 Ptr++;\r
1659 SectionLength--;\r
1660 break;\r
1661\r
1662 case EFI_DEP_NOT:\r
1663 printf ("NOT\n");\r
1664 Ptr++;\r
1665 SectionLength--;\r
1666 break;\r
1667\r
1668 case EFI_DEP_TRUE:\r
1669 printf ("TRUE\n");\r
1670 Ptr++;\r
1671 SectionLength--;\r
1672 break;\r
1673\r
1674 case EFI_DEP_FALSE:\r
1675 printf ("FALSE\n");\r
1676 Ptr++;\r
1677 SectionLength--;\r
1678 break;\r
1679\r
1680 case EFI_DEP_END:\r
1681 printf ("END DEPEX\n");\r
1682 Ptr++;\r
1683 SectionLength--;\r
1684 break;\r
1685\r
1686 case EFI_DEP_SOR:\r
1687 printf ("SOR\n");\r
1688 Ptr++;\r
1689 SectionLength--;\r
1690 break;\r
1691\r
1692 default:\r
1693 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);\r
1694 return EFI_SUCCESS;\r
1695 }\r
1696 }\r
1697\r
1698 return EFI_SUCCESS;\r
1699}\r
1700\r
1701EFI_STATUS\r
1702PrintGuidName (\r
1703 IN UINT8 *GuidStr\r
1704 )\r
1705/*++\r
1706\r
1707Routine Description:\r
1708\r
1709 GC_TODO: Add function description\r
1710\r
1711Arguments:\r
1712\r
1713 GuidStr - GC_TODO: add argument description\r
1714\r
1715Returns:\r
1716\r
1717 EFI_SUCCESS - GC_TODO: Add description for return value\r
1718 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
1719\r
1720--*/\r
1721{\r
1722 GUID_TO_BASENAME *GPtr;\r
1723 //\r
1724 // If we have a list of guid-to-basenames, then go through the list to\r
1725 // look for a guid string match. If found, print the basename to stdout,\r
1726 // otherwise return a failure.\r
1727 //\r
1728 GPtr = mGuidBaseNameList;\r
1729 while (GPtr != NULL) {\r
1730 if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {\r
1731 printf ("%s", GPtr->BaseName);\r
1732 return EFI_SUCCESS;\r
1733 }\r
1734\r
1735 GPtr = GPtr->Next;\r
1736 }\r
1737\r
1738 return EFI_INVALID_PARAMETER;\r
1739}\r
1740\r
1741EFI_STATUS\r
1742ParseGuidBaseNameFile (\r
1743 CHAR8 *FileName\r
1744 )\r
1745/*++\r
1746\r
1747Routine Description:\r
1748\r
1749 GC_TODO: Add function description\r
1750\r
1751Arguments:\r
1752\r
1753 FileName - GC_TODO: add argument description\r
1754\r
1755Returns:\r
1756\r
1757 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
1758 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value\r
1759 EFI_SUCCESS - GC_TODO: Add description for return value\r
1760\r
1761--*/\r
1762{\r
1763 FILE *Fptr;\r
1764 CHAR8 Line[MAX_LINE_LEN];\r
1765 GUID_TO_BASENAME *GPtr;\r
1766\r
97fa0ee9 1767 if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {\r
f51461c8
LG
1768 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);\r
1769 return EFI_DEVICE_ERROR;\r
1770 }\r
1771\r
1772 while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
1773 //\r
1774 // Allocate space for another guid/basename element\r
1775 //\r
1776 GPtr = malloc (sizeof (GUID_TO_BASENAME));\r
1777 if (GPtr == NULL) {\r
1778 return EFI_OUT_OF_RESOURCES;\r
1779 }\r
1780\r
1781 memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));\r
1782 if (sscanf (Line, "%s %s", GPtr->Guid, GPtr->BaseName) == 2) {\r
1783 GPtr->Next = mGuidBaseNameList;\r
1784 mGuidBaseNameList = GPtr;\r
1785 } else {\r
1786 //\r
1787 // Some sort of error. Just continue.\r
1788 //\r
1789 free (GPtr);\r
1790 }\r
1791 }\r
1792\r
1793 fclose (Fptr);\r
1794 return EFI_SUCCESS;\r
1795}\r
1796\r
1797EFI_STATUS\r
1798FreeGuidBaseNameList (\r
1799 VOID\r
1800 )\r
1801/*++\r
1802\r
1803Routine Description:\r
1804\r
1805 GC_TODO: Add function description\r
1806\r
1807Arguments:\r
1808\r
1809 None\r
1810\r
1811Returns:\r
1812\r
1813 EFI_SUCCESS - GC_TODO: Add description for return value\r
1814\r
1815--*/\r
1816{\r
1817 GUID_TO_BASENAME *Next;\r
1818\r
1819 while (mGuidBaseNameList != NULL) {\r
1820 Next = mGuidBaseNameList->Next;\r
1821 free (mGuidBaseNameList);\r
1822 mGuidBaseNameList = Next;\r
1823 }\r
1824\r
1825 return EFI_SUCCESS;\r
1826}\r
1827\r
1828\r
1829static\r
1830VOID\r
1831LoadGuidedSectionToolsTxt (\r
1832 IN CHAR8* FirmwareVolumeFilename\r
1833 )\r
1834{\r
1835 CHAR8* PeerFilename;\r
1836 CHAR8* Places[] = {\r
1837 NULL,\r
1838 //NULL,\r
1839 };\r
1840 UINTN Index;\r
1841\r
1842 Places[0] = FirmwareVolumeFilename;\r
1843 //Places[1] = mUtilityFilename;\r
1844\r
1845 mParsedGuidedSectionTools = NULL;\r
1846\r
1847 for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {\r
1848 PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");\r
1849 //printf("Loading %s...\n", PeerFilename);\r
1850 if (OsPathExists (PeerFilename)) {\r
1851 mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);\r
1852 }\r
1853 free (PeerFilename);\r
1854 if (mParsedGuidedSectionTools != NULL) {\r
1855 return;\r
1856 }\r
1857 }\r
1858}\r
1859\r
1860\r
1861void\r
1862Usage (\r
1863 VOID\r
1864 )\r
1865/*++\r
1866\r
1867Routine Description:\r
1868\r
1869 GC_TODO: Add function description\r
1870\r
1871Arguments:\r
1872\r
1873 None\r
1874\r
1875Returns:\r
1876\r
1877 GC_TODO: add return values\r
1878\r
1879--*/\r
1880{\r
1881 //\r
1882 // Summary usage\r
1883 //\r
1884 fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);\r
1885\r
1886 //\r
1887 // Copyright declaration\r
1888 // \r
45258285 1889 fprintf (stdout, "Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.\n\n");\r
f4260465 1890 fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");\r
f51461c8
LG
1891\r
1892 //\r
1893 // Details Option\r
1894 //\r
730ffca1 1895 fprintf (stdout, "optional arguments:\n");\r
f51461c8 1896 fprintf (stdout, " -h, --help\n\\r
730ffca1
YZ
1897 Show this help message and exit\n");\r
1898 fprintf (stdout, " --version\n\\r
1899 Show program's version number and exit\n");\r
1900 fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\\r
1901 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");\r
1902 fprintf (stdout, " -v, --verbose\n\\r
1903 Print informational statements\n");\r
1904 fprintf (stdout, " -q, --quiet\n\\r
1905 Returns the exit code, error messages will be displayed\n");\r
1906 fprintf (stdout, " -s, --silent\n\\r
1907 Returns only the exit code; informational and error\n\\r
1908 messages are not displayed\n");\r
1909 fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\\r
1910 Parse the basename to file-guid cross reference file(s)\n");\r
1911 fprintf (stdout, " -f OFFSET, --offset OFFSET\n\\r
1912 The offset from the start of the input file to start \n\\r
1913 processing an FV\n");\r
1914 fprintf (stdout, " --sfo\n\\r
1915 Reserved for future use\n");\r
f51461c8
LG
1916}\r
1917\r