/** @file
This file contains functions required to generate a Firmware File System file.

Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

**/

#ifndef __GNUC__
#include <windows.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.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 - 2017, 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, "  -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 + 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  of %s", InFileHandle);
    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], "-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;
      }

      //
      // 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 >= 0x400) {
            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 ();
}
