]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VolInfo/VolInfo.c
BaseTools: Check the fread function and avoid dead loop
[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
914 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {\r
915 printf (" EFI_FVB2_ALIGNMENT_1\n");\r
916 }\r
917\r
918 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
919 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
920 }\r
921\r
922 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
923 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
924 }\r
925\r
926 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
927 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
928 }\r
929\r
930 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
931 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
932 }\r
933\r
934 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
935 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
936 }\r
937\r
938 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
939 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
940 }\r
941\r
942 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
943 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
944 }\r
945\r
946 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
947 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
948 }\r
949\r
950 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
951 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
952 }\r
953\r
954 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
955 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
956 }\r
957\r
958 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
959 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
960 }\r
961\r
962 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
963 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
964 }\r
965\r
966 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
967 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
968 }\r
969\r
970 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
971 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
972 }\r
973\r
974 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
975 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
976 }\r
977\r
978 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
979 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
980 }\r
981\r
982 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {\r
983 printf (" EFI_FVB2_ALIGNMENT_128K\n");\r
984 }\r
985\r
986 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {\r
987 printf (" EFI_FVB2_ALIGNMENT_256K\n");\r
988 }\r
989\r
990 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) {\r
991 printf (" EFI_FVB2_ALIGNMENT_512K\n");\r
992 }\r
993\r
994 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {\r
995 printf (" EFI_FVB2_ALIGNMENT_1M\n");\r
996 }\r
997\r
998 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {\r
999 printf (" EFI_FVB2_ALIGNMENT_2M\n");\r
1000 }\r
1001\r
1002 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {\r
1003 printf (" EFI_FVB2_ALIGNMENT_4M\n");\r
1004 }\r
1005\r
1006 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {\r
1007 printf (" EFI_FVB2_ALIGNMENT_8M\n");\r
1008 }\r
1009\r
1010 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {\r
1011 printf (" EFI_FVB2_ALIGNMENT_16M\n");\r
1012 }\r
1013\r
1014 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {\r
1015 printf (" EFI_FVB2_ALIGNMENT_32M\n");\r
1016 }\r
1017\r
1018 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
1019 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
1020 }\r
1021\r
1022 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
1023 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
1024 }\r
1025\r
1026 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
1027 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
1028 }\r
1029\r
1030 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
1031 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
1032 }\r
1033\r
1034 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {\r
1035 printf (" EFI_FVB2_ALIGNMENT_256M\n");\r
1036 }\r
1037\r
1038 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {\r
1039 printf (" EFI_FVB2_ALIGNMENT_512M\n");\r
1040 }\r
1041\r
1042 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {\r
1043 printf (" EFI_FVB2_ALIGNMENT_1G\n");\r
1044 }\r
1045\r
1046 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {\r
1047 printf (" EFI_FVB2_ALIGNMENT_2G\n");\r
1048 }\r
1049\r
1050#endif\r
1051 printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);\r
1052 printf ("File System ID: ");\r
1053 PrintGuid (&VolumeHeader.FileSystemGuid);\r
1054 //\r
1055 // printf ("\n");\r
1056 //\r
1057 printf ("Revision: 0x%04X\n", VolumeHeader.Revision);\r
1058\r
1059 do {\r
ae3c247d
ZL
1060 ReadSize = fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
1061 if (ReadSize != 1) {\r
1062 return EFI_ABORTED;\r
1063 }\r
f51461c8
LG
1064 BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
1065\r
1066 if (BlockMap.NumBlocks != 0) {\r
1067 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);\r
1068 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);\r
1069 Size += BlockMap.NumBlocks * BlockMap.Length;\r
1070 }\r
1071\r
1072 } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));\r
1073\r
1074 if (BytesRead != VolumeHeader.HeaderLength) {\r
1075 printf ("ERROR: Header length not consistent with Block Maps!\n");\r
1076 return EFI_ABORTED;\r
1077 }\r
1078\r
1079 if (VolumeHeader.FvLength != Size) {\r
1080 printf ("ERROR: Volume Size not consistant with Block Maps!\n");\r
1081 return EFI_ABORTED;\r
1082 }\r
1083\r
1084 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);\r
1085\r
1086 *FvSize = Size;\r
1087\r
1088 //\r
1089 // rewind (InputFile);\r
1090 //\r
1091 return EFI_SUCCESS;\r
1092}\r
1093\r
1094STATIC\r
1095EFI_STATUS\r
1096PrintFileInfo (\r
1097 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
1098 EFI_FFS_FILE_HEADER *FileHeader,\r
1099 BOOLEAN ErasePolarity\r
1100 )\r
1101/*++\r
1102\r
1103Routine Description:\r
1104\r
1105 GC_TODO: Add function description\r
1106\r
1107Arguments:\r
1108\r
1109 FvImage - GC_TODO: add argument description\r
1110 FileHeader - GC_TODO: add argument description\r
1111 ErasePolarity - GC_TODO: add argument description\r
1112\r
1113Returns:\r
1114\r
1115 EFI_SUCCESS - GC_TODO: Add description for return value\r
1116 EFI_ABORTED - GC_TODO: Add description for return value\r
1117\r
1118--*/\r
1119{\r
1120 UINT32 FileLength;\r
1121 UINT8 FileState;\r
1122 UINT8 Checksum;\r
e4ac870f 1123 EFI_FFS_FILE_HEADER2 BlankHeader;\r
f51461c8
LG
1124 EFI_STATUS Status;\r
1125 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
e4ac870f 1126 UINT32 HeaderSize;\r
f7496d71 1127#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
f51461c8
LG
1128 UINT16 *Tail;\r
1129#endif\r
1130 //\r
1131 // Check if we have free space\r
1132 //\r
e4ac870f 1133 HeaderSize = FvBufGetFfsHeaderSize(FileHeader);\r
f51461c8 1134 if (ErasePolarity) {\r
e4ac870f 1135 memset (&BlankHeader, -1, HeaderSize);\r
f51461c8 1136 } else {\r
e4ac870f 1137 memset (&BlankHeader, 0, HeaderSize);\r
f51461c8
LG
1138 }\r
1139\r
e4ac870f 1140 if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {\r
f51461c8
LG
1141 return EFI_SUCCESS;\r
1142 }\r
1143 //\r
1144 // Print file information.\r
1145 //\r
1146 printf ("============================================================\n");\r
1147\r
1148 printf ("File Name: ");\r
1149 PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);\r
1150 printf ("%s ", GuidBuffer);\r
1151 PrintGuidName (GuidBuffer);\r
1152 printf ("\n");\r
1153\r
1154 //\r
1155 // PrintGuid (&FileHeader->Name);\r
1156 // printf ("\n");\r
1157 //\r
e4ac870f 1158 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1159 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));\r
1160 printf ("File Length: 0x%08X\n", (unsigned) FileLength);\r
1161 printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);\r
1162 printf ("File State: 0x%02X\n", FileHeader->State);\r
1163\r
1164 //\r
1165 // Print file state\r
1166 //\r
1167 FileState = GetFileState (ErasePolarity, FileHeader);\r
1168\r
1169 switch (FileState) {\r
1170\r
1171 case EFI_FILE_HEADER_CONSTRUCTION:\r
1172 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");\r
1173 return EFI_SUCCESS;\r
1174\r
1175 case EFI_FILE_HEADER_INVALID:\r
1176 printf (" EFI_FILE_HEADER_INVALID\n");\r
1177 return EFI_SUCCESS;\r
1178\r
1179 case EFI_FILE_HEADER_VALID:\r
1180 printf (" EFI_FILE_HEADER_VALID\n");\r
e4ac870f 1181 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1182 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1183 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1184 if (Checksum != 0) {\r
1185 printf ("ERROR: Header checksum invalid.\n");\r
1186 return EFI_ABORTED;\r
1187 }\r
1188\r
1189 return EFI_SUCCESS;\r
1190\r
1191 case EFI_FILE_DELETED:\r
1192 printf (" EFI_FILE_DELETED\n");\r
1193\r
1194 case EFI_FILE_MARKED_FOR_UPDATE:\r
1195 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");\r
1196\r
1197 case EFI_FILE_DATA_VALID:\r
1198 printf (" EFI_FILE_DATA_VALID\n");\r
1199\r
1200 //\r
1201 // Calculate header checksum\r
1202 //\r
e4ac870f 1203 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1204 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1205 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1206 if (Checksum != 0) {\r
1207 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);\r
1208 return EFI_ABORTED;\r
1209 }\r
1210\r
e4ac870f 1211 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1212\r
1213 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
1214 //\r
1215 // Calculate file checksum\r
1216 //\r
e4ac870f 1217 Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);\r
f51461c8
LG
1218 Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;\r
1219 if (Checksum != 0) {\r
1220 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);\r
1221 return EFI_ABORTED;\r
1222 }\r
1223 } else {\r
1224 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
1225 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
1226 return EFI_ABORTED;\r
1227 }\r
1228 }\r
f7496d71 1229#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
f51461c8
LG
1230 //\r
1231 // Verify tail if present\r
1232 //\r
1233 if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
1234 //\r
1235 // Verify tail is complement of integrity check field in the header.\r
1236 //\r
1237 Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));\r
1238 if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {\r
1239 Error (NULL, 0, 0003, "error parsing FFS file", \\r
1240 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);\r
1241 return EFI_ABORTED;\r
1242 }\r
1243 }\r
f7496d71 1244 #endif\r
f51461c8
LG
1245 break;\r
1246\r
1247 default:\r
1248 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);\r
1249 return EFI_ABORTED;\r
1250 }\r
1251\r
1252 printf ("File Type: 0x%02X ", FileHeader->Type);\r
1253\r
1254 switch (FileHeader->Type) {\r
1255\r
1256 case EFI_FV_FILETYPE_RAW:\r
1257 printf ("EFI_FV_FILETYPE_RAW\n");\r
1258 break;\r
1259\r
1260 case EFI_FV_FILETYPE_FREEFORM:\r
1261 printf ("EFI_FV_FILETYPE_FREEFORM\n");\r
1262 break;\r
1263\r
1264 case EFI_FV_FILETYPE_SECURITY_CORE:\r
1265 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");\r
1266 break;\r
1267\r
1268 case EFI_FV_FILETYPE_PEI_CORE:\r
1269 printf ("EFI_FV_FILETYPE_PEI_CORE\n");\r
1270 break;\r
1271\r
1272 case EFI_FV_FILETYPE_DXE_CORE:\r
1273 printf ("EFI_FV_FILETYPE_DXE_CORE\n");\r
1274 break;\r
1275\r
1276 case EFI_FV_FILETYPE_PEIM:\r
1277 printf ("EFI_FV_FILETYPE_PEIM\n");\r
1278 break;\r
1279\r
1280 case EFI_FV_FILETYPE_DRIVER:\r
1281 printf ("EFI_FV_FILETYPE_DRIVER\n");\r
1282 break;\r
1283\r
1284 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
1285 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");\r
1286 break;\r
1287\r
1288 case EFI_FV_FILETYPE_APPLICATION:\r
1289 printf ("EFI_FV_FILETYPE_APPLICATION\n");\r
1290 break;\r
1291\r
1292 case EFI_FV_FILETYPE_SMM:\r
1293 printf ("EFI_FV_FILETYPE_SMM\n");\r
1294 break;\r
1295\r
1296 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
1297 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");\r
1298 break;\r
1299\r
1300 case EFI_FV_FILETYPE_COMBINED_SMM_DXE:\r
1301 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");\r
1302 break;\r
1303\r
1304 case EFI_FV_FILETYPE_SMM_CORE:\r
1305 printf ("EFI_FV_FILETYPE_SMM_CORE\n");\r
1306 break;\r
1307\r
cb004eb0
EG
1308 case EFI_FV_FILETYPE_MM_STANDALONE:\r
1309 printf ("EFI_FV_FILETYPE_MM_STANDALONE\n");\r
1310 break;\r
1311\r
1312 case EFI_FV_FILETYPE_MM_CORE_STANDALONE:\r
1313 printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n");\r
1314 break;\r
1315\r
f51461c8
LG
1316 case EFI_FV_FILETYPE_FFS_PAD:\r
1317 printf ("EFI_FV_FILETYPE_FFS_PAD\n");\r
1318 break;\r
1319\r
1320 default:\r
1321 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);\r
1322 return EFI_ABORTED;\r
1323 break;\r
1324 }\r
1325\r
1326 switch (FileHeader->Type) {\r
1327\r
1328 case EFI_FV_FILETYPE_ALL:\r
1329 case EFI_FV_FILETYPE_RAW:\r
1330 case EFI_FV_FILETYPE_FFS_PAD:\r
1331 break;\r
1332\r
1333 default:\r
1334 //\r
1335 // All other files have sections\r
1336 //\r
1337 Status = ParseSection (\r
e4ac870f
LG
1338 (UINT8 *) ((UINTN) FileHeader + HeaderSize),\r
1339 FvBufGetFfsFileSize (FileHeader) - HeaderSize\r
f51461c8
LG
1340 );\r
1341 if (EFI_ERROR (Status)) {\r
1342 //\r
1343 // printf ("ERROR: Parsing the FFS file.\n");\r
1344 //\r
1345 return EFI_ABORTED;\r
1346 }\r
1347 break;\r
1348 }\r
1349\r
1350 return EFI_SUCCESS;\r
1351}\r
1352\r
9947f576
YZ
1353EFI_STATUS\r
1354RebaseImageRead (\r
1355 IN VOID *FileHandle,\r
1356 IN UINTN FileOffset,\r
1357 IN OUT UINT32 *ReadSize,\r
1358 OUT VOID *Buffer\r
1359 )\r
1360/*++\r
1361\r
1362Routine Description:\r
1363\r
1364 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
1365\r
1366Arguments:\r
1367\r
1368 FileHandle - The handle to the PE/COFF file\r
1369\r
1370 FileOffset - The offset, in bytes, into the file to read\r
1371\r
1372 ReadSize - The number of bytes to read from the file starting at FileOffset\r
1373\r
1374 Buffer - A pointer to the buffer to read the data into.\r
1375\r
1376Returns:\r
1377\r
1378 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
1379\r
1380--*/\r
1381{\r
1382 CHAR8 *Destination8;\r
1383 CHAR8 *Source8;\r
1384 UINT32 Length;\r
1385\r
1386 Destination8 = Buffer;\r
1387 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
1388 Length = *ReadSize;\r
1389 while (Length--) {\r
1390 *(Destination8++) = *(Source8++);\r
1391 }\r
1392\r
1393 return EFI_SUCCESS;\r
1394}\r
1395\r
1396EFI_STATUS\r
1397SetAddressToSectionHeader (\r
1398 IN CHAR8 *FileName,\r
1399 IN OUT UINT8 *FileBuffer,\r
1400 IN UINT64 NewPe32BaseAddress\r
1401 )\r
1402/*++\r
1403\r
1404Routine Description:\r
1405\r
1406 Set new base address into the section header of PeImage\r
1407\r
1408Arguments:\r
1409\r
1410 FileName - Name of file\r
1411 FileBuffer - Pointer to PeImage.\r
1412 NewPe32BaseAddress - New Base Address for PE image.\r
1413\r
1414Returns:\r
1415\r
1416 EFI_SUCCESS Set new base address into this image successfully.\r
1417\r
1418--*/\r
1419{\r
1420 EFI_STATUS Status;\r
1421 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1422 UINTN Index;\r
1423 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1424 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1425\r
1426 //\r
1427 // Initialize context\r
1428 //\r
1429 memset (&ImageContext, 0, sizeof (ImageContext));\r
1430 ImageContext.Handle = (VOID *) FileBuffer;\r
1431 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1432 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1433 if (EFI_ERROR (Status)) {\r
1434 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1435 return Status;\r
1436 }\r
1437\r
1438 if (ImageContext.RelocationsStripped) {\r
1439 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1440 return Status;\r
1441 }\r
1442\r
1443 //\r
1444 // Get PeHeader pointer\r
1445 //\r
1446 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1447\r
1448 //\r
1449 // Get section header list\r
1450 //\r
1451 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1452 (UINTN) ImgHdr +\r
1453 sizeof (UINT32) +\r
1454 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1455 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1456 );\r
1457\r
1458 //\r
1459 // Set base address into the first section header that doesn't point to code section.\r
1460 //\r
1461 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1462 if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
1463 *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;\r
1464 break;\r
1465 }\r
1466 }\r
1467\r
9947f576
YZ
1468 //\r
1469 // BaseAddress is set to section header.\r
1470 //\r
1471 return EFI_SUCCESS;\r
1472}\r
1473\r
1474EFI_STATUS\r
1475RebaseImage (\r
1476 IN CHAR8 *FileName,\r
1477 IN OUT UINT8 *FileBuffer,\r
1478 IN UINT64 NewPe32BaseAddress\r
1479 )\r
1480/*++\r
1481\r
1482Routine Description:\r
1483\r
1484 Set new base address into PeImage, and fix up PeImage based on new address.\r
1485\r
1486Arguments:\r
1487\r
1488 FileName - Name of file\r
1489 FileBuffer - Pointer to PeImage.\r
1490 NewPe32BaseAddress - New Base Address for PE image.\r
1491\r
1492Returns:\r
1493\r
1494 EFI_INVALID_PARAMETER - BaseAddress is not valid.\r
1495 EFI_SUCCESS - Update PeImage is correctly.\r
1496\r
1497--*/\r
1498{\r
1499 EFI_STATUS Status;\r
1500 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1501 UINTN Index;\r
1502 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1503 UINT8 *MemoryImagePointer;\r
1504 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1505\r
1506 //\r
1507 // Initialize context\r
1508 //\r
1509 memset (&ImageContext, 0, sizeof (ImageContext));\r
1510 ImageContext.Handle = (VOID *) FileBuffer;\r
1511 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1512 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1513 if (EFI_ERROR (Status)) {\r
1514 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1515 return Status;\r
1516 }\r
1517\r
1518 if (ImageContext.RelocationsStripped) {\r
1519 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1520 return Status;\r
1521 }\r
1522\r
1523 //\r
1524 // Get PeHeader pointer\r
1525 //\r
1526 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1527\r
1528 //\r
1529 // Load and Relocate Image Data\r
1530 //\r
1531 MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1532 if (MemoryImagePointer == NULL) {\r
1533 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
1534 return EFI_OUT_OF_RESOURCES;\r
1535 }\r
1536 memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1537 ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
1538\r
1539 Status = PeCoffLoaderLoadImage (&ImageContext);\r
1540 if (EFI_ERROR (Status)) {\r
1541 Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
1542 free ((VOID *) MemoryImagePointer);\r
1543 return Status;\r
1544 }\r
1545\r
1546 ImageContext.DestinationAddress = NewPe32BaseAddress;\r
1547 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
1548 if (EFI_ERROR (Status)) {\r
1549 Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
1550 free ((VOID *) MemoryImagePointer);\r
1551 return Status;\r
1552 }\r
1553\r
1554 //\r
1555 // Copy Relocated data to raw image file.\r
1556 //\r
1557 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1558 (UINTN) ImgHdr +\r
1559 sizeof (UINT32) +\r
1560 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1561 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1562 );\r
1563\r
1564 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1565 CopyMem (\r
1566 FileBuffer + SectionHeader->PointerToRawData,\r
1567 (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),\r
1568 SectionHeader->SizeOfRawData\r
1569 );\r
1570 }\r
1571\r
1572 free ((VOID *) MemoryImagePointer);\r
1573\r
1574 //\r
1575 // Update Image Base Address\r
1576 //\r
9e90fb09 1577 if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
9947f576
YZ
1578 ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
1579 } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
1580 ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
1581 } else {\r
1582 Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
1583 ImgHdr->Pe32.OptionalHeader.Magic,\r
1584 FileName\r
1585 );\r
1586 return EFI_ABORTED;\r
1587 }\r
1588\r
1589 //\r
1590 // Set new base address into section header\r
1591 //\r
1592 Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);\r
1593\r
1594 return Status;\r
1595}\r
1596\r
1597EFI_STATUS\r
1598CombinePath (\r
1599 IN CHAR8* DefaultPath,\r
1600 IN CHAR8* AppendPath,\r
1601 OUT CHAR8* NewPath\r
1602)\r
1603{\r
1604 UINT32 DefaultPathLen;\r
8994d2f9 1605 UINT64 Index;\r
3337eefb
YZ
1606 CHAR8 QuotesStr[] = "\"";\r
1607 strcpy(NewPath, QuotesStr);\r
9947f576 1608 DefaultPathLen = strlen(DefaultPath);\r
3337eefb 1609 strcat(NewPath, DefaultPath);\r
8994d2f9 1610 Index = 0;\r
3337eefb 1611 for (; Index < DefaultPathLen + 1; Index ++) {\r
9947f576
YZ
1612 if (NewPath[Index] == '\\' || NewPath[Index] == '/') {\r
1613 if (NewPath[Index + 1] != '\0') {\r
1614 NewPath[Index] = '/';\r
1615 }\r
1616 }\r
1617 }\r
1618 if (NewPath[Index -1] != '/') {\r
1619 NewPath[Index] = '/';\r
1620 NewPath[Index + 1] = '\0';\r
1621 }\r
1622 strcat(NewPath, AppendPath);\r
3337eefb 1623 strcat(NewPath, QuotesStr);\r
9947f576
YZ
1624 return EFI_SUCCESS;\r
1625}\r
1626\r
f51461c8
LG
1627EFI_STATUS\r
1628ParseSection (\r
1629 IN UINT8 *SectionBuffer,\r
1630 IN UINT32 BufferLength\r
1631 )\r
1632/*++\r
1633\r
1634Routine Description:\r
1635\r
1636 Parses EFI Sections\r
1637\r
1638Arguments:\r
1639\r
1640 SectionBuffer - Buffer containing the section to parse.\r
1641 BufferLength - Length of SectionBuffer\r
1642\r
1643Returns:\r
1644\r
1645 EFI_SECTION_ERROR - Problem with section parsing.\r
1646 (a) compression errors\r
f7496d71 1647 (b) unrecognized section\r
f51461c8
LG
1648 EFI_UNSUPPORTED - Do not know how to parse the section.\r
1649 EFI_SUCCESS - Section successfully parsed.\r
1650 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1651\r
1652--*/\r
1653{\r
1654 EFI_SECTION_TYPE Type;\r
1655 UINT8 *Ptr;\r
1656 UINT32 SectionLength;\r
e4ac870f 1657 UINT32 SectionHeaderLen;\r
f51461c8
LG
1658 CHAR8 *SectionName;\r
1659 EFI_STATUS Status;\r
1660 UINT32 ParsedLength;\r
1661 UINT8 *CompressedBuffer;\r
1662 UINT32 CompressedLength;\r
1663 UINT8 *UncompressedBuffer;\r
1664 UINT32 UncompressedLength;\r
1665 UINT8 *ToolOutputBuffer;\r
1666 UINT32 ToolOutputLength;\r
1667 UINT8 CompressionType;\r
1668 UINT32 DstSize;\r
1669 UINT32 ScratchSize;\r
1670 UINT8 *ScratchBuffer;\r
1671 DECOMPRESS_FUNCTION DecompressFunction;\r
1672 GETINFO_FUNCTION GetInfoFunction;\r
1673 // CHAR16 *name;\r
1674 CHAR8 *ExtractionTool;\r
1675 CHAR8 *ToolInputFile;\r
1676 CHAR8 *ToolOutputFile;\r
f51461c8 1677 CHAR8 *SystemCommand;\r
e4ac870f
LG
1678 EFI_GUID *EfiGuid;\r
1679 UINT16 DataOffset;\r
1680 UINT16 Attributes;\r
1681 UINT32 RealHdrLen;\r
9947f576
YZ
1682 CHAR8 *ToolInputFileName;\r
1683 CHAR8 *ToolOutputFileName;\r
3883e2cb 1684 CHAR8 *UIFileName;\r
f51461c8
LG
1685\r
1686 ParsedLength = 0;\r
9947f576
YZ
1687 ToolInputFileName = NULL;\r
1688 ToolOutputFileName = NULL;\r
1689\r
f51461c8
LG
1690 while (ParsedLength < BufferLength) {\r
1691 Ptr = SectionBuffer + ParsedLength;\r
1692\r
1693 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
1694 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
1695\r
1696 //\r
1697 // This is sort of an odd check, but is necessary because FFS files are\r
1698 // padded to a QWORD boundary, meaning there is potentially a whole section\r
1699 // header worth of 0xFF bytes.\r
1700 //\r
1701 if (SectionLength == 0xffffff && Type == 0xff) {\r
1702 ParsedLength += 4;\r
1703 continue;\r
1704 }\r
1705\r
e4ac870f
LG
1706 //\r
1707 // Get real section file size\r
1708 //\r
1709 SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);\r
1710 SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1711\r
f51461c8 1712 SectionName = SectionNameToStr (Type);\r
9dd00cb6
HW
1713 if (SectionName != NULL) {\r
1714 printf ("------------------------------------------------------------\n");\r
1715 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);\r
1716 free (SectionName);\r
1717 }\r
f51461c8
LG
1718\r
1719 switch (Type) {\r
1720 case EFI_SECTION_RAW:\r
f51461c8
LG
1721 case EFI_SECTION_PIC:\r
1722 case EFI_SECTION_TE:\r
1723 // default is no more information\r
1724 break;\r
1725\r
9947f576
YZ
1726 case EFI_SECTION_PE32:\r
1727 if (EnableHash) {\r
1728 ToolInputFileName = "edk2Temp_InputEfi.tmp";\r
1729 ToolOutputFileName = "edk2Temp_OutputHash.tmp";\r
1730 RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);\r
1731 PutFileImage (\r
1732 ToolInputFileName,\r
1733 (CHAR8*)Ptr + SectionHeaderLen,\r
1734 SectionLength - SectionHeaderLen\r
1735 );\r
1736\r
9947f576 1737 SystemCommand = malloc (\r
aeadb1c4 1738 strlen (OPENSSL_COMMAND_FORMAT_STRING) +\r
9947f576
YZ
1739 strlen (OpenSslPath) +\r
1740 strlen (ToolInputFileName) +\r
1741 strlen (ToolOutputFileName) +\r
1742 1\r
1743 );\r
9dd00cb6
HW
1744 if (SystemCommand == NULL) {\r
1745 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1746 return EFI_OUT_OF_RESOURCES;\r
1747 }\r
9947f576
YZ
1748 sprintf (\r
1749 SystemCommand,\r
aeadb1c4 1750 OPENSSL_COMMAND_FORMAT_STRING,\r
9947f576
YZ
1751 OpenSslPath,\r
1752 ToolOutputFileName,\r
1753 ToolInputFileName\r
1754 );\r
1755\r
1756 if (system (SystemCommand) != EFI_SUCCESS) {\r
1757 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
1758 }\r
1759 else {\r
1760 FILE *fp;\r
1761 CHAR8 *StrLine;\r
1762 CHAR8 *NewStr;\r
1763 UINT32 nFileLen;\r
1764 if((fp = fopen(ToolOutputFileName,"r")) == NULL) {\r
1765 Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);\r
1766 }\r
1767 else {\r
1768 fseek(fp,0,SEEK_SET);\r
1769 fseek(fp,0,SEEK_END);\r
1770 nFileLen = ftell(fp);\r
1771 fseek(fp,0,SEEK_SET);\r
1772 StrLine = malloc(nFileLen);\r
9dd00cb6
HW
1773 if (StrLine == NULL) {\r
1774 fclose(fp);\r
1775 free (SystemCommand);\r
1776 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1777 return EFI_OUT_OF_RESOURCES;\r
1778 }\r
9947f576
YZ
1779 fgets(StrLine, nFileLen, fp);\r
1780 NewStr = strrchr (StrLine, '=');\r
1781 printf (" SHA1: %s\n", NewStr + 1);\r
1782 free (StrLine);\r
9dd00cb6 1783 fclose(fp);\r
9947f576 1784 }\r
9947f576
YZ
1785 }\r
1786 remove(ToolInputFileName);\r
1787 remove(ToolOutputFileName);\r
1788 free (SystemCommand);\r
1789 }\r
1790 break;\r
1791\r
f51461c8 1792 case EFI_SECTION_USER_INTERFACE:\r
3883e2cb
HW
1793 UIFileName = (CHAR8 *) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString) + 1);\r
1794 if (UIFileName == NULL) {\r
1795 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1796 return EFI_OUT_OF_RESOURCES;\r
1797 }\r
1798 Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UIFileName);\r
1799 printf (" String: %s\n", UIFileName);\r
1800 free (UIFileName);\r
f51461c8
LG
1801 break;\r
1802\r
1803 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
e4ac870f 1804 Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);\r
f51461c8
LG
1805 if (EFI_ERROR (Status)) {\r
1806 Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);\r
1807 return EFI_SECTION_ERROR;\r
1808 }\r
1809 break;\r
1810\r
1811 case EFI_SECTION_COMPATIBILITY16:\r
1812 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
1813 //\r
1814 // Section does not contain any further header information.\r
1815 //\r
1816 break;\r
1817\r
1818 case EFI_SECTION_PEI_DEPEX:\r
1819 case EFI_SECTION_DXE_DEPEX:\r
1820 case EFI_SECTION_SMM_DEPEX:\r
1821 DumpDepexSection (Ptr, SectionLength);\r
1822 break;\r
1823\r
1824 case EFI_SECTION_VERSION:\r
e4ac870f
LG
1825 printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));\r
1826 printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));\r
f51461c8
LG
1827 break;\r
1828\r
1829 case EFI_SECTION_COMPRESSION:\r
1830 UncompressedBuffer = NULL;\r
e4ac870f
LG
1831 if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1832 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);\r
1833 UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;\r
1834 CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;\r
1835 } else {\r
1836 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);\r
1837 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;\r
1838 CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;\r
1839 }\r
1840 CompressedLength = SectionLength - RealHdrLen;\r
f51461c8
LG
1841 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);\r
1842\r
1843 if (CompressionType == EFI_NOT_COMPRESSED) {\r
1844 printf (" Compression Type: EFI_NOT_COMPRESSED\n");\r
1845 if (CompressedLength != UncompressedLength) {\r
1846 Error (\r
1847 NULL,\r
1848 0,\r
1849 0,\r
1850 "file is not compressed, but the compressed length does not match the uncompressed length",\r
1851 NULL\r
1852 );\r
1853 return EFI_SECTION_ERROR;\r
1854 }\r
1855\r
e4ac870f 1856 UncompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1857 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1858 GetInfoFunction = EfiGetInfo;\r
1859 DecompressFunction = EfiDecompress;\r
1860 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");\r
1861\r
e4ac870f 1862 CompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1863\r
1864 Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);\r
1865 if (EFI_ERROR (Status)) {\r
1866 Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);\r
1867 return EFI_SECTION_ERROR;\r
1868 }\r
1869\r
1870 if (DstSize != UncompressedLength) {\r
1871 Error (NULL, 0, 0003, "compression error in the compression section", NULL);\r
1872 return EFI_SECTION_ERROR;\r
1873 }\r
1874\r
1875 ScratchBuffer = malloc (ScratchSize);\r
85006654
HW
1876 if (ScratchBuffer == NULL) {\r
1877 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1878 return EFI_OUT_OF_RESOURCES;\r
1879 }\r
f51461c8 1880 UncompressedBuffer = malloc (UncompressedLength);\r
85006654
HW
1881 if (UncompressedBuffer == NULL) {\r
1882 free (ScratchBuffer);\r
1883 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
f51461c8
LG
1884 return EFI_OUT_OF_RESOURCES;\r
1885 }\r
1886 Status = DecompressFunction (\r
1887 CompressedBuffer,\r
1888 CompressedLength,\r
1889 UncompressedBuffer,\r
1890 UncompressedLength,\r
1891 ScratchBuffer,\r
1892 ScratchSize\r
1893 );\r
1894 free (ScratchBuffer);\r
1895 if (EFI_ERROR (Status)) {\r
1896 Error (NULL, 0, 0003, "decompress failed", NULL);\r
1897 free (UncompressedBuffer);\r
1898 return EFI_SECTION_ERROR;\r
1899 }\r
1900 } else {\r
1901 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);\r
1902 return EFI_SECTION_ERROR;\r
1903 }\r
1904\r
1905 Status = ParseSection (UncompressedBuffer, UncompressedLength);\r
1906\r
1907 if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1908 //\r
1909 // We need to deallocate Buffer\r
1910 //\r
1911 free (UncompressedBuffer);\r
1912 }\r
1913\r
1914 if (EFI_ERROR (Status)) {\r
1915 Error (NULL, 0, 0003, "failed to parse section", NULL);\r
1916 return EFI_SECTION_ERROR;\r
1917 }\r
1918 break;\r
1919\r
1920 case EFI_SECTION_GUID_DEFINED:\r
e4ac870f
LG
1921 if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {\r
1922 EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;\r
1923 DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;\r
1924 Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;\r
1925 } else {\r
1926 EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;\r
1927 DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;\r
1928 Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;\r
1929 }\r
f51461c8 1930 printf (" SectionDefinitionGuid: ");\r
e4ac870f 1931 PrintGuid (EfiGuid);\r
f51461c8 1932 printf ("\n");\r
e4ac870f
LG
1933 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);\r
1934 printf (" Attributes: 0x%04X\n", (unsigned) Attributes);\r
f51461c8
LG
1935\r
1936 ExtractionTool =\r
1937 LookupGuidedSectionToolPath (\r
1938 mParsedGuidedSectionTools,\r
e4ac870f 1939 EfiGuid\r
f51461c8
LG
1940 );\r
1941\r
1942 if (ExtractionTool != NULL) {\r
868c9c35 1943 #ifndef __GNUC__\r
f51461c8
LG
1944 ToolInputFile = CloneString (tmpnam (NULL));\r
1945 ToolOutputFile = CloneString (tmpnam (NULL));\r
868c9c35
YZ
1946 #else\r
1947 char tmp1[] = "/tmp/fileXXXXXX";\r
1948 char tmp2[] = "/tmp/fileXXXXXX";\r
1949 int fd1;\r
1950 int fd2;\r
1951 fd1 = mkstemp(tmp1);\r
1952 fd2 = mkstemp(tmp2);\r
1953 ToolInputFile = CloneString(tmp1);\r
1954 ToolOutputFile = CloneString(tmp2);\r
1955 close(fd1);\r
1956 close(fd2);\r
1957 #endif\r
f51461c8 1958\r
9dd00cb6
HW
1959 if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) {\r
1960 if (ToolInputFile != NULL) {\r
1961 free (ToolInputFile);\r
1962 }\r
1963 if (ToolOutputFile != NULL) {\r
1964 free (ToolOutputFile);\r
1965 }\r
1966 free (ExtractionTool);\r
1967\r
1968 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1969 return EFI_OUT_OF_RESOURCES;\r
1970 }\r
1971\r
f51461c8
LG
1972 //\r
1973 // Construction 'system' command string\r
1974 //\r
f51461c8 1975 SystemCommand = malloc (\r
aeadb1c4 1976 strlen (EXTRACT_COMMAND_FORMAT_STRING) +\r
f51461c8
LG
1977 strlen (ExtractionTool) +\r
1978 strlen (ToolInputFile) +\r
1979 strlen (ToolOutputFile) +\r
1980 1\r
1981 );\r
9dd00cb6
HW
1982 if (SystemCommand == NULL) {\r
1983 free (ToolInputFile);\r
1984 free (ToolOutputFile);\r
1985 free (ExtractionTool);\r
1986\r
1987 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1988 return EFI_OUT_OF_RESOURCES;\r
1989 }\r
f51461c8
LG
1990 sprintf (\r
1991 SystemCommand,\r
aeadb1c4 1992 EXTRACT_COMMAND_FORMAT_STRING,\r
f51461c8
LG
1993 ExtractionTool,\r
1994 ToolOutputFile,\r
1995 ToolInputFile\r
1996 );\r
1997 free (ExtractionTool);\r
1998\r
1999 Status =\r
2000 PutFileImage (\r
2001 ToolInputFile,\r
e4ac870f
LG
2002 (CHAR8*) SectionBuffer + DataOffset,\r
2003 BufferLength - DataOffset\r
f51461c8
LG
2004 );\r
2005\r
2006 system (SystemCommand);\r
2007 remove (ToolInputFile);\r
2008 free (ToolInputFile);\r
2009\r
2010 Status =\r
2011 GetFileImage (\r
2012 ToolOutputFile,\r
2013 (CHAR8 **)&ToolOutputBuffer,\r
2014 &ToolOutputLength\r
2015 );\r
2016 remove (ToolOutputFile);\r
2017 free (ToolOutputFile);\r
9dd00cb6 2018 free (SystemCommand);\r
f51461c8
LG
2019 if (EFI_ERROR (Status)) {\r
2020 Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);\r
2021 return EFI_SECTION_ERROR;\r
2022 }\r
2023\r
2024 Status = ParseSection (\r
2025 ToolOutputBuffer,\r
2026 ToolOutputLength\r
2027 );\r
2028 if (EFI_ERROR (Status)) {\r
2029 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);\r
2030 return EFI_SECTION_ERROR;\r
2031 }\r
2032\r
2033 //\r
2034 // Check for CRC32 sections which we can handle internally if needed.\r
2035 //\r
2036 } else if (!CompareGuid (\r
e4ac870f 2037 EfiGuid,\r
f51461c8
LG
2038 &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
2039 )\r
2040 ) {\r
2041 //\r
2042 // CRC32 guided section\r
2043 //\r
2044 Status = ParseSection (\r
e4ac870f
LG
2045 SectionBuffer + DataOffset,\r
2046 BufferLength - DataOffset\r
f51461c8
LG
2047 );\r
2048 if (EFI_ERROR (Status)) {\r
2049 Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);\r
2050 return EFI_SECTION_ERROR;\r
2051 }\r
2052 } else {\r
2053 //\r
2054 // We don't know how to parse it now.\r
2055 //\r
2056 Error (NULL, 0, 0003, "Error parsing section", \\r
2057 "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
2058 return EFI_UNSUPPORTED;\r
2059 }\r
2060 break;\r
2061\r
2062 default:\r
2063 //\r
2064 // Unknown section, return error\r
2065 //\r
2066 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);\r
2067 return EFI_SECTION_ERROR;\r
2068 }\r
2069\r
2070 ParsedLength += SectionLength;\r
2071 //\r
2072 // We make then next section begin on a 4-byte boundary\r
2073 //\r
2074 ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
2075 }\r
2076\r
2077 if (ParsedLength < BufferLength) {\r
2078 Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);\r
2079 return EFI_SECTION_ERROR;\r
2080 }\r
2081\r
2082 return EFI_SUCCESS;\r
2083}\r
2084\r
2085EFI_STATUS\r
2086DumpDepexSection (\r
2087 IN UINT8 *Ptr,\r
2088 IN UINT32 SectionLength\r
2089 )\r
2090/*++\r
2091\r
2092Routine Description:\r
2093\r
2094 GC_TODO: Add function description\r
2095\r
2096Arguments:\r
2097\r
2098 Ptr - GC_TODO: add argument description\r
2099 SectionLength - GC_TODO: add argument description\r
2100\r
2101Returns:\r
2102\r
2103 EFI_SUCCESS - GC_TODO: Add description for return value\r
2104\r
2105--*/\r
2106{\r
2107 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
2108\r
2109 //\r
2110 // Need at least a section header + data\r
2111 //\r
2112 if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {\r
2113 return EFI_SUCCESS;\r
2114 }\r
2115\r
e4ac870f
LG
2116 Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
2117 SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
f51461c8
LG
2118 while (SectionLength > 0) {\r
2119 printf (" ");\r
2120 switch (*Ptr) {\r
2121 case EFI_DEP_BEFORE:\r
2122 printf ("BEFORE\n");\r
2123 Ptr++;\r
2124 SectionLength--;\r
2125 break;\r
2126\r
2127 case EFI_DEP_AFTER:\r
2128 printf ("AFTER\n");\r
2129 Ptr++;\r
2130 SectionLength--;\r
2131 break;\r
2132\r
2133 case EFI_DEP_PUSH:\r
2134 printf ("PUSH\n ");\r
2135 PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);\r
2136 printf ("%s ", GuidBuffer);\r
2137 PrintGuidName (GuidBuffer);\r
2138 printf ("\n");\r
2139 //\r
2140 // PrintGuid ((EFI_GUID *)(Ptr + 1));\r
2141 //\r
2142 Ptr += 17;\r
2143 SectionLength -= 17;\r
2144 break;\r
2145\r
2146 case EFI_DEP_AND:\r
2147 printf ("AND\n");\r
2148 Ptr++;\r
2149 SectionLength--;\r
2150 break;\r
2151\r
2152 case EFI_DEP_OR:\r
2153 printf ("OR\n");\r
2154 Ptr++;\r
2155 SectionLength--;\r
2156 break;\r
2157\r
2158 case EFI_DEP_NOT:\r
2159 printf ("NOT\n");\r
2160 Ptr++;\r
2161 SectionLength--;\r
2162 break;\r
2163\r
2164 case EFI_DEP_TRUE:\r
2165 printf ("TRUE\n");\r
2166 Ptr++;\r
2167 SectionLength--;\r
2168 break;\r
2169\r
2170 case EFI_DEP_FALSE:\r
2171 printf ("FALSE\n");\r
2172 Ptr++;\r
2173 SectionLength--;\r
2174 break;\r
2175\r
2176 case EFI_DEP_END:\r
2177 printf ("END DEPEX\n");\r
2178 Ptr++;\r
2179 SectionLength--;\r
2180 break;\r
2181\r
2182 case EFI_DEP_SOR:\r
2183 printf ("SOR\n");\r
2184 Ptr++;\r
2185 SectionLength--;\r
2186 break;\r
2187\r
2188 default:\r
2189 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);\r
2190 return EFI_SUCCESS;\r
2191 }\r
2192 }\r
2193\r
2194 return EFI_SUCCESS;\r
2195}\r
2196\r
2197EFI_STATUS\r
2198PrintGuidName (\r
2199 IN UINT8 *GuidStr\r
2200 )\r
2201/*++\r
2202\r
2203Routine Description:\r
2204\r
2205 GC_TODO: Add function description\r
2206\r
2207Arguments:\r
2208\r
2209 GuidStr - GC_TODO: add argument description\r
2210\r
2211Returns:\r
2212\r
2213 EFI_SUCCESS - GC_TODO: Add description for return value\r
2214 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
2215\r
2216--*/\r
2217{\r
2218 GUID_TO_BASENAME *GPtr;\r
2219 //\r
2220 // If we have a list of guid-to-basenames, then go through the list to\r
2221 // look for a guid string match. If found, print the basename to stdout,\r
2222 // otherwise return a failure.\r
2223 //\r
2224 GPtr = mGuidBaseNameList;\r
2225 while (GPtr != NULL) {\r
2226 if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {\r
2227 printf ("%s", GPtr->BaseName);\r
2228 return EFI_SUCCESS;\r
2229 }\r
2230\r
2231 GPtr = GPtr->Next;\r
2232 }\r
2233\r
2234 return EFI_INVALID_PARAMETER;\r
2235}\r
2236\r
2237EFI_STATUS\r
2238ParseGuidBaseNameFile (\r
2239 CHAR8 *FileName\r
2240 )\r
2241/*++\r
2242\r
2243Routine Description:\r
2244\r
2245 GC_TODO: Add function description\r
2246\r
2247Arguments:\r
2248\r
2249 FileName - GC_TODO: add argument description\r
2250\r
2251Returns:\r
2252\r
2253 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
2254 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value\r
2255 EFI_SUCCESS - GC_TODO: Add description for return value\r
2256\r
2257--*/\r
2258{\r
2259 FILE *Fptr;\r
2260 CHAR8 Line[MAX_LINE_LEN];\r
a9b4ee43 2261 CHAR8 FormatString[MAX_LINE_LEN];\r
f51461c8
LG
2262 GUID_TO_BASENAME *GPtr;\r
2263\r
97fa0ee9 2264 if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {\r
f51461c8
LG
2265 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);\r
2266 return EFI_DEVICE_ERROR;\r
2267 }\r
2268\r
d6a1ce3b
HW
2269 //\r
2270 // Generate the format string for fscanf\r
2271 //\r
a9b4ee43 2272 sprintf (\r
d6a1ce3b 2273 FormatString,\r
d6a1ce3b
HW
2274 "%%%us %%%us",\r
2275 (unsigned) sizeof (GPtr->Guid) - 1,\r
2276 (unsigned) sizeof (GPtr->BaseName) - 1\r
2277 );\r
2278\r
f51461c8
LG
2279 while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
2280 //\r
2281 // Allocate space for another guid/basename element\r
2282 //\r
2283 GPtr = malloc (sizeof (GUID_TO_BASENAME));\r
2284 if (GPtr == NULL) {\r
2a9afe80 2285 fclose (Fptr);\r
f51461c8
LG
2286 return EFI_OUT_OF_RESOURCES;\r
2287 }\r
2288\r
2289 memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));\r
d6a1ce3b 2290 if (sscanf (Line, FormatString, GPtr->Guid, GPtr->BaseName) == 2) {\r
f51461c8
LG
2291 GPtr->Next = mGuidBaseNameList;\r
2292 mGuidBaseNameList = GPtr;\r
2293 } else {\r
2294 //\r
2295 // Some sort of error. Just continue.\r
2296 //\r
2297 free (GPtr);\r
2298 }\r
2299 }\r
2300\r
2301 fclose (Fptr);\r
2302 return EFI_SUCCESS;\r
2303}\r
2304\r
2305EFI_STATUS\r
2306FreeGuidBaseNameList (\r
2307 VOID\r
2308 )\r
2309/*++\r
2310\r
2311Routine Description:\r
2312\r
2313 GC_TODO: Add function description\r
2314\r
2315Arguments:\r
2316\r
2317 None\r
2318\r
2319Returns:\r
2320\r
2321 EFI_SUCCESS - GC_TODO: Add description for return value\r
2322\r
2323--*/\r
2324{\r
2325 GUID_TO_BASENAME *Next;\r
2326\r
2327 while (mGuidBaseNameList != NULL) {\r
2328 Next = mGuidBaseNameList->Next;\r
2329 free (mGuidBaseNameList);\r
2330 mGuidBaseNameList = Next;\r
2331 }\r
2332\r
2333 return EFI_SUCCESS;\r
2334}\r
2335\r
2336\r
2337static\r
2338VOID\r
2339LoadGuidedSectionToolsTxt (\r
2340 IN CHAR8* FirmwareVolumeFilename\r
2341 )\r
2342{\r
2343 CHAR8* PeerFilename;\r
2344 CHAR8* Places[] = {\r
2345 NULL,\r
2346 //NULL,\r
2347 };\r
2348 UINTN Index;\r
2349\r
2350 Places[0] = FirmwareVolumeFilename;\r
2351 //Places[1] = mUtilityFilename;\r
2352\r
2353 mParsedGuidedSectionTools = NULL;\r
2354\r
2355 for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {\r
2356 PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");\r
2357 //printf("Loading %s...\n", PeerFilename);\r
2358 if (OsPathExists (PeerFilename)) {\r
2359 mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);\r
2360 }\r
2361 free (PeerFilename);\r
2362 if (mParsedGuidedSectionTools != NULL) {\r
2363 return;\r
2364 }\r
2365 }\r
2366}\r
2367\r
2368\r
2369void\r
2370Usage (\r
2371 VOID\r
2372 )\r
2373/*++\r
2374\r
2375Routine Description:\r
2376\r
2377 GC_TODO: Add function description\r
2378\r
2379Arguments:\r
2380\r
2381 None\r
2382\r
2383Returns:\r
2384\r
2385 GC_TODO: add return values\r
2386\r
2387--*/\r
2388{\r
2389 //\r
2390 // Summary usage\r
2391 //\r
2392 fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);\r
2393\r
2394 //\r
2395 // Copyright declaration\r
f7496d71
LG
2396 //\r
2397 fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
f4260465 2398 fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");\r
f51461c8
LG
2399\r
2400 //\r
2401 // Details Option\r
2402 //\r
730ffca1 2403 fprintf (stdout, "optional arguments:\n");\r
f51461c8 2404 fprintf (stdout, " -h, --help\n\\r
730ffca1
YZ
2405 Show this help message and exit\n");\r
2406 fprintf (stdout, " --version\n\\r
2407 Show program's version number and exit\n");\r
2408 fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\\r
2409 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");\r
2410 fprintf (stdout, " -v, --verbose\n\\r
2411 Print informational statements\n");\r
2412 fprintf (stdout, " -q, --quiet\n\\r
2413 Returns the exit code, error messages will be displayed\n");\r
2414 fprintf (stdout, " -s, --silent\n\\r
2415 Returns only the exit code; informational and error\n\\r
2416 messages are not displayed\n");\r
2417 fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\\r
2418 Parse the basename to file-guid cross reference file(s)\n");\r
2419 fprintf (stdout, " -f OFFSET, --offset OFFSET\n\\r
2420 The offset from the start of the input file to start \n\\r
2421 processing an FV\n");\r
9947f576
YZ
2422 fprintf (stdout, " --hash\n\\r
2423 Generate HASH value of the entire PE image\n");\r
730ffca1
YZ
2424 fprintf (stdout, " --sfo\n\\r
2425 Reserved for future use\n");\r
f51461c8
LG
2426}\r
2427\r