/** @file
This file contains functions required to generate a Firmware File System file.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef __GNUC__
#define RUNTIME_FUNCTION  _WINNT_DUP_RUNTIME_FUNCTION
#include <windows.h>
#undef RUNTIME_FUNCTION
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif

#ifdef __GNUC__
#include <unistd.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <Common/UefiBaseTypes.h>
#include <Common/PiFirmwareFile.h>
#include <IndustryStandard/PeImage.h>
#include <Guid/FfsSectionAlignmentPadding.h>

#include "CommonLib.h"
#include "ParseInf.h"
#include "EfiUtilityMsgs.h"
#include "FvLib.h"
#include "PeCoffLib.h"

#define UTILITY_NAME            "GenFfs"
#define UTILITY_MAJOR_VERSION   0
#define UTILITY_MINOR_VERSION   1

STATIC CHAR8 *mFfsFileType[] = {
  NULL,                                   // 0x00
  "EFI_FV_FILETYPE_RAW",                  // 0x01
  "EFI_FV_FILETYPE_FREEFORM",             // 0x02
  "EFI_FV_FILETYPE_SECURITY_CORE",        // 0x03
  "EFI_FV_FILETYPE_PEI_CORE",             // 0x04
  "EFI_FV_FILETYPE_DXE_CORE",             // 0x05
  "EFI_FV_FILETYPE_PEIM",                 // 0x06
  "EFI_FV_FILETYPE_DRIVER",               // 0x07
  "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER", // 0x08
  "EFI_FV_FILETYPE_APPLICATION",          // 0x09
  "EFI_FV_FILETYPE_SMM",                  // 0x0A
  "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE",// 0x0B
  "EFI_FV_FILETYPE_COMBINED_SMM_DXE",     // 0x0C
  "EFI_FV_FILETYPE_SMM_CORE",             // 0x0D
  "EFI_FV_FILETYPE_MM_STANDALONE",        // 0x0E
  "EFI_FV_FILETYPE_MM_CORE_STANDALONE"    // 0x0F
};

STATIC CHAR8 *mAlignName[] = {
  "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
  "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",
  "512K", "1M", "2M", "4M", "8M", "16M"
 };

STATIC CHAR8 *mFfsValidAlignName[] = {
  "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K","256K",
  "512K", "1M", "2M", "4M", "8M", "16M"
 };

STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536, 131072, 262144,
                                  524288, 1048576, 2097152, 4194304, 8388608, 16777216};

STATIC EFI_GUID mZeroGuid = {0};

STATIC EFI_GUID mEfiFfsSectionAlignmentPaddingGuid = EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID;

STATIC
VOID
Version (
  VOID
  )
/*++

Routine Description:

  Print out version information for this utility.

Arguments:

  None

Returns:

  None

--*/
{
  fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
}

STATIC
VOID
Usage (
  VOID
  )
/*++

Routine Description:

  Print Error / Help message.

Arguments:

  VOID

Returns:

  None

--*/
{
  //
  // Summary usage
  //
  fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);

  //
  // Copyright declaration
  //
  fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");

  //
  // Details Option
  //
  fprintf (stdout, "Options:\n");
  fprintf (stdout, "  -o FileName, --outputfile FileName\n\
                        File is FFS file to be created.\n");
  fprintf (stdout, "  -t Type, --filetype Type\n\
                        Type is one FV file type defined in PI spec, which is\n\
                        EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FREEFORM,\n\
                        EFI_FV_FILETYPE_SECURITY_CORE, EFI_FV_FILETYPE_PEIM,\n\
                        EFI_FV_FILETYPE_PEI_CORE, EFI_FV_FILETYPE_DXE_CORE,\n\
                        EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION,\n\
                        EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\n\
                        EFI_FV_FILETYPE_SMM, EFI_FV_FILETYPE_SMM_CORE,\n\
                        EFI_FV_FILETYPE_MM_STANDALONE,\n\
                        EFI_FV_FILETYPE_MM_CORE_STANDALONE,\n\
                        EFI_FV_FILETYPE_COMBINED_SMM_DXE, \n\
                        EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE.\n");
  fprintf (stdout, "  -g FileGuid, --fileguid FileGuid\n\
                        FileGuid is one module guid.\n\
                        Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
  fprintf (stdout, "  -x, --fixed           Indicates that the file may not be moved\n\
                        from its present location.\n");
  fprintf (stdout, "  -s, --checksum        Indicates to calculate file checksum.\n");
  fprintf (stdout, "  -a FileAlign, --align FileAlign\n\
                        FileAlign points to file alignment, which only support\n\
                        the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n\
                        128K,256K,512K,1M,2M,4M,8M,16M\n");
  fprintf (stdout, "  -i SectionFile, --sectionfile SectionFile\n\
                        Section file will be contained in this FFS file.\n");
  fprintf (stdout, "  -oi SectionFile, --optionalsectionfile SectionFile\n\
                        If the Section file exists, it will be contained in this FFS file, otherwise, it will be ignored.\n");
  fprintf (stdout, "  -n SectionAlign, --sectionalign SectionAlign\n\
                        SectionAlign points to section alignment, which support\n\
                        the alignment scope 0~16M. If SectionAlign is specified\n\
                        as 0, tool get alignment value from SectionFile. It is\n\
                        specified together with sectionfile to point its\n\
                        alignment in FFS file.\n");
  fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");
  fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");
  fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");
  fprintf (stdout, "  --version             Show program's version number and exit.\n");
  fprintf (stdout, "  -h, --help            Show this help message and exit.\n");
}

STATIC
EFI_STATUS
StringtoAlignment (
  IN  CHAR8  *AlignBuffer,
  OUT UINT32 *AlignNumber
  )
/*++

Routine Description:

  Converts Align String to align value (1~16M).

Arguments:

  AlignBuffer    - Pointer to Align string.
  AlignNumber    - Pointer to Align value.

Returns:

  EFI_SUCCESS             Successfully convert align string to align value.
  EFI_INVALID_PARAMETER   Align string is invalid or align value is not in scope.

--*/
{
  UINT32 Index = 0;
  //
  // Check AlignBuffer
  //
  if (AlignBuffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  for (Index = 0; Index < sizeof (mAlignName) / sizeof (CHAR8 *); Index ++) {
    if (stricmp (AlignBuffer, mAlignName [Index]) == 0) {
      *AlignNumber = 1 << Index;
      return EFI_SUCCESS;
    }
  }
  return EFI_INVALID_PARAMETER;
}

STATIC
UINT8
StringToType (
  IN CHAR8 *String
  )
/*++

Routine Description:

  Converts File Type String to value.  EFI_FV_FILETYPE_ALL indicates that an
  unrecognized file type was specified.

Arguments:

  String    - File type string

Returns:

  File Type Value

--*/
{
  UINT8 Index = 0;

  if (String == NULL) {
    return EFI_FV_FILETYPE_ALL;
  }

  for (Index = 0; Index < sizeof (mFfsFileType) / sizeof (CHAR8 *); Index ++) {
    if (mFfsFileType [Index] != NULL && (stricmp (String, mFfsFileType [Index]) == 0)) {
      return Index;
    }
  }
  return EFI_FV_FILETYPE_ALL;
}

STATIC
EFI_STATUS
GetSectionContents (
  IN  CHAR8                     **InputFileName,
  IN  UINT32                    *InputFileAlign,
  IN  UINT32                    InputFileNum,
  IN  EFI_FFS_FILE_ATTRIBUTES   FfsAttrib,
  OUT UINT8                     *FileBuffer,
  OUT UINT32                    *BufferLength,
  OUT UINT32                    *MaxAlignment,
  OUT UINT8                     *PESectionNum
  )
/*++

Routine Description:

  Get the contents of all section files specified in InputFileName
  into FileBuffer.

Arguments:

  InputFileName  - Name of the input file.

  InputFileAlign - Alignment required by the input file data.

  InputFileNum   - Number of input files. Should be at least 1.

  FileBuffer     - Output buffer to contain data

  BufferLength   - On input, this is size of the FileBuffer.
                   On output, this is the actual length of the data.

  MaxAlignment   - The max alignment required by all the input file datas.

  PeSectionNum   - Calculate the number of Pe/Te Section in this FFS file.

Returns:

  EFI_SUCCESS on successful return
  EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
  EFI_ABORTED if unable to open input file.
  EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
--*/
{
  UINT32                              Size;
  UINT32                              Offset;
  UINT32                              FileSize;
  UINT32                              Index;
  FILE                                *InFile;
  EFI_FREEFORM_SUBTYPE_GUID_SECTION   *SectHeader;
  EFI_COMMON_SECTION_HEADER2          TempSectHeader;
  EFI_TE_IMAGE_HEADER                 TeHeader;
  UINT32                              TeOffset;
  EFI_GUID_DEFINED_SECTION            GuidSectHeader;
  EFI_GUID_DEFINED_SECTION2           GuidSectHeader2;
  UINT32                              HeaderSize;
  UINT32                              MaxEncounteredAlignment;

  Size                    = 0;
  Offset                  = 0;
  TeOffset                = 0;
  MaxEncounteredAlignment = 1;

  //
  // Go through our array of file names and copy their contents
  // to the output buffer.
  //
  for (Index = 0; Index < InputFileNum; Index++) {
    //
    // make sure section ends on a DWORD boundary
    //
    while ((Size & 0x03) != 0) {
      Size++;
    }

    //
    // Open file and read contents
    //
    InFile = fopen (LongFilePath (InputFileName[Index]), "rb");
    if (InFile == NULL) {
      Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);
      return EFI_ABORTED;
    }

    fseek (InFile, 0, SEEK_END);
    FileSize = ftell (InFile);
    fseek (InFile, 0, SEEK_SET);
    DebugMsg (NULL, 0, 9, "Input section files",
              "the input section name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize);

    //
    // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
    //
    TeOffset = 0;
    if (FileSize >= MAX_FFS_SIZE) {
      HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
    } else {
      HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
    }
    fread (&TempSectHeader, 1, HeaderSize, InFile);
    if (TempSectHeader.Type == EFI_SECTION_TE) {
      (*PESectionNum) ++;
      fread (&TeHeader, 1, sizeof (TeHeader), InFile);
      if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
        TeOffset = TeHeader.StrippedSize - sizeof (TeHeader);
      }
    } else if (TempSectHeader.Type == EFI_SECTION_PE32) {
      (*PESectionNum) ++;
    } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {
      fseek (InFile, 0, SEEK_SET);
      if (FileSize >= MAX_SECTION_SIZE) {
        fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);
        if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
          HeaderSize = GuidSectHeader2.DataOffset;
        }
      } else {
        fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
        if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
          HeaderSize = GuidSectHeader.DataOffset;
        }
      }
      (*PESectionNum) ++;
    } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION ||
               TempSectHeader.Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
      //
      // for the encapsulated section, assume it contains Pe/Te section
      //
      (*PESectionNum) ++;
    }

    fseek (InFile, 0, SEEK_SET);

    //
    // Revert TeOffset to the converse value relative to Alignment
    // This is to assure the original PeImage Header at Alignment.
    //
    if ((TeOffset != 0) && (InputFileAlign [Index] != 0)) {
      TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);
      TeOffset = TeOffset % InputFileAlign [Index];
    }

    //
    // make sure section data meet its alignment requirement by adding one pad section.
    // But the different sections have the different section header. Necessary or not?
    // Based on section type to adjust offset? Todo
    //
    if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {
      Offset = (Size + (UINT32)sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);
      Offset = Offset - Size - HeaderSize - TeOffset;

      if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {
        //
        // The maximal alignment is 64K, the raw section size must be less than 0xffffff
        //
        memset (FileBuffer + Size, 0, Offset);
        SectHeader                        = (EFI_FREEFORM_SUBTYPE_GUID_SECTION *) (FileBuffer + Size);
        SectHeader->CommonHeader.Size[0]  = (UINT8) (Offset & 0xff);
        SectHeader->CommonHeader.Size[1]  = (UINT8) ((Offset & 0xff00) >> 8);
        SectHeader->CommonHeader.Size[2]  = (UINT8) ((Offset & 0xff0000) >> 16);

        //
        // Only add a special reducible padding section if
        // - this FFS has the FFS_ATTRIB_FIXED attribute,
        // - none of the preceding sections have alignment requirements,
        // - the size of the padding is sufficient for the
        //   EFI_SECTION_FREEFORM_SUBTYPE_GUID header.
        //
        if ((FfsAttrib & FFS_ATTRIB_FIXED) != 0 &&
            MaxEncounteredAlignment <= 1 &&
            Offset >= sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION)) {
          SectHeader->CommonHeader.Type   = EFI_SECTION_FREEFORM_SUBTYPE_GUID;
          SectHeader->SubTypeGuid         = mEfiFfsSectionAlignmentPaddingGuid;
        } else {
          SectHeader->CommonHeader.Type   = EFI_SECTION_RAW;
        }
      }
      DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment",
                "Pad Raw section size is %u", (unsigned) Offset);

      Size = Size + Offset;
    }

    //
    // Get the Max alignment of all input file datas
    //
    if (MaxEncounteredAlignment < InputFileAlign [Index]) {
      MaxEncounteredAlignment = InputFileAlign [Index];
    }

    //
    // Now read the contents of the file into the buffer
    // Buffer must be enough to contain the file content.
    //
    if ((FileSize > 0) && (FileBuffer != NULL) && ((Size + FileSize) <= *BufferLength)) {
      if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {
        Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);
        fclose (InFile);
        return EFI_ABORTED;
      }
    }

    fclose (InFile);
    Size += FileSize;
  }

  *MaxAlignment = MaxEncounteredAlignment;

  //
  // Set the actual length of the data.
  //
  if (Size > *BufferLength) {
    *BufferLength = Size;
    return EFI_BUFFER_TOO_SMALL;
  } else {
    *BufferLength = Size;
    return EFI_SUCCESS;
  }
}

EFI_STATUS
FfsRebaseImageRead (
    IN      VOID    *FileHandle,
    IN      UINTN   FileOffset,
    IN OUT  UINT32  *ReadSize,
    OUT     VOID    *Buffer
    )
  /*++

    Routine Description:

    Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

    Arguments:

   FileHandle - The handle to the PE/COFF file

   FileOffset - The offset, in bytes, into the file to read

   ReadSize   - The number of bytes to read from the file starting at FileOffset

   Buffer     - A pointer to the buffer to read the data into.

   Returns:

   EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

   --*/
{
  CHAR8   *Destination8;
  CHAR8   *Source8;
  UINT32  Length;

  Destination8  = Buffer;
  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
  Length        = *ReadSize;
  while (Length--) {
    *(Destination8++) = *(Source8++);
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
  /*++
    InFile is input file for getting alignment
    return the alignment
    --*/
{
  FILE                           *InFileHandle;
  UINT8                          *PeFileBuffer;
  UINTN                          PeFileSize;
  UINT32                         CurSecHdrSize;
  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;
  EFI_COMMON_SECTION_HEADER      *CommonHeader;
  EFI_STATUS                     Status;

  InFileHandle        = NULL;
  PeFileBuffer        = NULL;
  *Alignment          = 0;

  memset (&ImageContext, 0, sizeof (ImageContext));

  InFileHandle = fopen(LongFilePath(InFile), "rb");
  if (InFileHandle == NULL){
    Error (NULL, 0, 0001, "Error opening file", InFile);
    return EFI_ABORTED;
  }
  PeFileSize = _filelength (fileno(InFileHandle));
  PeFileBuffer = (UINT8 *) malloc (PeFileSize);
  if (PeFileBuffer == NULL) {
    fclose (InFileHandle);
    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile);
    return EFI_OUT_OF_RESOURCES;
  }
  fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
  fclose (InFileHandle);
  CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;
  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);
  ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);
  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;
  Status               = PeCoffLoaderGetImageInfo(&ImageContext);
  if (EFI_ERROR (Status)) {
    Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);
    return Status;
   }
  *Alignment = ImageContext.SectionAlignment;
  // Free the allocated memory resource
  if (PeFileBuffer != NULL) {
    free (PeFileBuffer);
    PeFileBuffer = NULL;
  }
  return EFI_SUCCESS;
}

int
main (
  int   argc,
  CHAR8 *argv[]
  )
/*++

Routine Description:

  Main function.

Arguments:

  argc - Number of command line parameters.
  argv - Array of pointers to parameter strings.

Returns:
  STATUS_SUCCESS - Utility exits successfully.
  STATUS_ERROR   - Some error occurred during execution.

--*/
{
  EFI_STATUS              Status;
  EFI_FFS_FILE_ATTRIBUTES FfsAttrib;
  UINT32                  FfsAlign;
  EFI_FV_FILETYPE         FfsFiletype;
  CHAR8                   *OutputFileName;
  EFI_GUID                FileGuid = {0};
  UINT32                  InputFileNum;
  UINT32                  *InputFileAlign;
  CHAR8                   **InputFileName;
  UINT8                   *FileBuffer;
  UINT32                  FileSize;
  UINT32                  MaxAlignment;
  EFI_FFS_FILE_HEADER2    FfsFileHeader;
  FILE                    *FfsFile;
  UINT32                  Index;
  UINT64                  LogLevel;
  UINT8                   PeSectionNum;
  UINT32                  HeaderSize;
  UINT32                  Alignment;
  //
  // Workaround for static code checkers.
  // Ensures the size of 'AlignmentBuffer' can hold all the digits of an
  // unsigned 32-bit integer plus the size unit character.
  //
  CHAR8                   AlignmentBuffer[16];

  //
  // Init local variables
  //
  LogLevel       = 0;
  Index          = 0;
  FfsAttrib      = 0;
  FfsAlign       = 0;
  FfsFiletype    = EFI_FV_FILETYPE_ALL;
  OutputFileName = NULL;
  InputFileNum   = 0;
  InputFileName  = NULL;
  InputFileAlign = NULL;
  FileBuffer     = NULL;
  FileSize       = 0;
  MaxAlignment   = 1;
  FfsFile        = NULL;
  Status         = EFI_SUCCESS;
  PeSectionNum   = 0;

  SetUtilityName (UTILITY_NAME);

  if (argc == 1) {
    Error (NULL, 0, 1001, "Missing options", "no options input");
    Usage ();
    return STATUS_ERROR;
  }

  //
  // Parse command line
  //
  argc --;
  argv ++;

  if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
    Version ();
    Usage ();
    return STATUS_SUCCESS;
  }

  if (stricmp (argv[0], "--version") == 0) {
    Version ();
    return STATUS_SUCCESS;
  }

  while (argc > 0) {
    if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--filetype") == 0)) {
      if (argv[1] == NULL || argv[1][0] == '-') {
        Error (NULL, 0, 1003, "Invalid option value", "file type is missing for -t option");
        goto Finish;
      }
      FfsFiletype = StringToType (argv[1]);
      if (FfsFiletype == EFI_FV_FILETYPE_ALL) {
        Error (NULL, 0, 1003, "Invalid option value", "%s is not a valid file type", argv[1]);
        goto Finish;
      }
      argc -= 2;
      argv += 2;
      continue;
    }

    if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
      if (argv[1] == NULL || argv[1][0] == '-') {
        Error (NULL, 0, 1003, "Invalid option value", "Output file is missing for -o option");
        goto Finish;
      }
      OutputFileName = argv[1];
      argc -= 2;
      argv += 2;
      continue;
    }

    if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--fileguid") == 0)) {
      Status = StringToGuid (argv[1], &FileGuid);
      if (EFI_ERROR (Status)) {
        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
        goto Finish;
      }
      argc -= 2;
      argv += 2;
      continue;
    }

    if ((stricmp (argv[0], "-x") == 0) || (stricmp (argv[0], "--fixed") == 0)) {
      FfsAttrib |= FFS_ATTRIB_FIXED;
      argc -= 1;
      argv += 1;
      continue;
    }

    if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--checksum") == 0)) {
      FfsAttrib |= FFS_ATTRIB_CHECKSUM;
      argc -= 1;
      argv += 1;
      continue;
    }

    if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) {
      if (argv[1] == NULL || argv[1][0] == '-') {
        Error (NULL, 0, 1003, "Invalid option value", "Align value is missing for -a option");
        goto Finish;
      }
      for (Index = 0; Index < sizeof (mFfsValidAlignName) / sizeof (CHAR8 *); Index ++) {
        if (stricmp (argv[1], mFfsValidAlignName[Index]) == 0) {
          break;
        }
      }
      if (Index == sizeof (mFfsValidAlignName) / sizeof (CHAR8 *)) {
        if ((stricmp (argv[1], "1") == 0) || (stricmp (argv[1], "2") == 0) || (stricmp (argv[1], "4") == 0)) {
          //
          // 1, 2, 4 byte alignment same to 8 byte alignment
          //
          Index = 0;
        } else {
          Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
          goto Finish;
        }
      }
      FfsAlign = Index;
      argc -= 2;
      argv += 2;
      continue;
    }

    if ((stricmp (argv[0], "-oi") == 0) || (stricmp (argv[0], "--optionalsectionfile") == 0) || (stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--sectionfile") == 0)) {
      //
      // Get Input file name and its alignment
      //
      if (argv[1] == NULL || argv[1][0] == '-') {
        Error (NULL, 0, 1003, "Invalid option value", "input section file is missing for -i option");
        goto Finish;
      }
      if ((stricmp (argv[0], "-oi") == 0) || (stricmp (argv[0], "--optionalsectionfile") == 0) ){
        if (-1 == access(argv[1] , 0)){
          Warning(NULL, 0, 0001, "File is not found.", argv[1]);
          argc -= 2;
          argv += 2;
          continue;
        }
      }
      //
      // Allocate Input file name buffer and its alignment buffer.
      //
      if ((InputFileNum == 0) && (InputFileName == NULL)) {
        InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));
        if (InputFileName == NULL) {
          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
          return STATUS_ERROR;
        }
        memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));

        InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
        if (InputFileAlign == NULL) {
          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
          free (InputFileName);
          return STATUS_ERROR;
        }
        memset (InputFileAlign, 0, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
      } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {
        //
        // InputFileName and alignment buffer too small, need to realloc
        //
        InputFileName = (CHAR8 **) realloc (
                                    InputFileName,
                                    (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
                                    );

        if (InputFileName == NULL) {
          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
          free (InputFileAlign);
          return STATUS_ERROR;
        }
        memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));

        InputFileAlign = (UINT32 *) realloc (
                                    InputFileAlign,
                                    (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)
                                    );

        if (InputFileAlign == NULL) {
          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
          free (InputFileName);
          return STATUS_ERROR;
        }
        memset (&(InputFileAlign[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));
      }

      InputFileName[InputFileNum] = argv[1];
      argc -= 2;
      argv += 2;

      if (argc <= 0) {
        InputFileNum ++;
        break;
      }

      //
      // Section File alignment requirement
      //
      if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {
        if ((argv[1] != NULL) && (stricmp("0", argv[1]) == 0)) {
          Status = GetAlignmentFromFile(InputFileName[InputFileNum], &Alignment);
          if (EFI_ERROR(Status)) {
            Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);
            goto Finish;
          }
          if (Alignment < 0x400){
            sprintf (AlignmentBuffer, "%d", Alignment);
          }
          else if (Alignment >= 0x100000) {
            sprintf (AlignmentBuffer, "%dM", Alignment/0x100000);
          }
          else {
            sprintf (AlignmentBuffer, "%dK", Alignment/0x400);
          }
          Status = StringtoAlignment (AlignmentBuffer, &(InputFileAlign[InputFileNum]));
        }
        else {
          Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum]));
        }
        if (EFI_ERROR (Status)) {
          Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
          goto Finish;
        }
        argc -= 2;
        argv += 2;
      }
      InputFileNum ++;
      continue;
    }

    if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {
      Error (NULL, 0, 1000, "Unknown option", "SectionAlign option must be specified with section file.");
      goto Finish;
    }

    if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
      SetPrintLevel (VERBOSE_LOG_LEVEL);
      VerboseMsg ("Verbose output Mode Set!");
      argc --;
      argv ++;
      continue;
    }

    if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
      SetPrintLevel (KEY_LOG_LEVEL);
      KeyMsg ("Quiet output Mode Set!");
      argc --;
      argv ++;
      continue;
    }

    if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
      Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
      if (EFI_ERROR (Status)) {
        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
        goto Finish;
      }
      if (LogLevel > 9) {
        Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
        goto Finish;
      }
      SetPrintLevel (LogLevel);
      DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
      argc -= 2;
      argv += 2;
      continue;
    }

    Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);
    goto Finish;
  }

  VerboseMsg ("%s tool start.", UTILITY_NAME);

  //
  // Check the complete input parameters.
  //
  if (FfsFiletype == EFI_FV_FILETYPE_ALL) {
    Error (NULL, 0, 1001, "Missing option", "filetype");
    goto Finish;
  }

  if (CompareGuid (&FileGuid, &mZeroGuid) == 0) {
    Error (NULL, 0, 1001, "Missing option", "fileguid");
    goto Finish;
  }

  if (InputFileNum == 0) {
    Error (NULL, 0, 1001, "Missing option", "Input files");
    goto Finish;
  }

  //
  // Output input parameter information
  //
  VerboseMsg ("Fv File type is %s", mFfsFileType [FfsFiletype]);
  VerboseMsg ("Output file name is %s", OutputFileName);
  VerboseMsg ("FFS File Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
                (unsigned) FileGuid.Data1,
                FileGuid.Data2,
                FileGuid.Data3,
                FileGuid.Data4[0],
                FileGuid.Data4[1],
                FileGuid.Data4[2],
                FileGuid.Data4[3],
                FileGuid.Data4[4],
                FileGuid.Data4[5],
                FileGuid.Data4[6],
                FileGuid.Data4[7]);
  if ((FfsAttrib & FFS_ATTRIB_FIXED) != 0) {
    VerboseMsg ("FFS File has the fixed file attribute");
  }
  if ((FfsAttrib & FFS_ATTRIB_CHECKSUM) != 0) {
    VerboseMsg ("FFS File requires the checksum of the whole file");
  }
  VerboseMsg ("FFS file alignment is %s", mFfsValidAlignName[FfsAlign]);
  for (Index = 0; Index < InputFileNum; Index ++) {
    if (InputFileAlign[Index] == 0) {
      //
      // Minimum alignment is 1 byte.
      //
      InputFileAlign[Index] = 1;
    }
    VerboseMsg ("the %dth input section name is %s and section alignment is %u", Index, InputFileName[Index], (unsigned) InputFileAlign[Index]);
  }

  //
  // Calculate the size of all input section files.
  //
  Status = GetSectionContents (
             InputFileName,
             InputFileAlign,
             InputFileNum,
             FfsAttrib,
             FileBuffer,
             &FileSize,
             &MaxAlignment,
             &PeSectionNum
             );

  if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE ||
      FfsFiletype == EFI_FV_FILETYPE_PEI_CORE ||
      FfsFiletype == EFI_FV_FILETYPE_DXE_CORE) && (PeSectionNum != 1)) {
    Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %u Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum);
    goto Finish;
  }

  if ((FfsFiletype == EFI_FV_FILETYPE_PEIM ||
      FfsFiletype == EFI_FV_FILETYPE_DRIVER ||
      FfsFiletype == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER ||
      FfsFiletype == EFI_FV_FILETYPE_APPLICATION) && (PeSectionNum < 1)) {
    Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have at least one Pe or Te section, but no Pe/Te section is input", mFfsFileType [FfsFiletype]);
    goto Finish;
  }

  if (Status == EFI_BUFFER_TOO_SMALL) {
    FileBuffer = (UINT8 *) malloc (FileSize);
    if (FileBuffer == NULL) {
      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
      goto Finish;
    }
    memset (FileBuffer, 0, FileSize);

    //
    // read all input file contents into a buffer
    //
    Status = GetSectionContents (
               InputFileName,
               InputFileAlign,
               InputFileNum,
               FfsAttrib,
               FileBuffer,
               &FileSize,
               &MaxAlignment,
               &PeSectionNum
               );
  }

  if (EFI_ERROR (Status)) {
    goto Finish;
  }

  if (FileBuffer == NULL && FileSize != 0) {
    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
    goto Finish;
  }

  //
  // Create Ffs file header.
  //
  memset (&FfsFileHeader, 0, sizeof (EFI_FFS_FILE_HEADER2));
  memcpy (&FfsFileHeader.Name, &FileGuid, sizeof (EFI_GUID));
  FfsFileHeader.Type       = FfsFiletype;
  //
  // Update FFS Alignment based on the max alignment required by input section files
  //
  VerboseMsg ("the max alignment of all input sections is %u", (unsigned) MaxAlignment);
  for (Index = 0; Index < sizeof (mFfsValidAlign) / sizeof (UINT32) - 1; Index ++) {
    if ((MaxAlignment > mFfsValidAlign [Index]) && (MaxAlignment <= mFfsValidAlign [Index + 1])) {
      break;
    }
  }
  if (FfsAlign < Index) {
    FfsAlign = Index;
  }
  VerboseMsg ("the alignment of the generated FFS file is %u", (unsigned) mFfsValidAlign [FfsAlign + 1]);

  //
  // Now FileSize includes the EFI_FFS_FILE_HEADER
  //
  if (FileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
    HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
    FileSize += sizeof (EFI_FFS_FILE_HEADER2);
    FfsFileHeader.ExtendedSize = FileSize;
    memset(FfsFileHeader.Size, 0, sizeof (UINT8) * 3);
    FfsAttrib |= FFS_ATTRIB_LARGE_FILE;
  } else {
    HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
    FileSize += sizeof (EFI_FFS_FILE_HEADER);
    FfsFileHeader.Size[0]  = (UINT8) (FileSize & 0xFF);
    FfsFileHeader.Size[1]  = (UINT8) ((FileSize & 0xFF00) >> 8);
    FfsFileHeader.Size[2]  = (UINT8) ((FileSize & 0xFF0000) >> 16);
  }
  VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);

  //FfsAlign larger than 7, set FFS_ATTRIB_DATA_ALIGNMENT2
  if (FfsAlign < 8) {
    FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
  } else {
    FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | ((FfsAlign & 0x7) << 3) | FFS_ATTRIB_DATA_ALIGNMENT2);
  }

  //
  // Fill in checksums and state, these must be zero for checksumming
  //
  // FileHeader.IntegrityCheck.Checksum.Header = 0;
  // FileHeader.IntegrityCheck.Checksum.File = 0;
  // FileHeader.State = 0;
  //
  FfsFileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (
                                                   (UINT8 *) &FfsFileHeader,
                                                   HeaderSize
                                                   );

  if (FfsFileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {
    //
    // Ffs header checksum = zero, so only need to calculate ffs body.
    //
    FfsFileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (
                                                   FileBuffer,
                                                   FileSize - HeaderSize
                                                   );
  } else {
    FfsFileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
  }

  FfsFileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

  //
  // Open output file to write ffs data.
  //
  if (OutputFileName != NULL) {
    remove(OutputFileName);
    FfsFile = fopen (LongFilePath (OutputFileName), "wb");
    if (FfsFile == NULL) {
      Error (NULL, 0, 0001, "Error opening file", OutputFileName);
      goto Finish;
    }
    //
    // write header
    //
    fwrite (&FfsFileHeader, 1, HeaderSize, FfsFile);
    //
    // write data
    //
    if (FileBuffer != NULL) {
      fwrite (FileBuffer, 1, FileSize - HeaderSize, FfsFile);
    }

    fclose (FfsFile);
  }

Finish:
  if (InputFileName != NULL) {
    free (InputFileName);
  }
  if (InputFileAlign != NULL) {
    free (InputFileAlign);
  }
  if (FileBuffer != NULL) {
    free (FileBuffer);
  }
  //
  // If any errors were reported via the standard error reporting
  // routines, then the status has been saved. Get the value and
  // return it to the caller.
  //
  VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());

  return GetUtilityStatus ();
}
