summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/C/VolInfo/VolInfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/C/VolInfo/VolInfo.c')
-rw-r--r--BaseTools/Source/C/VolInfo/VolInfo.c1826
1 files changed, 1826 insertions, 0 deletions
diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c
new file mode 100644
index 0000000000..7d127e1691
--- /dev/null
+++ b/BaseTools/Source/C/VolInfo/VolInfo.c
@@ -0,0 +1,1826 @@
+/** @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");
+
+}
+