modified BaseTools/Source/C/GNUmakefile
authorjljusten <jljusten@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 3 Dec 2007 22:07:21 +0000 (22:07 +0000)
committerjljusten <jljusten@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 3 Dec 2007 22:07:21 +0000 (22:07 +0000)
modified   BaseTools/Source/C/Makefile
added      BaseTools/Source/C/VolInfo
added      BaseTools/Source/C/VolInfo/GNUmakefile
added      BaseTools/Source/C/VolInfo/Makefile
added      BaseTools/Source/C/VolInfo/VolInfo.c
added      BaseTools/Source/C/VolInfo/VolInfo.h
  Added VolInfo tool.

git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@901 7335b38e-4728-0410-8992-fb3ffe349368

Source/C/GNUmakefile
Source/C/Makefile
Source/C/VolInfo/GNUmakefile [new file with mode: 0644]
Source/C/VolInfo/Makefile [new file with mode: 0644]
Source/C/VolInfo/VolInfo.c [new file with mode: 0644]
Source/C/VolInfo/VolInfo.h [new file with mode: 0644]

index 2b69919..2d4eba3 100644 (file)
@@ -7,7 +7,19 @@ all: makerootdir subdirs $(MAKEROOT)/libs
 
 LIBRARIES = Common
 NON_BUILDABLE_APPLICATIONS = GenBootSector BootSectImage
-APPLICATIONS = GenFw GenSec GenFv GenFfs GenVtf EfiRom TianoCompress Split EfiLdrImage GenPage VfrCompile
+APPLICATIONS = \
+  EfiLdrImage \
+  EfiRom \
+  GenFfs \
+  GenFv \
+  GenFw \
+  GenPage \
+  GenSec \
+  GenVtf \
+  Split \
+  TianoCompress \
+  VolInfo \
+  VfrCompile
 
 SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
 
index 10dadec..6827734 100644 (file)
@@ -3,7 +3,22 @@ ARCH = IA32
 !INCLUDE Makefiles\ms.common
 
 LIBRARIES = Common
-APPLICATIONS = GenFw GenSec GenFv GenFfs GenVtf EfiRom TianoCompress Split GenBootSector BootSectImage EfiLdrImage GenPage VfrCompile GenCrc32
+APPLICATIONS = \
+  BootSectImage \
+  EfiLdrImage \
+  EfiRom \
+  GenBootSector \
+  GenCrc32 \
+  GenFfs \
+  GenFv \
+  GenFw \
+  GenPage \
+  GenSec \
+  GenVtf \
+  Split \
+  TianoCompress \
+  VolInfo \
+  VfrCompile
 
 all: libs apps install
 
diff --git a/Source/C/VolInfo/GNUmakefile b/Source/C/VolInfo/GNUmakefile
new file mode 100644 (file)
index 0000000..309f9cc
--- /dev/null
@@ -0,0 +1,12 @@
+ARCH ?= IA32
+MAKEROOT ?= ..
+
+APPNAME = VolInfo
+
+OBJECTS = VolInfo.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+
+
diff --git a/Source/C/VolInfo/Makefile b/Source/C/VolInfo/Makefile
new file mode 100644 (file)
index 0000000..6bf58de
--- /dev/null
@@ -0,0 +1,10 @@
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = VolInfo
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = VolInfo.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/Source/C/VolInfo/VolInfo.c b/Source/C/VolInfo/VolInfo.c
new file mode 100644 (file)
index 0000000..051524a
--- /dev/null
@@ -0,0 +1,1807 @@
+/*++
+
+Copyright (c) 1999 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+  VolInfo.c
+
+Abstract:
+
+  The tool dumps the contents of a firmware volume
+
+--*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <FvLib.h>
+#include <Common/UefiBaseTypes.h>
+#include <Common/UefiCapsule.h>
+#include <Common/PiFirmwareFile.h>
+#include <Common/PiFirmwareVolume.h>
+#include <Guid/PiFirmwareFileSystem.h>
+#include <IndustryStandard/PeImage.h>
+#include <Protocol/GuidedSectionExtraction.h>
+
+#include "Compress.h"
+#include "Decompress.h"
+#include "VolInfo.h"
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+#include "FirmwareVolumeBufferLib.h"
+#include "OsPath.h"
+#include "ParseGuidedSectionTools.h"
+#include "StringFuncs.h"
+
+//
+// Utility global variables
+//
+
+EFI_GUID  gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
+
+#define UTILITY_MAJOR_VERSION      0
+#define UTILITY_MINOR_VERSION      82
+
+#define UTILITY_NAME         "VolInfo"
+
+#define EFI_SECTION_ERROR EFIERR (100)
+
+#define MAX_BASENAME_LEN  60  // not good to hardcode, but let's be reasonable
+
+//
+// Structure to keep a list of guid-to-basenames
+//
+typedef struct _GUID_TO_BASENAME {
+  struct _GUID_TO_BASENAME  *Next;
+  INT8                      Guid[PRINTED_GUID_BUFFER_SIZE];
+  INT8                      BaseName[MAX_BASENAME_LEN];
+} GUID_TO_BASENAME;
+
+static GUID_TO_BASENAME *mGuidBaseNameList = NULL;
+
+//
+// Store GUIDed Section guid->tool mapping
+//
+EFI_HANDLE mParsedGuidedSectionTools = NULL;
+
+CHAR8* mUtilityFilename = NULL;
+
+EFI_STATUS
+ParseGuidBaseNameFile (
+  INT8    *FileName
+  );
+
+EFI_STATUS
+FreeGuidBaseNameList (
+  VOID
+  );
+
+EFI_STATUS
+PrintGuidName (
+  IN UINT8    *GuidStr
+  );
+
+EFI_STATUS
+ParseSection (
+  IN UINT8  *SectionBuffer,
+  IN UINT32 BufferLength
+  );
+
+EFI_STATUS
+DumpDepexSection (
+  IN UINT8    *Ptr,
+  IN UINT32   SectionLength
+  );
+
+static
+int
+ReadHeader (
+  IN FILE       *InputFile,
+  OUT UINT32    *FvSize,
+  OUT BOOLEAN   *ErasePolarity
+  );
+
+static
+int
+PrintFileInfo (
+  EFI_FIRMWARE_VOLUME_HEADER  *FvImage,
+  EFI_FFS_FILE_HEADER         *FileHeader,
+  BOOLEAN                     ErasePolarity
+  );
+
+static
+EFI_STATUS
+PrintFvInfo (
+  IN VOID                         *Fv
+  );
+
+static
+VOID
+LoadGuidedSectionToolsTxt (
+  IN CHAR8* FirmwareVolumeFilename
+  );
+
+void
+Usage (
+  VOID
+  );
+
+int
+main (
+  int       argc,
+  char      *argv[]
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  argc  - GC_TODO: add argument description
+  ]     - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  FILE                        *InputFile;
+  int                         BytesRead;
+  EFI_FIRMWARE_VOLUME_HEADER  *FvImage;
+  UINT32                      FvSize;
+  EFI_STATUS                  Status;
+  UINT32                      Offset;
+  BOOLEAN                     ErasePolarity;
+
+  SetUtilityName (UTILITY_NAME);
+  //
+  // Print utility header
+  //
+  printf ("%s Tiano Firmware Volume FFS image info.  Version %d.%d, %s\n",
+    UTILITY_NAME,
+    UTILITY_MAJOR_VERSION,
+    UTILITY_MINOR_VERSION,
+    __DATE__
+    );
+
+  //
+  // Save, and then skip filename arg
+  //
+  mUtilityFilename = argv[0];
+  argc--;
+  argv++;
+
+  Offset = 0;
+
+  //
+  // If they specified -x xref guid/basename cross-reference files, process it.
+  // This will print the basename beside each file guid. To use it, specify
+  // -x xref_filename to processdsc, then use xref_filename as a parameter
+  // here.
+  //
+  while (argc > 2) {
+    if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {
+      ParseGuidBaseNameFile (argv[1]);
+      printf("ParseGuidBaseNameFile: %s\n", argv[1]);
+      argc -= 2;
+      argv += 2;
+    } else if (strcmp(argv[0], "--offset") == 0) {
+      //
+      // Hex or decimal?
+      //
+      if ((argv[1][0] == '0') && (tolower (argv[1][1]) == 'x')) {
+        if (sscanf (argv[1], "%x", &Offset) != 1) {
+          Error (NULL, 0, 0, argv[1], "invalid offset specified");
+          return GetUtilityStatus ();
+        }
+      } else {
+        if (sscanf (argv[1], "%d", &Offset) != 1) {
+          Error (NULL, 0, 0, argv[1], "invalid offset specified");
+          return GetUtilityStatus ();
+        }
+        //
+        // See if they said something like "64K"
+        //
+        if (tolower (argv[1][strlen (argv[1]) - 1]) == 'k') {
+          Offset *= 1024;
+        }
+      }
+
+      argc -= 2;
+      argv += 2;
+    } else {
+      Usage ();
+      return -1;
+    }
+  }
+  //
+  // Check for proper number of arguments
+  //
+  if (argc != 1) {
+    Usage ();
+    return -1;
+  }
+  //
+  // Look for help options
+  //
+  if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) || 
+      (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {
+    Usage();
+    return STATUS_ERROR;
+  }
+
+  //
+  // Open the file containing the FV
+  //
+  InputFile = fopen (argv[0], "rb");
+  if (InputFile == NULL) {
+    Error (NULL, 0, 0, argv[0], "failed to open input FV file");
+    return GetUtilityStatus ();
+  }
+  //
+  // Skip over pad bytes if specified. This is used if they prepend 0xff
+  // data to the FV image binary.
+  //
+  if (Offset != 0) {
+    fseek (InputFile, Offset, SEEK_SET);
+  }
+  //
+  // Determine size of FV
+  //
+  Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);
+  if (EFI_ERROR (Status)) {
+    Error (NULL, 0, 0, argv[0], "failed to parse FV header");
+    fclose (InputFile);
+    return GetUtilityStatus ();
+  }
+  //
+  // Allocate a buffer for the FV image
+  //
+  FvImage = malloc (FvSize);
+  if (FvImage == NULL) {
+    Error (__FILE__, __LINE__, 0, "application error", "memory allocation failed");
+    fclose (InputFile);
+    return GetUtilityStatus ();
+  }
+  //
+  // Seek to the start of the image, then read the entire FV to the buffer
+  //
+  fseek (InputFile, Offset, SEEK_SET);
+  BytesRead = fread (FvImage, 1, FvSize, InputFile);
+  fclose (InputFile);
+  if ((unsigned int) BytesRead != FvSize) {
+    Error (NULL, 0, 0, argv[0], "failed to read FV from file");
+    free (FvImage);
+    return GetUtilityStatus ();
+  }
+
+  LoadGuidedSectionToolsTxt (argv[0]);
+
+  PrintFvInfo (FvImage);
+
+  //
+  // Clean up
+  //
+  free (FvImage);
+  FreeGuidBaseNameList ();
+  return GetUtilityStatus ();
+}
+
+
+static
+EFI_STATUS
+PrintFvInfo (
+  IN VOID                         *Fv
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Fv            - Firmware Volume to print information about
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  EFI_STATUS                  Status;
+  UINTN                       NumberOfFiles;
+  BOOLEAN                     ErasePolarity;
+  UINTN                       FvSize;
+  EFI_FFS_FILE_HEADER         *CurrentFile;
+  UINTN                       Key;
+
+  Status = FvBufGetSize (Fv, &FvSize);
+
+  NumberOfFiles = 0;
+  ErasePolarity =
+    (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?
+      TRUE : FALSE;
+
+  //
+  // Get the first file
+  //
+  Key = 0;
+  Status = FvBufFindNextFile (Fv, &Key, &CurrentFile);
+  if (EFI_ERROR (Status)) {
+    Error (NULL, 0, 0, NULL, "cannot find the first file in the FV image");
+    return GetUtilityStatus ();
+  }
+  //
+  // Display information about files found
+  //
+  while (CurrentFile != NULL) {
+    //
+    // Increment the number of files counter
+    //
+    NumberOfFiles++;
+
+    //
+    // Display info about this file
+    //
+    Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);
+    if (EFI_ERROR (Status)) {
+      Error (NULL, 0, 0, NULL, "failed to parse a file in the FV");
+      return GetUtilityStatus ();
+    }
+    //
+    // Get the next file
+    //
+    Status = FvBufFindNextFile (Fv, &Key, &CurrentFile);
+    if (Status == EFI_NOT_FOUND) {
+      CurrentFile = NULL;
+    } else if (EFI_ERROR (Status)) {
+      Error (NULL, 0, 0, NULL, "cannot find the next file in the FV image");
+      return GetUtilityStatus ();
+    }
+  }
+
+  printf ("There are a total of %d files in this FV\n", NumberOfFiles);
+
+  return EFI_SUCCESS;
+}
+
+UINT32
+GetOccupiedSize (
+  IN UINT32  ActualSize,
+  IN UINT32  Alignment
+  )
+/*++
+
+Routine Description:
+
+  This function returns the next larger size that meets the alignment 
+  requirement specified.
+
+Arguments:
+
+  ActualSize      The size.
+  Alignment       The desired alignment.
+    
+Returns:
+  EFI_SUCCESS             Function completed successfully.
+  EFI_ABORTED             The function encountered an error.
+
+--*/
+{
+  UINT32  OccupiedSize;
+
+  OccupiedSize = ActualSize;
+  while ((OccupiedSize & (Alignment - 1)) != 0) {
+    OccupiedSize++;
+  }
+
+  return OccupiedSize;
+}
+
+static
+CHAR8 *
+SectionNameToStr (
+  IN EFI_SECTION_TYPE   Type
+  )
+/*++
+
+Routine Description:
+
+  Converts EFI Section names to Strings
+
+Arguments:
+
+  Type  - The EFI Section type
+
+Returns:
+
+  CHAR8* - Pointer to the String containing the section name.
+
+--*/
+{
+  CHAR8 *SectionStr;
+  CHAR8 *SectionTypeStringTable[] = {
+    "EFI_SECTION_ALL",
+    //
+    // 0X00
+    //
+    "EFI_SECTION_COMPRESSION",
+    //
+    // 0x01
+    //
+    "EFI_SECTION_GUID_DEFINED",
+    //
+    // 0x02
+    //
+    "Unknown section type - Reserved 0x03",
+    //
+    // 0x03
+    //
+    "Unknown section type - Reserved 0x04",
+    //
+    // 0x04
+    //
+    "Unknown section type - Reserved 0x05",
+    //
+    // 0x05
+    //
+    "Unknown section type - Reserved 0x06",
+    //
+    // 0x06
+    //
+    "Unknown section type - Reserved 0x07",
+    //
+    // 0x07
+    //
+    "Unknown section type - Reserved 0x08",
+    //
+    // 0x08
+    //
+    "Unknown section type - Reserved 0x09",
+    //
+    // 0x09
+    //
+    "Unknown section type - Reserved 0x0A",
+    //
+    // 0x0A
+    //
+    "Unknown section type - Reserved 0x0B",
+    //
+    // 0x0B
+    //
+    "Unknown section type - Reserved 0x0C",
+    //
+    // 0x0C
+    //
+    "Unknown section type - Reserved 0x0D",
+    //
+    // 0x0D
+    //
+    "Unknown section type - Reserved 0x0E",
+    //
+    // 0x0E
+    //
+    "Unknown section type - Reserved 0x0F",
+    //
+    // 0x0F
+    //
+    "EFI_SECTION_PE32",
+    //
+    // 0x10
+    //
+    "EFI_SECTION_PIC",
+    //
+    // 0x11
+    //
+    "EFI_SECTION_TE",
+    //
+    // 0x12
+    //
+    "EFI_SECTION_DXE_DEPEX",
+    //
+    // 0x13
+    //
+    "EFI_SECTION_VERSION",
+    //
+    // 0x14
+    //
+    "EFI_SECTION_USER_INTERFACE",
+    //
+    // 0x15
+    //
+    "EFI_SECTION_COMPATIBILITY16",
+    //
+    // 0x16
+    //
+    "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
+    //
+    // 0x17
+    //
+    "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
+    //
+    // 0x18
+    //
+    "EFI_SECTION_RAW",
+    //
+    // 0x19
+    //
+    "Unknown section type - 0x1A",
+    //
+    // 0x1A
+    //
+    "EFI_SECTION_PEI_DEPEX",
+    //
+    // 0x1B
+    //
+    "Unknown section type - Reserved - beyond last defined section"
+    //
+    // 0x1C+
+    //
+  };
+
+  if (Type > EFI_SECTION_LAST_SECTION_TYPE) {
+    Type = EFI_SECTION_LAST_SECTION_TYPE + 1;
+  }
+
+  SectionStr = malloc (100);
+  if (SectionStr == NULL) {
+    printf ("Error: Out of memory resources.\n");
+    return SectionStr;
+  }
+  strcpy (SectionStr, SectionTypeStringTable[Type]);
+  return SectionStr;
+}
+
+static
+int
+ReadHeader (
+  IN FILE       *InputFile,
+  OUT UINT32    *FvSize,
+  OUT BOOLEAN   *ErasePolarity
+  )
+/*++
+
+Routine Description:
+
+  This function determines the size of the FV and the erase polarity.  The 
+  erase polarity is the FALSE value for file state.
+
+Arguments:
+
+  InputFile       The file that contains the FV image.
+  FvSize          The size of the FV.
+  ErasePolarity   The FV erase polarity.
+    
+Returns:
+  EFI_SUCCESS             Function completed successfully.
+  EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.
+  EFI_ABORTED             The function encountered an error.
+
+--*/
+{
+  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;
+  EFI_FV_BLOCK_MAP_ENTRY      BlockMap;
+  UINTN                       Signature[2];
+  UINTN                       BytesRead;
+  UINT32                      Size;
+
+  BytesRead = 0;
+  Size      = 0;
+  //
+  // Check input parameters
+  //
+  if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {
+    Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Read the header
+  //
+  fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
+  BytesRead     = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+  Signature[0]  = VolumeHeader.Signature;
+  Signature[1]  = 0;
+
+  //
+  // Print FV header information
+  //
+  printf ("Signature:        %s (%X)\n", Signature, VolumeHeader.Signature);
+  printf ("Attributes:       %X\n", VolumeHeader.Attributes);
+
+  if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {
+    printf ("       EFI_FVB2_READ_DISABLED_CAP\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {
+    printf ("       EFI_FVB2_READ_ENABLED_CAP\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {
+    printf ("       EFI_FVB2_READ_STATUS\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {
+    printf ("       EFI_FVB2_WRITE_DISABLED_CAP\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {
+    printf ("       EFI_FVB2_WRITE_ENABLED_CAP\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {
+    printf ("       EFI_FVB2_WRITE_STATUS\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {
+    printf ("       EFI_FVB2_LOCK_CAP\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {
+    printf ("       EFI_FVB2_LOCK_STATUS\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {
+    printf ("       EFI_FVB2_STICKY_WRITE\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {
+    printf ("       EFI_FVB2_MEMORY_MAPPED\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {
+    printf ("       EFI_FVB2_ERASE_POLARITY\n");
+    *ErasePolarity = TRUE;
+  }
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {
+    printf ("       EFI_FVB2_ALIGNMENT\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {
+    printf ("       EFI_FVB2_ALIGNMENT_2\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {
+    printf ("       EFI_FVB2_ALIGNMENT_4\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {
+    printf ("       EFI_FVB2_ALIGNMENT_8\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {
+    printf ("       EFI_FVB2_ALIGNMENT_16\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {
+    printf ("       EFI_FVB2_ALIGNMENT_32\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {
+    printf ("        EFI_FVB2_ALIGNMENT_64\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {
+    printf ("        EFI_FVB2_ALIGNMENT_128\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {
+    printf ("        EFI_FVB2_ALIGNMENT_256\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {
+    printf ("        EFI_FVB2_ALIGNMENT_512\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {
+    printf ("        EFI_FVB2_ALIGNMENT_1K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {
+    printf ("        EFI_FVB2_ALIGNMENT_2K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {
+    printf ("        EFI_FVB2_ALIGNMENT_4K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {
+    printf ("        EFI_FVB2_ALIGNMENT_8K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {
+    printf ("        EFI_FVB2_ALIGNMENT_16K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {
+    printf ("        EFI_FVB2_ALIGNMENT_32K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {
+    printf ("        EFI_FVB2_ALIGNMENT_64K\n");
+  }
+  
+#else
+
+  if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {
+    printf ("       EFI_FVB2_READ_LOCK_CAP\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {
+    printf ("       EFI_FVB2_READ_LOCK_STATUS\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {
+    printf ("       EFI_FVB2_WRITE_LOCK_CAP\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {
+    printf ("       EFI_FVB2_WRITE_LOCK_STATUS\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {
+    printf ("       EFI_FVB2_ALIGNMENT_1\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {
+    printf ("        EFI_FVB2_ALIGNMENT_2\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {
+    printf ("        EFI_FVB2_ALIGNMENT_4\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {
+    printf ("        EFI_FVB2_ALIGNMENT_8\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {
+    printf ("        EFI_FVB2_ALIGNMENT_16\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {
+    printf ("        EFI_FVB2_ALIGNMENT_32\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {
+    printf ("        EFI_FVB2_ALIGNMENT_64\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {
+    printf ("        EFI_FVB2_ALIGNMENT_128\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {
+    printf ("        EFI_FVB2_ALIGNMENT_256\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {
+    printf ("        EFI_FVB2_ALIGNMENT_512\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {
+    printf ("        EFI_FVB2_ALIGNMENT_1K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {
+    printf ("        EFI_FVB2_ALIGNMENT_2K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {
+    printf ("        EFI_FVB2_ALIGNMENT_4K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {
+    printf ("        EFI_FVB2_ALIGNMENT_8K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {
+    printf ("        EFI_FVB2_ALIGNMENT_16K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {
+    printf ("        EFI_FVB2_ALIGNMENT_32K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {
+    printf ("        EFI_FVB2_ALIGNMENT_64K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {
+    printf ("        EFI_FVB2_ALIGNMENT_128K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {
+    printf ("        EFI_FVB2_ALIGNMENT_256K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMNET_512K) {
+    printf ("        EFI_FVB2_ALIGNMNET_512K\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {
+    printf ("        EFI_FVB2_ALIGNMENT_1M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {
+    printf ("        EFI_FVB2_ALIGNMENT_2M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {
+    printf ("        EFI_FVB2_ALIGNMENT_4M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {
+    printf ("        EFI_FVB2_ALIGNMENT_8M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {
+    printf ("        EFI_FVB2_ALIGNMENT_16M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {
+    printf ("        EFI_FVB2_ALIGNMENT_32M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
+    printf ("        EFI_FVB2_ALIGNMENT_64M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
+    printf ("        EFI_FVB2_ALIGNMENT_128M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
+    printf ("        EFI_FVB2_ALIGNMENT_64M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
+    printf ("        EFI_FVB2_ALIGNMENT_128M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {
+    printf ("        EFI_FVB2_ALIGNMENT_256M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {
+    printf ("        EFI_FVB2_ALIGNMENT_512M\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {
+    printf ("        EFI_FVB2_ALIGNMENT_1G\n");
+  }
+
+  if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {
+    printf ("        EFI_FVB2_ALIGNMENT_2G\n");
+  }
+
+#endif
+  printf ("Header Length:         0x%08X\n", VolumeHeader.HeaderLength);
+  printf ("File System ID:        ");
+  PrintGuid (&VolumeHeader.FileSystemGuid);
+  //
+  // printf ("\n");
+  //
+  printf ("Revision:              0x%04X\n", VolumeHeader.Revision);
+
+  do {
+    fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
+    BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+
+    if (BlockMap.NumBlocks != 0) {
+      printf ("Number of Blocks:      0x%08X\n", BlockMap.NumBlocks);
+      printf ("Block Length:          0x%08X\n", BlockMap.Length);
+      Size += BlockMap.NumBlocks * BlockMap.Length;
+    }
+
+  } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));
+
+  if (BytesRead != VolumeHeader.HeaderLength) {
+    printf ("ERROR: Header length not consistent with Block Maps!\n");
+    return EFI_ABORTED;
+  }
+
+  if (VolumeHeader.FvLength != Size) {
+    printf ("ERROR: Volume Size not consistant with Block Maps!\n");
+    return EFI_ABORTED;
+  }
+
+  printf ("Total Volume Size:     0x%08X\n", Size);
+
+  *FvSize = Size;
+
+  //
+  // rewind (InputFile);
+  //
+  return EFI_SUCCESS;
+}
+
+static
+int
+PrintFileInfo (
+  EFI_FIRMWARE_VOLUME_HEADER  *FvImage,
+  EFI_FFS_FILE_HEADER         *FileHeader,
+  BOOLEAN                     ErasePolarity
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  FvImage       - GC_TODO: add argument description
+  FileHeader    - GC_TODO: add argument description
+  ErasePolarity - GC_TODO: add argument description
+
+Returns:
+
+  EFI_SUCCESS - GC_TODO: Add description for return value
+  EFI_ABORTED - GC_TODO: Add description for return value
+
+--*/
+{
+  UINT32              FileLength;
+  UINT8               FileState;
+  UINT8               Checksum;
+  EFI_FFS_FILE_HEADER BlankHeader;
+  EFI_STATUS          Status;
+  UINT8               GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
+#if (PI_SPECIFICATION_VERSION < 0x00010000) 
+  UINT16              *Tail;
+#endif
+  //
+  // Check if we have free space
+  //
+  if (ErasePolarity) {
+    memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER));
+  } else {
+    memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
+  }
+
+  if (memcmp (&BlankHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) {
+    return EFI_SUCCESS;
+  }
+  //
+  // Print file information.
+  //
+  printf ("============================================================\n");
+
+  printf ("File Name:        ");
+  PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);
+  printf ("%s  ", GuidBuffer);
+  PrintGuidName (GuidBuffer);
+  printf ("\n");
+
+  //
+  //  PrintGuid (&FileHeader->Name);
+  //  printf ("\n");
+  //
+  FileLength = GetLength (FileHeader->Size);
+  printf ("File Offset:      0x%08X\n", (UINTN) FileHeader - (UINTN) FvImage);
+  printf ("File Length:      0x%08X\n", FileLength);
+  printf ("File Attributes:  0x%02X\n", FileHeader->Attributes);
+  printf ("File State:       0x%02X\n", FileHeader->State);
+
+  //
+  // Print file state
+  //
+  FileState = GetFileState (ErasePolarity, FileHeader);
+
+  switch (FileState) {
+
+  case EFI_FILE_HEADER_CONSTRUCTION:
+    printf ("        EFI_FILE_HEADER_CONSTRUCTION\n");
+    return EFI_SUCCESS;
+
+  case EFI_FILE_HEADER_INVALID:
+    printf ("        EFI_FILE_HEADER_INVALID\n");
+    return EFI_SUCCESS;
+
+  case EFI_FILE_HEADER_VALID:
+    printf ("        EFI_FILE_HEADER_VALID\n");
+    Checksum  = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
+    Checksum  = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
+    Checksum  = (UINT8) (Checksum - FileHeader->State);
+    if (Checksum != 0) {
+      printf ("ERROR: Header checksum invalid.\n");
+      return EFI_ABORTED;
+    }
+
+    return EFI_SUCCESS;
+
+  case EFI_FILE_DELETED:
+    printf ("        EFI_FILE_DELETED\n");
+
+  case EFI_FILE_MARKED_FOR_UPDATE:
+    printf ("        EFI_FILE_MARKED_FOR_UPDATE\n");
+
+  case EFI_FILE_DATA_VALID:
+    printf ("        EFI_FILE_DATA_VALID\n");
+
+    //
+    // Calculate header checksum
+    //
+    Checksum  = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
+    Checksum  = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
+    Checksum  = (UINT8) (Checksum - FileHeader->State);
+    if (Checksum != 0) {
+      Error (NULL, 0, 0, "invalid header checksum", NULL);
+      return EFI_ABORTED;
+    }
+
+    FileLength = GetLength (FileHeader->Size);
+
+    if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
+      //
+      // Calculate file checksum
+      //
+      Checksum  = CalculateSum8 ((UINT8 *) FileHeader, FileLength);
+      Checksum  = (UINT8) (Checksum - FileHeader->State);
+      if (Checksum != 0) {
+        Error (NULL, 0, 0, "invalid file checksum", NULL);
+        return EFI_ABORTED;
+      }
+    } else {
+      if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
+        Error (NULL, 0, 0, "invalid header checksum -- not set to fixed value of 0x5A", NULL);
+        return EFI_ABORTED;
+      }
+    }
+#if (PI_SPECIFICATION_VERSION < 0x00010000)    
+    //
+    // Verify tail if present
+    //
+    if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
+      //
+      // Verify tail is complement of integrity check field in the header.
+      //
+      Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));
+      if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {
+        Error (NULL, 0, 0, "integrity check failed", "tail is not the complement of the header field");
+        return EFI_ABORTED;
+      }
+    }
+ #endif   
+    break;
+
+  default:
+    Error (NULL, 0, 0, "invalid/unrecognized file state bits", NULL);
+    return EFI_ABORTED;
+  }
+
+  printf ("File Type:        0x%02X  ", FileHeader->Type);
+
+  switch (FileHeader->Type) {
+
+  case EFI_FV_FILETYPE_RAW:
+    printf ("EFI_FV_FILETYPE_RAW\n");
+    break;
+
+  case EFI_FV_FILETYPE_FREEFORM:
+    printf ("EFI_FV_FILETYPE_FREEFORM\n");
+    break;
+
+  case EFI_FV_FILETYPE_SECURITY_CORE:
+    printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
+    break;
+
+  case EFI_FV_FILETYPE_PEI_CORE:
+    printf ("EFI_FV_FILETYPE_PEI_CORE\n");
+    break;
+
+  case EFI_FV_FILETYPE_DXE_CORE:
+    printf ("EFI_FV_FILETYPE_DXE_CORE\n");
+    break;
+
+  case EFI_FV_FILETYPE_PEIM:
+    printf ("EFI_FV_FILETYPE_PEIM\n");
+    break;
+
+  case EFI_FV_FILETYPE_DRIVER:
+    printf ("EFI_FV_FILETYPE_DRIVER\n");
+    break;
+
+  case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
+    printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
+    break;
+
+  case EFI_FV_FILETYPE_APPLICATION:
+    printf ("EFI_FV_FILETYPE_APPLICATION\n");
+    break;
+
+  case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
+    printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
+    break;
+
+  case EFI_FV_FILETYPE_FFS_PAD:
+    printf ("EFI_FV_FILETYPE_FFS_PAD\n");
+    break;
+
+  default:
+    printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);
+    return EFI_ABORTED;
+    break;
+  }
+
+  switch (FileHeader->Type) {
+
+  case EFI_FV_FILETYPE_ALL:
+  case EFI_FV_FILETYPE_RAW:
+  case EFI_FV_FILETYPE_FFS_PAD:
+    break;
+
+  default:
+    //
+    // All other files have sections
+    //
+    Status = ParseSection (
+              (UINT8 *) ((UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER)),
+              GetLength (FileHeader->Size) - sizeof (EFI_FFS_FILE_HEADER)
+              );
+    if (EFI_ERROR (Status)) {
+      //
+      // printf ("ERROR: Parsing the FFS file.\n");
+      //
+      return EFI_ABORTED;
+    }
+    break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ParseSection (
+  IN UINT8  *SectionBuffer,
+  IN UINT32 BufferLength
+  )
+/*++
+
+Routine Description:
+
+  Parses EFI Sections
+
+Arguments:
+
+  SectionBuffer - Buffer containing the section to parse.
+  BufferLength  - Length of SectionBuffer
+
+Returns:
+
+  EFI_SECTION_ERROR - Problem with section parsing.
+                      (a) compression errors
+                      (b) unrecognized section 
+  EFI_UNSUPPORTED - Do not know how to parse the section.
+  EFI_SUCCESS - Section successfully parsed.
+  EFI_OUT_OF_RESOURCES - Memory allocation failed.
+
+--*/
+{
+  EFI_SECTION_TYPE    Type;
+  UINT8               *Ptr;
+  UINT32              SectionLength;
+  CHAR8               *SectionName;
+  EFI_STATUS          Status;
+  UINT32              ParsedLength;
+  UINT8               *CompressedBuffer;
+  UINT32              CompressedLength;
+  UINT8               *UncompressedBuffer;
+  UINT32              UncompressedLength;
+  UINT8               *ToolOutputBuffer;
+  UINT32              ToolOutputLength;
+  UINT8               CompressionType;
+  UINT32              DstSize;
+  UINT32              ScratchSize;
+  UINT8               *ScratchBuffer;
+  DECOMPRESS_FUNCTION DecompressFunction;
+  GETINFO_FUNCTION    GetInfoFunction;
+  // CHAR16              *name;
+  CHAR8               *ExtractionTool;
+  CHAR8               *ToolInputFile;
+  CHAR8               *ToolOutputFile;
+  CHAR8               *SystemCommandFormatString;
+  CHAR8               *SystemCommand;
+
+  ParsedLength = 0;
+  while (ParsedLength < BufferLength) {
+    Ptr           = SectionBuffer + ParsedLength;
+
+    SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);
+    Type          = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;
+
+    //
+    // This is sort of an odd check, but is necessary because FFS files are
+    // padded to a QWORD boundary, meaning there is potentially a whole section
+    // header worth of 0xFF bytes.
+    //
+    if (SectionLength == 0xffffff && Type == 0xff) {
+      ParsedLength += 4;
+      continue;
+    }
+
+    SectionName = SectionNameToStr (Type);
+    printf ("------------------------------------------------------------\n");
+    printf ("  Type:  %s\n  Size:  0x%08X\n", SectionName, SectionLength);
+    free (SectionName);
+
+    switch (Type) {
+    case EFI_SECTION_RAW:
+    case EFI_SECTION_PE32:
+    case EFI_SECTION_PIC:
+    case EFI_SECTION_TE:
+      // default is no more information
+      break;
+
+    case EFI_SECTION_USER_INTERFACE:
+      // name = &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString;
+      // printf ("  String: %s\n", &name);
+      break;
+
+    case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
+      Status = PrintFvInfo (((EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)Ptr) + 1);
+      if (EFI_ERROR (Status)) {
+        Error (NULL, 0, 0, "printing of FV section contents failed", NULL);
+        return EFI_SECTION_ERROR;
+      }
+      break;
+
+    case EFI_SECTION_COMPATIBILITY16:
+    case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
+      //
+      // Section does not contain any further header information.
+      //
+      break;
+
+    case EFI_SECTION_DXE_DEPEX:
+    case EFI_SECTION_PEI_DEPEX:
+      DumpDepexSection (Ptr, SectionLength);
+      break;
+
+    case EFI_SECTION_VERSION:
+      printf ("  Build Number:  0x%02X\n", ((EFI_VERSION_SECTION *) Ptr)->BuildNumber);
+      printf ("  Version Strg:  %s\n", ((EFI_VERSION_SECTION *) Ptr)->VersionString);
+      break;
+
+    case EFI_SECTION_COMPRESSION:
+      UncompressedBuffer  = NULL;
+      CompressedLength    = SectionLength - sizeof (EFI_COMPRESSION_SECTION);
+      UncompressedLength  = ((EFI_COMPRESSION_SECTION *) Ptr)->UncompressedLength;
+      CompressionType     = ((EFI_COMPRESSION_SECTION *) Ptr)->CompressionType;
+      printf ("  Uncompressed Length:  0x%08X\n", UncompressedLength);
+
+      if (CompressionType == EFI_NOT_COMPRESSED) {
+        printf ("  Compression Type:  EFI_NOT_COMPRESSED\n");
+        if (CompressedLength != UncompressedLength) {
+          Error (
+            NULL,
+            0,
+            0,
+            "file is not compressed, but the compressed length does not match the uncompressed length",
+            NULL
+            );
+          return EFI_SECTION_ERROR;
+        }
+
+        UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION);
+      } else if (CompressionType == EFI_STANDARD_COMPRESSION) {
+        GetInfoFunction     = EfiGetInfo;
+        DecompressFunction  = EfiDecompress;
+        printf ("  Compression Type:  EFI_STANDARD_COMPRESSION\n");
+
+        CompressedBuffer  = Ptr + sizeof (EFI_COMPRESSION_SECTION);
+
+        Status            = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 0, "error getting compression info for file", NULL);
+          return EFI_SECTION_ERROR;
+        }
+
+        if (DstSize != UncompressedLength) {
+          Error (NULL, 0, 0, "compression error in the compression section", NULL);
+          return EFI_SECTION_ERROR;
+        }
+
+        ScratchBuffer       = malloc (ScratchSize);
+        UncompressedBuffer  = malloc (UncompressedLength);
+        if ((ScratchBuffer == NULL) || (UncompressedBuffer == NULL)) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+        Status = DecompressFunction (
+                  CompressedBuffer,
+                  CompressedLength,
+                  UncompressedBuffer,
+                  UncompressedLength,
+                  ScratchBuffer,
+                  ScratchSize
+                  );
+        free (ScratchBuffer);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 0, "decompress failed", NULL);
+          free (UncompressedBuffer);
+          return EFI_SECTION_ERROR;
+        }
+      } else {
+        Error (NULL, 0, 0, "unrecognized compression type", "type 0x%X", (UINT32) CompressionType);
+        return EFI_SECTION_ERROR;
+      }
+
+      Status = ParseSection (UncompressedBuffer, UncompressedLength);
+
+      if (CompressionType == EFI_STANDARD_COMPRESSION) {
+        //
+        // We need to deallocate Buffer
+        //
+        free (UncompressedBuffer);
+      }
+
+      if (EFI_ERROR (Status)) {
+        Error (NULL, 0, 0, "failed to parse section", NULL);
+        return EFI_SECTION_ERROR;
+      }
+      break;
+
+    case EFI_SECTION_GUID_DEFINED:
+      printf ("  SectionDefinitionGuid:  ");
+      PrintGuid (&((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid);
+      printf ("\n");
+      printf ("  DataOffset:             0x%04X\n", ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset);
+      printf ("  Attributes:             0x%04X\n", ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes);
+
+      ExtractionTool =
+        LookupGuidedSectionToolPath (
+          mParsedGuidedSectionTools,
+          &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid
+          );
+
+      if (ExtractionTool != NULL) {
+
+        ToolInputFile = CloneString (tmpnam (NULL));
+        ToolOutputFile = CloneString (tmpnam (NULL));
+
+        //
+        // Construction 'system' command string
+        //
+        SystemCommandFormatString = "%s -d -o %s %s";
+        SystemCommand = malloc (
+          strlen (SystemCommandFormatString) +
+          strlen (ExtractionTool) +
+          strlen (ToolInputFile) +
+          strlen (ToolOutputFile) +
+          1
+          );
+        sprintf (
+          SystemCommand,
+          SystemCommandFormatString,
+          ExtractionTool,
+          ToolOutputFile,
+          ToolInputFile
+          );
+        free (ExtractionTool);
+
+        Status =
+          PutFileImage (
+            ToolInputFile,
+            SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,
+            BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset
+            );
+
+        system (SystemCommand);
+        remove (ToolInputFile);
+        free (ToolInputFile);
+
+        Status =
+          GetFileImage (
+            ToolOutputFile,
+            &ToolOutputBuffer,
+            &ToolOutputLength
+            );
+        remove (ToolOutputFile);
+        free (ToolOutputFile);
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 0, "unable to read decoded GUIDED section", NULL);
+          return EFI_SECTION_ERROR;
+        }
+
+        Status = ParseSection (
+                  ToolOutputBuffer,
+                  ToolOutputLength
+                  );
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 0, "parse of decoded GUIDED section failed", NULL);
+          return EFI_SECTION_ERROR;
+        }
+
+      //
+      // Check for CRC32 sections which we can handle internally if needed.
+      //
+      } else if (!CompareGuid (
+                   &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid,
+                   &gEfiCrc32GuidedSectionExtractionProtocolGuid
+                   )
+          ) {
+        //
+        // CRC32 guided section
+        //
+        Status = ParseSection (
+                  SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,
+                  BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset
+                  );
+        if (EFI_ERROR (Status)) {
+          Error (NULL, 0, 0, "parse of CRC32 GUIDED section failed", NULL);
+          return EFI_SECTION_ERROR;
+        }
+      } else {
+        //
+        // We don't know how to parse it now.
+        //
+        Error (NULL, 0, 0, "EFI_SECTION_GUID_DEFINED cannot be parsed at this time.", NULL);
+        Error (NULL, 0, 0, "Tool to decode this section should have been defined", NULL);
+        Error (NULL, 0, 0, "in GuidedSectionTools.txt (built in the FV directory).", NULL);
+        return EFI_UNSUPPORTED;
+      }
+      break;
+
+    default:
+      //
+      // Unknown section, return error
+      //
+      Error (NULL, 0, 0, "unrecognized section type found", "section type = 0x%X", (UINT32) Type);
+      return EFI_SECTION_ERROR;
+    }
+
+    ParsedLength += SectionLength;
+    //
+    // We make then next section begin on a 4-byte boundary
+    //
+    ParsedLength = GetOccupiedSize (ParsedLength, 4);
+  }
+
+  if (ParsedLength < BufferLength) {
+    Error (NULL, 0, 0, "sections do not completely fill the sectioned buffer being parsed", NULL);
+    return EFI_SECTION_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DumpDepexSection (
+  IN UINT8    *Ptr,
+  IN UINT32   SectionLength
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Ptr           - GC_TODO: add argument description
+  SectionLength - GC_TODO: add argument description
+
+Returns:
+
+  EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+  UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
+
+  //
+  // Need at least a section header + data
+  //
+  if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {
+    return EFI_SUCCESS;
+  }
+
+  Ptr += sizeof (EFI_COMMON_SECTION_HEADER);
+  SectionLength -= sizeof (EFI_COMMON_SECTION_HEADER);
+  while (SectionLength > 0) {
+    printf ("        ");
+    switch (*Ptr) {
+    case EFI_DEP_BEFORE:
+      printf ("BEFORE\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_AFTER:
+      printf ("AFTER\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_PUSH:
+      printf ("PUSH\n        ");
+      PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);
+      printf ("%s  ", GuidBuffer);
+      PrintGuidName (GuidBuffer);
+      printf ("\n");
+      //
+      // PrintGuid ((EFI_GUID *)(Ptr + 1));
+      //
+      Ptr += 17;
+      SectionLength -= 17;
+      break;
+
+    case EFI_DEP_AND:
+      printf ("AND\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_OR:
+      printf ("OR\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_NOT:
+      printf ("NOT\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_TRUE:
+      printf ("TRUE\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_FALSE:
+      printf ("FALSE\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_END:
+      printf ("END DEPEX\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    case EFI_DEP_SOR:
+      printf ("SOR\n");
+      Ptr++;
+      SectionLength--;
+      break;
+
+    default:
+      printf ("Unrecognized byte in depex: 0x%X\n", (UINT32) *Ptr);
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PrintGuidName (
+  IN UINT8    *GuidStr
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  GuidStr - GC_TODO: add argument description
+
+Returns:
+
+  EFI_SUCCESS - GC_TODO: Add description for return value
+  EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
+
+--*/
+{
+  GUID_TO_BASENAME  *GPtr;
+  //
+  // If we have a list of guid-to-basenames, then go through the list to
+  // look for a guid string match. If found, print the basename to stdout,
+  // otherwise return a failure.
+  //
+  GPtr = mGuidBaseNameList;
+  while (GPtr != NULL) {
+    if (_stricmp (GuidStr, GPtr->Guid) == 0) {
+      printf (GPtr->BaseName);
+      return EFI_SUCCESS;
+    }
+
+    GPtr = GPtr->Next;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+ParseGuidBaseNameFile (
+  INT8    *FileName
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  FileName  - GC_TODO: add argument description
+
+Returns:
+
+  EFI_DEVICE_ERROR - GC_TODO: Add description for return value
+  EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
+  EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+  FILE              *Fptr;
+  INT8              Line[MAX_LINE_LEN];
+  GUID_TO_BASENAME  *GPtr;
+
+  if ((Fptr = fopen (FileName, "r")) == NULL) {
+    printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);
+    return EFI_DEVICE_ERROR;
+  }
+
+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {
+    //
+    // Allocate space for another guid/basename element
+    //
+    GPtr = malloc (sizeof (GUID_TO_BASENAME));
+    if (GPtr == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));
+    if (sscanf (Line, "%s %s", GPtr->Guid, GPtr->BaseName) == 2) {
+      GPtr->Next        = mGuidBaseNameList;
+      mGuidBaseNameList = GPtr;
+    } else {
+      //
+      // Some sort of error. Just continue.
+      //
+      free (GPtr);
+    }
+  }
+
+  fclose (Fptr);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FreeGuidBaseNameList (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+  GUID_TO_BASENAME  *Next;
+
+  while (mGuidBaseNameList != NULL) {
+    Next = mGuidBaseNameList->Next;
+    free (mGuidBaseNameList);
+    mGuidBaseNameList = Next;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+static
+VOID
+LoadGuidedSectionToolsTxt (
+  IN CHAR8* FirmwareVolumeFilename
+  )
+{
+  CHAR8* PeerFilename;
+  CHAR8* Places[] = {
+    FirmwareVolumeFilename,
+    //mUtilityFilename,
+    };
+  UINTN Index;
+
+  mParsedGuidedSectionTools = NULL;
+
+  for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {
+    PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");
+    //printf("Loading %s...\n", PeerFilename);
+    if (OsPathExists (PeerFilename)) {
+      mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);
+    }
+    free (PeerFilename);
+    if (mParsedGuidedSectionTools != NULL) {
+      return;
+    }
+  }
+}
+
+
+void
+Usage (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  //
+  // Summary usage
+  //
+  fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);
+
+  //
+  // Copyright declaration
+  // 
+  fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");
+
+  //
+  // Details Option
+  //
+  fprintf (stdout, "Options:\n");
+  //fprintf (stdout, "  -o FileName, --output FileName\n\
+  //          File will be created to store the ouput content.\n");
+  //fprintf (stdout, "  -v, --verbose\n\
+  //          Turn on verbose output with informational messages.\n");
+  //fprintf (stdout, "  --version\n\
+  //          Show program's version number and exit.\n");
+  fprintf (stdout, "  -x xref, --xref xref\n\
+            Parse basename to file-guid cross reference file(s).\n");
+  fprintf (stdout, "  --offset offset\n\
+            Offset of file to start processing FV at.\n");
+  fprintf (stdout, "  -h, --help\n\
+            Show this help message and exit.\n");
+  //fprintf (stdout, "  -q, --quiet\n\
+  //       Disable all messages except FATAL ERRORS.\n");
+  //fprintf (stdout, "  --debug [#,0-9]\n\
+  //       Enable debug messages at level #.\n");
+}
+
diff --git a/Source/C/VolInfo/VolInfo.h b/Source/C/VolInfo/VolInfo.h
new file mode 100644 (file)
index 0000000..b212766
--- /dev/null
@@ -0,0 +1,41 @@
+/*++
+
+Copyright (c) 1999 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+  VolInfo.c
+
+Abstract:
+
+  Local Definitions for the VolInfo utility
+
+--*/
+
+#ifndef _VOLINFO_H_
+#define _VOLINFO_H_ 1
+
+#define PI_SPECIFICATION_VERSION  0x00010000
+
+#define EFI_DEP_BEFORE    0x00
+#define EFI_DEP_AFTER     0x01
+#define EFI_DEP_PUSH      0x02
+#define EFI_DEP_AND       0x03
+#define EFI_DEP_OR        0x04
+#define EFI_DEP_NOT       0x05
+#define EFI_DEP_TRUE      0x06
+#define EFI_DEP_FALSE     0x07
+#define EFI_DEP_END       0x08
+#define EFI_DEP_SOR       0x09
+
+#define EFI_SECTION_LAST_LEAF_SECTION_TYPE  0x1B
+#define EFI_SECTION_LAST_SECTION_TYPE       0x1B
+
+#endif