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