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