-/** @file
-
-Copyright (c) 1999 - 2010, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
- VolInfo.c
-
-Abstract:
-
- The tool dumps the contents of a firmware volume
-
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include <FvLib.h>
-#include <Common/UefiBaseTypes.h>
-#include <Common/UefiCapsule.h>
-#include <Common/PiFirmwareFile.h>
-#include <Common/PiFirmwareVolume.h>
-#include <Guid/PiFirmwareFileSystem.h>
-#include <IndustryStandard/PeImage.h>
-#include <Protocol/GuidedSectionExtraction.h>
-
-#include "Compress.h"
-#include "Decompress.h"
-#include "VolInfo.h"
-#include "CommonLib.h"
-#include "EfiUtilityMsgs.h"
-#include "FirmwareVolumeBufferLib.h"
-#include "OsPath.h"
-#include "ParseGuidedSectionTools.h"
-#include "StringFuncs.h"
-
-//
-// Utility global variables
-//
-
-EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
-
-#define UTILITY_MAJOR_VERSION 0
-#define UTILITY_MINOR_VERSION 82
-
-#define UTILITY_NAME "VolInfo"
-
-#define EFI_SECTION_ERROR EFIERR (100)
-
-#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable
-
-//
-// Structure to keep a list of guid-to-basenames
-//
-typedef struct _GUID_TO_BASENAME {
- struct _GUID_TO_BASENAME *Next;
- INT8 Guid[PRINTED_GUID_BUFFER_SIZE];
- INT8 BaseName[MAX_BASENAME_LEN];
-} GUID_TO_BASENAME;
-
-static GUID_TO_BASENAME *mGuidBaseNameList = NULL;
-
-//
-// Store GUIDed Section guid->tool mapping
-//
-EFI_HANDLE mParsedGuidedSectionTools = NULL;
-
-CHAR8* mUtilityFilename = NULL;
-
-EFI_STATUS
-ParseGuidBaseNameFile (
- 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
- );
-
-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\n",
- UTILITY_NAME,
- UTILITY_MAJOR_VERSION,
- UTILITY_MINOR_VERSION,
- __DATE__
- );
-
- //
- // Save, and then skip filename arg
- //
- mUtilityFilename = argv[0];
- argc--;
- argv++;
-
- Offset = 0;
-
- //
- // If they specified -x xref guid/basename cross-reference files, process it.
- // This will print the basename beside each file guid. To use it, specify
- // -x xref_filename to processdsc, then use xref_filename as a parameter
- // here.
- //
- while (argc > 2) {
- if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {
- ParseGuidBaseNameFile (argv[1]);
- printf("ParseGuidBaseNameFile: %s\n", argv[1]);
- argc -= 2;
- argv += 2;
- } else if (strcmp(argv[0], "--offset") == 0) {
- //
- // Hex or decimal?
- //
- if ((argv[1][0] == '0') && (tolower ((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);
-
- //
- // Clean up
- //
- free (FvImage);
- FreeGuidBaseNameList ();
- return GetUtilityStatus ();
-}
-
-
-static
-EFI_STATUS
-PrintFvInfo (
- IN VOID *Fv
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- Fv - Firmware Volume to print information about
-
-Returns:
-
- EFI_STATUS
-
---*/
-{
- EFI_STATUS Status;
- UINTN NumberOfFiles;
- BOOLEAN ErasePolarity;
- UINTN FvSize;
- EFI_FFS_FILE_HEADER *CurrentFile;
- UINTN Key;
-
- Status = FvBufGetSize (Fv, &FvSize);
-
- NumberOfFiles = 0;
- ErasePolarity =
- (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?
- TRUE : FALSE;
-
- //
- // Get the first file
- //
- Key = 0;
- Status = FvBufFindNextFile (Fv, &Key, (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 ();
- }
- }
-
- 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_ALIGNMNET_512K) {
- printf (" EFI_FVB2_ALIGNMNET_512K\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {
- printf (" EFI_FVB2_ALIGNMENT_1M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {
- printf (" EFI_FVB2_ALIGNMENT_2M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {
- printf (" EFI_FVB2_ALIGNMENT_4M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {
- printf (" EFI_FVB2_ALIGNMENT_8M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {
- printf (" EFI_FVB2_ALIGNMENT_16M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {
- printf (" EFI_FVB2_ALIGNMENT_32M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
- printf (" EFI_FVB2_ALIGNMENT_64M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
- printf (" EFI_FVB2_ALIGNMENT_128M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
- printf (" EFI_FVB2_ALIGNMENT_64M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
- printf (" EFI_FVB2_ALIGNMENT_128M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {
- printf (" EFI_FVB2_ALIGNMENT_256M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {
- printf (" EFI_FVB2_ALIGNMENT_512M\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {
- printf (" EFI_FVB2_ALIGNMENT_1G\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {
- printf (" EFI_FVB2_ALIGNMENT_2G\n");
- }
-
-#endif
- printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);
- printf ("File System ID: ");
- PrintGuid (&VolumeHeader.FileSystemGuid);
- //
- // printf ("\n");
- //
- printf ("Revision: 0x%04X\n", VolumeHeader.Revision);
-
- do {
- fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
- BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
-
- if (BlockMap.NumBlocks != 0) {
- printf ("Number of Blocks: 0x%08X\n", (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);
- 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
+The tool dumps the contents of a firmware volume\r
+\r
+Copyright (c) 1999 - 2017, 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
+**/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <assert.h>\r
+#ifdef __GNUC__\r
+#include <unistd.h>\r
+#else\r
+#include <direct.h>\r
+#endif\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
+#include "ParseInf.h"\r
+#include "PeCoffLib.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 1\r
+#define UTILITY_MINOR_VERSION 0\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
+BOOLEAN EnableHash = FALSE;\r
+CHAR8 *OpenSslPath = 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
+EFI_STATUS\r
+CombinePath (\r
+ IN CHAR8* DefaultPath,\r
+ IN CHAR8* AppendPath,\r
+ OUT CHAR8* NewPath\r
+);\r
+\r
+void\r
+Usage (\r
+ VOID\r
+ );\r
+\r
+UINT32\r
+UnicodeStrLen (\r
+ IN CHAR16 *String\r
+ )\r
+ /*++\r
+\r
+ Routine Description:\r
+\r
+ Returns the length of a null-terminated unicode string.\r
+\r
+ Arguments:\r
+\r
+ String - The pointer to a null-terminated unicode string.\r
+\r
+ Returns:\r
+\r
+ N/A\r
+\r
+ --*/\r
+{\r
+ UINT32 Length;\r
+\r
+ for (Length = 0; *String != L'\0'; String++, Length++) {\r
+ ;\r
+ }\r
+ return Length;\r
+}\r
+\r
+VOID\r
+Unicode2AsciiString (\r
+ IN CHAR16 *Source,\r
+ OUT CHAR8 *Destination\r
+ )\r
+ /*++\r
+\r
+ Routine Description:\r
+\r
+ Convert a null-terminated unicode string to a null-terminated ascii string.\r
+\r
+ Arguments:\r
+\r
+ Source - The pointer to the null-terminated input unicode string.\r
+ Destination - The pointer to the null-terminated output ascii string.\r
+\r
+ Returns:\r
+\r
+ N/A\r
+\r
+ --*/\r
+{\r
+ while (*Source != '\0') {\r
+ *(Destination++) = (CHAR8) *(Source++);\r
+ }\r
+ //\r
+ // End the ascii with a NULL.\r
+ //\r
+ *Destination = '\0';\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
+ UINT64 LogLevel;\r
+ CHAR8 *OpenSslEnv;\r
+ CHAR8 *OpenSslCommand;\r
+\r
+ SetUtilityName (UTILITY_NAME);\r
+ //\r
+ // Print utility header\r
+ //\r
+ printf ("%s Version %d.%d Build %s\n",\r
+ UTILITY_NAME,\r
+ UTILITY_MAJOR_VERSION,\r
+ UTILITY_MINOR_VERSION,\r
+ __BUILD_VERSION\r
+ );\r
+\r
+ if (argc == 1) {\r
+ Usage ();\r
+ return -1;\r
+ }\r
+\r
+ argc--;\r
+ argv++;\r
+ LogLevel = 0;\r
+ Offset = 0;\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_SUCCESS;\r
+ }\r
+ //\r
+ // Version has already be printed, so just return success\r
+ //\r
+ if (strcmp(argv[0], "--version") == 0) {\r
+ return STATUS_SUCCESS;\r
+ }\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 > 0) {\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
+ continue;\r
+ }\r
+ 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
+ continue;\r
+ }\r
+ if ((stricmp (argv[0], "--hash") == 0)) {\r
+ if (EnableHash == TRUE) {\r
+ //\r
+ // --hash already given in the option, ignore this one\r
+ //\r
+ argc --;\r
+ argv ++;\r
+ continue;\r
+ }\r
+ EnableHash = TRUE;\r
+ OpenSslCommand = "openssl";\r
+ OpenSslEnv = getenv("OPENSSL_PATH");\r
+ if (OpenSslEnv == NULL) {\r
+ OpenSslPath = OpenSslCommand;\r
+ } else {\r
+ OpenSslPath = malloc(strlen(OpenSslEnv)+strlen(OpenSslCommand)+1);\r
+ if (OpenSslPath == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return GetUtilityStatus ();\r
+ }\r
+ CombinePath(OpenSslEnv, OpenSslCommand, OpenSslPath);\r
+ }\r
+ if (OpenSslPath == NULL){\r
+ Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
+ return GetUtilityStatus ();\r
+ }\r
+ argc --;\r
+ argv ++;\r
+ continue;\r
+ }\r
+\r
+ if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
+ SetPrintLevel (VERBOSE_LOG_LEVEL);\r
+ argc --;\r
+ argv ++;\r
+ continue;\r
+ }\r
+\r
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
+ SetPrintLevel (KEY_LOG_LEVEL);\r
+ argc --;\r
+ argv ++;\r
+ continue;\r
+ }\r
+\r
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
+ Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+ return -1;\r
+ }\r
+ if (LogLevel > 9) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
+ return -1;\r
+ }\r
+ SetPrintLevel (LogLevel);\r
+ DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
+ argc -= 2;\r
+ argv += 2;\r
+ continue;\r
+ }\r
+\r
+ mUtilityFilename = argv[0];\r
+ argc --;\r
+ argv ++;\r
+ }\r
+\r
+ //\r
+ // Open the file containing the FV\r
+ //\r
+ if (mUtilityFilename == NULL) {\r
+ Error (NULL, 0, 1001, "Missing option", "Input files are not specified");\r
+ return GetUtilityStatus ();\r
+ }\r
+ InputFile = fopen (LongFilePath (mUtilityFilename), "rb");\r
+ if (InputFile == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename);\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", mUtilityFilename);\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", mUtilityFilename);\r
+ free (FvImage);\r
+ return GetUtilityStatus ();\r
+ }\r
+\r
+ LoadGuidedSectionToolsTxt (mUtilityFilename);\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_HEADER2 BlankHeader;\r
+ EFI_STATUS Status;\r
+ UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
+ UINT32 HeaderSize;\r
+#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
+ UINT16 *Tail;\r
+#endif\r
+ //\r
+ // Check if we have free space\r
+ //\r
+ HeaderSize = FvBufGetFfsHeaderSize(FileHeader);\r
+ if (ErasePolarity) {\r
+ memset (&BlankHeader, -1, HeaderSize);\r
+ } else {\r
+ memset (&BlankHeader, 0, HeaderSize);\r
+ }\r
+\r
+ if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 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 = FvBufGetFfsFileSize (FileHeader);\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, HeaderSize);\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, HeaderSize);\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 = FvBufGetFfsFileSize (FileHeader);\r
+\r
+ if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
+ //\r
+ // Calculate file checksum\r
+ //\r
+ Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);\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 + HeaderSize),\r
+ FvBufGetFfsFileSize (FileHeader) - HeaderSize\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
+RebaseImageRead (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINT32 *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+Arguments:\r
+\r
+ FileHandle - The handle to the PE/COFF file\r
+\r
+ FileOffset - The offset, in bytes, into the file to read\r
+\r
+ ReadSize - The number of bytes to read from the file starting at FileOffset\r
+\r
+ Buffer - A pointer to the buffer to read the data into.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+--*/\r
+{\r
+ CHAR8 *Destination8;\r
+ CHAR8 *Source8;\r
+ UINT32 Length;\r
+\r
+ Destination8 = Buffer;\r
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+ Length = *ReadSize;\r
+ while (Length--) {\r
+ *(Destination8++) = *(Source8++);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+SetAddressToSectionHeader (\r
+ IN CHAR8 *FileName,\r
+ IN OUT UINT8 *FileBuffer,\r
+ IN UINT64 NewPe32BaseAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set new base address into the section header of PeImage\r
+\r
+Arguments:\r
+\r
+ FileName - Name of file\r
+ FileBuffer - Pointer to PeImage.\r
+ NewPe32BaseAddress - New Base Address for PE image.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Set new base address into this image successfully.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ UINTN Index;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
+\r
+ //\r
+ // Initialize context\r
+ //\r
+ memset (&ImageContext, 0, sizeof (ImageContext));\r
+ ImageContext.Handle = (VOID *) FileBuffer;\r
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
+ return Status;\r
+ }\r
+\r
+ if (ImageContext.RelocationsStripped) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get PeHeader pointer\r
+ //\r
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
+\r
+ //\r
+ // Get section header list\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+ (UINTN) ImgHdr +\r
+ sizeof (UINT32) +\r
+ sizeof (EFI_IMAGE_FILE_HEADER) +\r
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
+ );\r
+\r
+ //\r
+ // Set base address into the first section header that doesn't point to code section.\r
+ //\r
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
+ *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // BaseAddress is set to section header.\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RebaseImage (\r
+ IN CHAR8 *FileName,\r
+ IN OUT UINT8 *FileBuffer,\r
+ IN UINT64 NewPe32BaseAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set new base address into PeImage, and fix up PeImage based on new address.\r
+\r
+Arguments:\r
+\r
+ FileName - Name of file\r
+ FileBuffer - Pointer to PeImage.\r
+ NewPe32BaseAddress - New Base Address for PE image.\r
+\r
+Returns:\r
+\r
+ EFI_INVALID_PARAMETER - BaseAddress is not valid.\r
+ EFI_SUCCESS - Update PeImage is correctly.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ UINTN Index;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
+ UINT8 *MemoryImagePointer;\r
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
+\r
+ //\r
+ // Initialize context\r
+ //\r
+ memset (&ImageContext, 0, sizeof (ImageContext));\r
+ ImageContext.Handle = (VOID *) FileBuffer;\r
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
+ return Status;\r
+ }\r
+\r
+ if (ImageContext.RelocationsStripped) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get PeHeader pointer\r
+ //\r
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
+\r
+ //\r
+ // Load and Relocate Image Data\r
+ //\r
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ if (MemoryImagePointer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
+\r
+ Status = PeCoffLoaderLoadImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
+ free ((VOID *) MemoryImagePointer);\r
+ return Status;\r
+ }\r
+\r
+ ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+ Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
+ free ((VOID *) MemoryImagePointer);\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Copy Relocated data to raw image file.\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+ (UINTN) ImgHdr +\r
+ sizeof (UINT32) +\r
+ sizeof (EFI_IMAGE_FILE_HEADER) +\r
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
+ );\r
+\r
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ CopyMem (\r
+ FileBuffer + SectionHeader->PointerToRawData,\r
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),\r
+ SectionHeader->SizeOfRawData\r
+ );\r
+ }\r
+\r
+ free ((VOID *) MemoryImagePointer);\r
+\r
+ //\r
+ // Update Image Base Address\r
+ //\r
+ if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
+ } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
+ } else {\r
+ Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
+ ImgHdr->Pe32.OptionalHeader.Magic,\r
+ FileName\r
+ );\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ //\r
+ // Set new base address into section header\r
+ //\r
+ Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CombinePath (\r
+ IN CHAR8* DefaultPath,\r
+ IN CHAR8* AppendPath,\r
+ OUT CHAR8* NewPath\r
+)\r
+{\r
+ UINT32 DefaultPathLen;\r
+ DefaultPathLen = strlen(DefaultPath);\r
+ strcpy(NewPath, DefaultPath);\r
+ UINT64 Index = 0;\r
+ for (; Index < DefaultPathLen; Index ++) {\r
+ if (NewPath[Index] == '\\' || NewPath[Index] == '/') {\r
+ if (NewPath[Index + 1] != '\0') {\r
+ NewPath[Index] = '/';\r
+ }\r
+ }\r
+ }\r
+ if (NewPath[Index -1] != '/') {\r
+ NewPath[Index] = '/';\r
+ NewPath[Index + 1] = '\0';\r
+ }\r
+ strcat(NewPath, AppendPath);\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
+ UINT32 SectionHeaderLen;\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 *SystemCommand;\r
+ EFI_GUID *EfiGuid;\r
+ UINT16 DataOffset;\r
+ UINT16 Attributes;\r
+ UINT32 RealHdrLen;\r
+ CHAR8 *ToolInputFileName;\r
+ CHAR8 *ToolOutputFileName;\r
+ CHAR8 *UIFileName;\r
+\r
+ ParsedLength = 0;\r
+ ToolInputFileName = NULL;\r
+ ToolOutputFileName = NULL;\r
+\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
+ //\r
+ // Get real section file size\r
+ //\r
+ SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);\r
+ SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
+\r
+ SectionName = SectionNameToStr (Type);\r
+ if (SectionName != NULL) {\r
+ printf ("------------------------------------------------------------\n");\r
+ printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);\r
+ free (SectionName);\r
+ }\r
+\r
+ switch (Type) {\r
+ case EFI_SECTION_RAW:\r
+ case EFI_SECTION_PIC:\r
+ case EFI_SECTION_TE:\r
+ // default is no more information\r
+ break;\r
+\r
+ case EFI_SECTION_PE32:\r
+ if (EnableHash) {\r
+ ToolInputFileName = "edk2Temp_InputEfi.tmp";\r
+ ToolOutputFileName = "edk2Temp_OutputHash.tmp";\r
+ RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);\r
+ PutFileImage (\r
+ ToolInputFileName,\r
+ (CHAR8*)Ptr + SectionHeaderLen,\r
+ SectionLength - SectionHeaderLen\r
+ );\r
+\r
+ SystemCommand = malloc (\r
+ strlen (OPENSSL_COMMAND_FORMAT_STRING) +\r
+ strlen (OpenSslPath) +\r
+ strlen (ToolInputFileName) +\r
+ strlen (ToolOutputFileName) +\r
+ 1\r
+ );\r
+ if (SystemCommand == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ sprintf (\r
+ SystemCommand,\r
+ OPENSSL_COMMAND_FORMAT_STRING,\r
+ OpenSslPath,\r
+ ToolOutputFileName,\r
+ ToolInputFileName\r
+ );\r
+\r
+ if (system (SystemCommand) != EFI_SUCCESS) {\r
+ Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
+ }\r
+ else {\r
+ FILE *fp;\r
+ CHAR8 *StrLine;\r
+ CHAR8 *NewStr;\r
+ UINT32 nFileLen;\r
+ if((fp = fopen(ToolOutputFileName,"r")) == NULL) {\r
+ Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);\r
+ }\r
+ else {\r
+ fseek(fp,0,SEEK_SET);\r
+ fseek(fp,0,SEEK_END);\r
+ nFileLen = ftell(fp);\r
+ fseek(fp,0,SEEK_SET);\r
+ StrLine = malloc(nFileLen);\r
+ if (StrLine == NULL) {\r
+ fclose(fp);\r
+ free (SystemCommand);\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ fgets(StrLine, nFileLen, fp);\r
+ NewStr = strrchr (StrLine, '=');\r
+ printf (" SHA1: %s\n", NewStr + 1);\r
+ free (StrLine);\r
+ fclose(fp);\r
+ }\r
+ }\r
+ remove(ToolInputFileName);\r
+ remove(ToolOutputFileName);\r
+ free (SystemCommand);\r
+ }\r
+ break;\r
+\r
+ case EFI_SECTION_USER_INTERFACE:\r
+ UIFileName = (CHAR8 *) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString) + 1);\r
+ if (UIFileName == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UIFileName);\r
+ printf (" String: %s\n", UIFileName);\r
+ free (UIFileName);\r
+ break;\r
+\r
+ case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
+ Status = PrintFvInfo (Ptr + SectionHeaderLen, 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", *(UINT16 *)(Ptr + SectionHeaderLen));\r
+ printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));\r
+ break;\r
+\r
+ case EFI_SECTION_COMPRESSION:\r
+ UncompressedBuffer = NULL;\r
+ if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {\r
+ RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);\r
+ UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;\r
+ CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;\r
+ } else {\r
+ RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);\r
+ UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;\r
+ CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;\r
+ }\r
+ CompressedLength = SectionLength - RealHdrLen;\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 + RealHdrLen;\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 + RealHdrLen;\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
+ if (ScratchBuffer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ UncompressedBuffer = malloc (UncompressedLength);\r
+ if (UncompressedBuffer == NULL) {\r
+ free (ScratchBuffer);\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\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
+ if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {\r
+ EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;\r
+ DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;\r
+ Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;\r
+ } else {\r
+ EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;\r
+ DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;\r
+ Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;\r
+ }\r
+ printf (" SectionDefinitionGuid: ");\r
+ PrintGuid (EfiGuid);\r
+ printf ("\n");\r
+ printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);\r
+ printf (" Attributes: 0x%04X\n", (unsigned) Attributes);\r
+\r
+ ExtractionTool =\r
+ LookupGuidedSectionToolPath (\r
+ mParsedGuidedSectionTools,\r
+ EfiGuid\r
+ );\r
+\r
+ if (ExtractionTool != NULL) {\r
+ #ifndef __GNUC__\r
+ ToolInputFile = CloneString (tmpnam (NULL));\r
+ ToolOutputFile = CloneString (tmpnam (NULL));\r
+ #else\r
+ char tmp1[] = "/tmp/fileXXXXXX";\r
+ char tmp2[] = "/tmp/fileXXXXXX";\r
+ int fd1;\r
+ int fd2;\r
+ fd1 = mkstemp(tmp1);\r
+ fd2 = mkstemp(tmp2);\r
+ ToolInputFile = CloneString(tmp1);\r
+ ToolOutputFile = CloneString(tmp2);\r
+ close(fd1);\r
+ close(fd2);\r
+ #endif\r
+\r
+ if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) {\r
+ if (ToolInputFile != NULL) {\r
+ free (ToolInputFile);\r
+ }\r
+ if (ToolOutputFile != NULL) {\r
+ free (ToolOutputFile);\r
+ }\r
+ free (ExtractionTool);\r
+\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Construction 'system' command string\r
+ //\r
+ SystemCommand = malloc (\r
+ strlen (EXTRACT_COMMAND_FORMAT_STRING) +\r
+ strlen (ExtractionTool) +\r
+ strlen (ToolInputFile) +\r
+ strlen (ToolOutputFile) +\r
+ 1\r
+ );\r
+ if (SystemCommand == NULL) {\r
+ free (ToolInputFile);\r
+ free (ToolOutputFile);\r
+ free (ExtractionTool);\r
+\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ sprintf (\r
+ SystemCommand,\r
+ EXTRACT_COMMAND_FORMAT_STRING,\r
+ ExtractionTool,\r
+ ToolOutputFile,\r
+ ToolInputFile\r
+ );\r
+ free (ExtractionTool);\r
+\r
+ Status =\r
+ PutFileImage (\r
+ ToolInputFile,\r
+ (CHAR8*) SectionBuffer + DataOffset,\r
+ BufferLength - 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
+ free (SystemCommand);\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
+ EfiGuid,\r
+ &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
+ )\r
+ ) {\r
+ //\r
+ // CRC32 guided section\r
+ //\r
+ Status = ParseSection (\r
+ SectionBuffer + DataOffset,\r
+ BufferLength - 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 += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
+ SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\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
+ CHAR8 FormatString[MAX_LINE_LEN];\r
+ GUID_TO_BASENAME *GPtr;\r
+\r
+ if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {\r
+ printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Generate the format string for fscanf\r
+ //\r
+ sprintf (\r
+ FormatString,\r
+ "%%%us %%%us",\r
+ (unsigned) sizeof (GPtr->Guid) - 1,\r
+ (unsigned) sizeof (GPtr->BaseName) - 1\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
+ fclose (Fptr);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));\r
+ if (sscanf (Line, FormatString, 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 - 2016, Intel Corporation. All rights reserved.\n\n");\r
+ fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");\r
+\r
+ //\r
+ // Details Option\r
+ //\r
+ fprintf (stdout, "optional arguments:\n");\r
+ fprintf (stdout, " -h, --help\n\\r
+ Show this help message and exit\n");\r
+ fprintf (stdout, " --version\n\\r
+ Show program's version number and exit\n");\r
+ fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\\r
+ Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");\r
+ fprintf (stdout, " -v, --verbose\n\\r
+ Print informational statements\n");\r
+ fprintf (stdout, " -q, --quiet\n\\r
+ Returns the exit code, error messages will be displayed\n");\r
+ fprintf (stdout, " -s, --silent\n\\r
+ Returns only the exit code; informational and error\n\\r
+ messages are not displayed\n");\r
+ fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\\r
+ Parse the basename to file-guid cross reference file(s)\n");\r
+ fprintf (stdout, " -f OFFSET, --offset OFFSET\n\\r
+ The offset from the start of the input file to start \n\\r
+ processing an FV\n");\r
+ fprintf (stdout, " --hash\n\\r
+ Generate HASH value of the entire PE image\n");\r
+ fprintf (stdout, " --sfo\n\\r
+ Reserved for future use\n");\r
+}\r
+\r