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