/** @file
Creates and EFILDR image.
This tool combines several PE Image files together using following format denoted as EBNF:
FILE := EFILDR_HEADER
        EFILDR_IMAGE +
        <PeImageFileContent> +
The order of EFILDR_IMAGE is same as the order of placing PeImageFileContent.
  
Copyright (c) 2006 - 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.             

**/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ParseInf.h"
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"

#define MAX_PE_IMAGES                  63
#define FILE_TYPE_FIXED_LOADER         0
#define FILE_TYPE_RELOCATABLE_PE_IMAGE 1

typedef struct {
  UINT32 CheckSum;
  UINT32 Offset;
  UINT32 Length;
  UINT8  FileName[52];
} EFILDR_IMAGE;

typedef struct {          
  UINT32       Signature;     
  UINT32       HeaderCheckSum;
  UINT32       FileLength;
  UINT32       NumberOfImages;
} EFILDR_HEADER;

//
// Utility Name
//
#define UTILITY_NAME  "EfiLdrImage"

//
// Utility version information
//
#define UTILITY_MAJOR_VERSION 1
#define UTILITY_MINOR_VERSION 0

void
Version (
  void
  )
/*++

Routine Description:

  Displays the standard utility information to SDTOUT

Arguments:

  None

Returns:

  None

--*/
{
  printf ("%s Version %d.%d Build %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
}

VOID
Usage (
  VOID
  )
{
  printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");
  printf ("%s Version %d.%d Build %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
  printf ("Copyright (c) 1999-2017 Intel Corporation. All rights reserved.\n");
  printf ("\n  The EfiLdrImage tool is used to combine PE files into EFILDR image with Efi loader header.\n");
}

EFI_STATUS
CountVerboseLevel (
  IN CONST CHAR8* VerboseLevelString,
  IN CONST UINT64 Length,
  OUT UINT64 *ReturnValue
)
{
  UINT64 i = 0;
  for (;i < Length; ++i) {
    if (VerboseLevelString[i] != 'v' && VerboseLevelString[i] != 'V') {
      return EFI_ABORTED;
    }
    ++(*ReturnValue);
  }
  
  return EFI_SUCCESS;
}

UINT64
FCopyFile (
  FILE    *in,
  FILE    *out
  )
/*++
Routine Description:
  Write all the content of input file to output file.

Arguments:
  in  - input file pointer
  out - output file pointer

Return:
  UINT64 : file size of input file
--*/
{
  UINT32          filesize, offset, length;
  CHAR8           Buffer[8*1024];

  fseek (in, 0, SEEK_END);
  filesize = ftell(in);

  fseek (in, 0, SEEK_SET);

  offset = 0;
  while (offset < filesize)  {
    length = sizeof(Buffer);
    if (filesize-offset < length) {
      length = filesize-offset;
    }

    fread (Buffer, length, 1, in);
    fwrite (Buffer, length, 1, out);
    offset += length;
  }

  return filesize;
}


int
main (
  int argc,
  char *argv[]
  )
/*++

Routine Description:


Arguments:


Returns:


--*/
{
  UINT64         i;
  UINT64         filesize;
  FILE          *fpIn, *fpOut;
  EFILDR_HEADER EfiLdrHeader;
  EFILDR_IMAGE  EfiLdrImage[MAX_PE_IMAGES];
  CHAR8* OutputFileName = NULL;
  CHAR8* InputFileNames[MAX_PE_IMAGES + 1];
  UINT8 InputFileCount = 0;
  UINT64        DebugLevel = 0;
  UINT64        VerboseLevel = 0;
  EFI_STATUS Status = EFI_SUCCESS;
  
  SetUtilityName (UTILITY_NAME);

  if (argc == 1) {
    printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");
    return STATUS_ERROR;
  }
  
  argc --;
  argv ++;

  if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
    Usage();
    return STATUS_SUCCESS;    
  }

  if (stricmp (argv[0], "--version") == 0) {
    Version();
    return STATUS_SUCCESS;    
  }

  while (argc > 0) {
   
    if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
      OutputFileName = argv[1];
      if (OutputFileName == NULL) {
        Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");
        return STATUS_ERROR;
      }
      argc -= 2;
      argv += 2;
      continue; 
    }
    
    if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
      argc --;
      argv ++;
      continue; 
    }
    
    if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (stricmp (argv[0], "--verbose") == 0)) {
      VerboseLevel = 1;
      if (strlen(argv[0]) > 2) {
        Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel);
        if (EFI_ERROR (Status)) {
          Error (NULL, 0, 1003, "Invalid option value", "%s", argv[0]);
          return STATUS_ERROR;        
        }
      }
      
      argc --;
      argv ++;
      continue; 
    }
    
    if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
      Status = AsciiStringToUint64 (argv[1], FALSE, &DebugLevel);
      if (EFI_ERROR (Status)) {
        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
        return STATUS_ERROR;        
      }
      argc -= 2;
      argv += 2;
      continue; 
    }
    //
    // Don't recognize the parameter, should be regarded as the input file name.
    //
    InputFileNames[InputFileCount] = argv[0];
    InputFileCount++;
    argc--;
    argv++;
  }

  if (InputFileCount == 0) {
    Error (NULL, 0, 1001, "Missing option", "No input file");
    return STATUS_ERROR;
  }
  //
  // Open output file for write
  //
  if (OutputFileName == NULL) {
    Error (NULL, 0, 1001, "Missing option", "No output file");
    return STATUS_ERROR;
  }

  fpOut = fopen (LongFilePath (OutputFileName), "w+b");
  if (!fpOut) {
    Error (NULL, 0, 0001, "Could not open output file", OutputFileName);
    return STATUS_ERROR;
  }

  memset (&EfiLdrHeader, 0, sizeof (EfiLdrHeader));
  memset (&EfiLdrImage, 0, sizeof (EFILDR_IMAGE) * (InputFileCount));

  memcpy (&EfiLdrHeader.Signature, "EFIL", 4);
  EfiLdrHeader.FileLength = sizeof(EFILDR_HEADER) + sizeof(EFILDR_IMAGE)*(InputFileCount);

  //
  // Skip the file header first
  //
  fseek (fpOut, EfiLdrHeader.FileLength, SEEK_SET);

  //
  // copy all the input files to the output file
  //
  for(i=0;i<InputFileCount;i++) {
    //
    // Copy the content of PeImage file to output file
    //
    fpIn = fopen (LongFilePath (InputFileNames[i]), "rb");
    if (!fpIn) {
      Error (NULL, 0, 0001, "Could not open input file", InputFileNames[i]);
      fclose (fpOut);
      return STATUS_ERROR;
    }
    filesize = FCopyFile (fpIn, fpOut);
    fclose(fpIn);

    //
    //  And in the same time update the EfiLdrHeader and EfiLdrImage array
    //
    EfiLdrImage[i].Offset = EfiLdrHeader.FileLength;
    EfiLdrImage[i].Length = (UINT32) filesize;
    strncpy ((CHAR8*) EfiLdrImage[i].FileName, InputFileNames[i], sizeof (EfiLdrImage[i].FileName) - 1);
    EfiLdrHeader.FileLength += (UINT32) filesize;
    EfiLdrHeader.NumberOfImages++;
  }

  //
  // Write the image header to the output file finally
  //
  fseek (fpOut, 0, SEEK_SET);
  fwrite (&EfiLdrHeader, sizeof(EFILDR_HEADER)        , 1, fpOut);
  fwrite (&EfiLdrImage , sizeof(EFILDR_IMAGE)*(InputFileCount), 1, fpOut);

  fclose (fpOut);
  printf ("Created %s\n", OutputFileName);
  return 0;
}

