/*++

Copyright (c) 2004 - 2007, 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:

  GenFfsFile.c

Abstract:

  This file contains functions required to generate a Firmware File System
  file.

--*/

#include "TianoCommon.h"
#include "EfiFirmwareFileSystem.h"
#include "EfiFirmwareVolumeHeader.h"
#include "EfiImageFormat.h"
#include "EfiImage.h"
#include "ParseInf.h"
#include "Compress.h"
#include "EfiCustomizedCompress.h"
#include "crc32.h"
#include "GenFfsFile.h"
#include <stdio.h>
#include <ctype.h>  // for isalpha()
//
// include file for _spawnv
//
#include <process.h>
#include <stdlib.h>
#include <string.h>
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"
#include "SimpleFileParsing.h"

#define UTILITY_NAME    "GenFfsFile"
#define TOOLVERSION     "0.32"
#define MAX_ARRAY_SIZE  100

static
INT32
GetNextLine (
  OUT CHAR8       *Destination,
  IN FILE         *Package,
  IN OUT UINT32   *LineNumber
  );

static
void
CheckSlash (
  IN OUT CHAR8  *String,
  IN FILE       *In,
  IN OUT UINT32 *LineNumber
  );

static
INT32
FindSectionInPackage (
  IN CHAR8        *BuildDirectory,
  IN FILE         *OverridePackage,
  IN OUT UINT32   *LineNumber
  );

static
STATUS
ProcessCommandLineArgs (
  int     Argc,
  char    *Argv[]
  );

static
void
PrintUsage (
  void
  );

static
void
AddMacro (
  UINT8   *MacroString
  );

static
UINT8 *
GetMacroValue (
  UINT8   *MacroName
  );
    
static
void
FreeMacros (
  );

static
STATUS
ReplaceMacros (
  UINT8   *InputFile,
  UINT8   *OutputFile
  );
    
//
// Linked list to keep track of all macros
//
typedef struct _MACRO {
  struct _MACRO   *Next;
  UINT8           *Name;
  UINT8           *Value;
} MACRO;

//
// Keep globals in this structure
//
static struct {
  UINT8   BuildDirectory[_MAX_PATH];
  UINT8   PrimaryPackagePath[_MAX_PATH];
  UINT8   OverridePackagePath[_MAX_PATH];
  BOOLEAN Verbose;
  MACRO   *MacroList;
} mGlobals;

static EFI_GUID mZeroGuid = { 0 };

static UINT8  MinFfsDataAlignOverride = 0;

static
void
StripQuotes (
  IN OUT CHAR8 *String
  )
/*++

Routine Description:

  Removes quotes and/or whitespace from around a string

Arguments:

 String    - String to remove quotes from

Returns:

  None

--*/
{
  UINTN Index;
  UINTN Index2;
  UINTN StrLen;

  Index2  = strspn (String, "\" \t\n");
  StrLen  = strlen (String);

  for (Index = Index2; String[Index] != '\"', Index < StrLen; Index++) {
    String[Index - Index2] = String[Index];
  }

  String[Index - Index2] = 0;
}

static
void
PrintUsage (
  void
  )
/*++

Routine Description:

  Print Error / Help message.

Arguments:

  void

Returns:

  None

--*/
{
  printf ("Usage:\n");
  printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\"\n");
  printf ("           -d \"name=value\" -v\n");
  printf ("   -b \"build directory\":\n");
  printf ("       specifies the full path to the component build directory.\n");
  printf ("   -p1 \"P1_path\":\n");
  printf ("       specifies fully qualified file name to the primary package file.\n");
  printf ("       This file will normally exist in the same directory as the makefile\n");
  printf ("       for the component. Required.\n");
  printf ("   -p2 \"P2_path\":\n");
  printf ("       specifies fully qualified file name to the override package file.\n");
  printf ("       This file will normally exist in the build tip. Optional.\n");
  printf ("   -d \"name=value\":\n");
  printf ("       add a macro definition for package file. Optional.\n");
  printf ("   -v :\n");
  printf ("       verbose. Optional.\n");
}

static
INT32
TestComment (
  IN CHAR8  *String,
  IN FILE   *In
  )
/*++

Routine Description:

  Tests input string to see if it is a comment, and if so goes to the next line in the file that is not a comment

Arguments:

  String      - String to test

  In          - Open file to move pointer within

Returns:

  -1          - End of file reached
   0          - Not a comment
   1          - Comment bypassed

--*/
{
  CHAR8 CharBuffer;

  CharBuffer = 0;
  if ((String[0] == '/') && (String[1] == '/')) {
    while (CharBuffer != '\n') {
      fscanf (In, "%c", &CharBuffer);
      if (feof (In)) {
        return -1;
      }
    }
  } else {
    return 0;
  }

  return 1;
}

static
void
BreakString (
  IN CONST CHAR8 *Source,
  OUT CHAR8      *Destination,
  IN INTN        Direction
  )
/*++

Routine Description:

  Takes an input string and returns either the part before the =, or the part after the =, depending on direction

Arguments:

  Source      - String to break

  Destination - Buffer to place new string in

  Direction   - 0 to return all of source string before =
                1 to return all of source string after =

Returns:

  None

--*/
{
  UINTN Index;
  UINTN Index2;

  Index   = 0;
  Index2  = 0;

  if (strchr (Source, '=') == NULL) {
    strcpy (Destination, Source);

    return ;
  }

  if (Direction == 0) {
    //
    // return part of string before =
    //
    while (Source[Index] != '=') {
      Destination[Index] = Source[Index++];
    }

    Destination[Index] = 0;
  } else {
    //
    // return part of string after =
    //
    strcpy (Destination, strchr (Source, '=') + 1);
  }
}

static
INT32
GetNextLine (
  OUT CHAR8       *Destination,
  IN FILE         *Package,
  IN OUT UINT32   *LineNumber
  )
/*++

Routine Description:

  Gets the next non-commented line from the file

Arguments:

  Destination - Where to put string

  Package     - Package to get string from
  
  LineNumber  - The actual line number.

Returns:

  -1          - End of file reached
   0          - Success

--*/
{
  CHAR8 String[_MAX_PATH];
  fscanf (Package, "%s", &String);
  if (feof (Package)) {
    return -1;
  }

  while (TestComment (String, Package) == 1) {
    fscanf (Package, "%s", &String);
    if (feof (Package)) {
      return -1;
    }
  }

  strcpy (Destination, String);
  return 0;
}

static
VOID
CheckSlash (
  IN OUT CHAR8  *String,
  IN FILE       *In,
  IN OUT UINT32 *LineNumber
  )
/*++

Routine Description:

  Checks to see if string is line continuation character, if so goes to next valid line

Arguments:

  String      - String to test

  In          - Open file to move pointer within
  
  LineNumber  - The line number.

Returns:

  None

--*/
{
  CHAR8 ByteBuffer;
  ByteBuffer = 0;

  switch (String[0]) {

  case '\\':
    while (String[0] == '\\') {
      while (ByteBuffer != '\n') {
        fscanf (In, "%c", &ByteBuffer);
      }
      (*LineNumber)++;
      if (GetNextLine (String, In, LineNumber) == -1) {
        return ;
      }
    }
    break;

  case '\n':
    (*LineNumber)++;
    while (String[0] == '\n') {
      if (GetNextLine (String, In, LineNumber) == -1) {
        return ;
      }
    }
    break;

  default:
    break;

  }

}

static
INT32
FindSectionInPackage (
  IN CHAR8        *BuildDirectory,
  IN FILE         *OverridePackage,
  IN OUT UINT32   *LineNumber
  )
/*++

Routine Description:

  Finds the matching section within the package

Arguments:

  BuildDirectory  - name of section to find

  OverridePackage - Package file to search within
  
  LineNumber      - The line number.

Returns:

  -1          - End of file reached
   0          - Success

--*/
{
  CHAR8 String[_MAX_PATH];
  CHAR8 NewString[_MAX_PATH];
  String[0] = 0;

  while (strcmp (BuildDirectory, String) != 0) {
    if (GetNextLine (NewString, OverridePackage, LineNumber) != 0) {
      return -1;
    }

    if (NewString[0] == '[') {
      if (NewString[strlen (NewString) - 1] != ']') {
        //
        // have to construct string.
        //
        strcpy (String, NewString + 1);

        while (1) {
          fscanf (OverridePackage, "%s", &NewString);
          if (feof (OverridePackage)) {
            return -1;
          }

          if (NewString[0] != ']') {
            if (strlen (String) != 0) {
              strcat (String, " ");
            }

            strcat (String, NewString);
            if (String[strlen (String) - 1] == ']') {
              String[strlen (String) - 1] = 0;
              break;
            }
          } else {
            break;
          }
        }
      } else {
        NewString[strlen (NewString) - 1] = 0;
        strcpy (String, NewString + 1);
      }
    }
  }

  return 0;
}

static
EFI_STATUS
GenSimpleGuidSection (
  IN OUT UINT8  *FileBuffer,
  IN OUT UINT32 *BufferSize,
  IN UINT32     DataSize,
  IN EFI_GUID   SignGuid,
  IN UINT16     GuidedSectionAttributes
  )
/*++

Routine Description:

  add GUIDed section header for the data buffer.
  data stays in same location (overwrites source data).

Arguments:

  FileBuffer  - Buffer containing data to sign

  BufferSize  - On input, the size of FileBuffer. On output, the size of
                actual section data (including added section header).

  DataSize    - Length of data to Sign

  SignGuid    - Guid to be add.
  
  GuidedSectionAttributes - The section attribute.

Returns:

  EFI_SUCCESS           - Successful
  EFI_OUT_OF_RESOURCES  - Not enough resource.

--*/
{
  UINT32                    TotalSize;

  EFI_GUID_DEFINED_SECTION  GuidSectionHeader;
  UINT8                     *SwapBuffer;

  SwapBuffer = NULL;

  if (DataSize == 0) {
    *BufferSize = 0;

    return EFI_SUCCESS;
  }

  TotalSize = DataSize + sizeof (EFI_GUID_DEFINED_SECTION);
  GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;
  GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalSize & 0xff);
  GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalSize & 0xff00) >> 8);
  GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalSize & 0xff0000) >> 16);
  memcpy (&(GuidSectionHeader.SectionDefinitionGuid), &SignGuid, sizeof (EFI_GUID));
  GuidSectionHeader.Attributes  = GuidedSectionAttributes;
  GuidSectionHeader.DataOffset  = sizeof (EFI_GUID_DEFINED_SECTION);

  SwapBuffer                    = (UINT8 *) malloc (DataSize);
  if (SwapBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  memcpy (SwapBuffer, FileBuffer, DataSize);
  memcpy (FileBuffer, &GuidSectionHeader, sizeof (EFI_GUID_DEFINED_SECTION));
  memcpy (FileBuffer + sizeof (EFI_GUID_DEFINED_SECTION), SwapBuffer, DataSize);

  //
  // Make sure section ends on a DWORD boundary
  //
  while ((TotalSize & 0x03) != 0) {
    FileBuffer[TotalSize] = 0;
    TotalSize++;
  }

  *BufferSize = TotalSize;

  if (SwapBuffer != NULL) {
    free (SwapBuffer);
  }

  return EFI_SUCCESS;
}

static
EFI_STATUS
CompressSection (
  UINT8  *FileBuffer,
  UINT32 *BufferSize,
  UINT32 DataSize,
  CHAR8  *Type
  )
/*++

Routine Description:

  Compress the data and add section header for the compressed data.
  Compressed data (with section header) stays in same location as the source
  (overwrites source data).

Arguments:

  FileBuffer  - Buffer containing data to Compress

  BufferSize  - On input, the size of FileBuffer. On output, the size of
                actual compressed data (including added section header).
                When buffer is too small, this value indicates the size needed.

  DataSize    - The size of data to compress

  Type        - The compression type (not used currently).
                Assume EFI_HEAVY_COMPRESSION.

Returns:

  EFI_BUFFER_TOO_SMALL - Buffer size is too small.
  EFI_UNSUPPORTED      - Compress type can not be supported.
  EFI_SUCCESS          - Successful
  EFI_OUT_OF_RESOURCES - Not enough resource.

--*/
{
  EFI_STATUS              Status;
  UINT8                   *CompData;
  UINT32                  CompSize;
  UINT32                  TotalSize;
  EFI_COMPRESSION_SECTION CompressionSet;
  UINT8                   CompressionType;
  COMPRESS_FUNCTION       CompressFunction;

  Status            = EFI_SUCCESS;
  CompData          = NULL;
  CompSize          = 0;
  TotalSize         = 0;
  CompressFunction  = NULL;

  //
  // Get the compress type
  //
  if (_strcmpi (Type, "Dummy") == 0) {
    //
    // Added "Dummy" to keep backward compatibility.
    //
    CompressionType   = EFI_STANDARD_COMPRESSION;
    CompressFunction  = (COMPRESS_FUNCTION) TianoCompress;

  } else if (_strcmpi (Type, "LZH") == 0) {
    //
    // EFI stardard compression (LZH)
    //
    CompressionType   = EFI_STANDARD_COMPRESSION;
    CompressFunction  = (COMPRESS_FUNCTION) TianoCompress;

  } else {
    //
    // Customized compression
    //
    Status = SetCustomizedCompressionType (Type);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    CompressionType   = EFI_CUSTOMIZED_COMPRESSION;
    CompressFunction  = (COMPRESS_FUNCTION) CustomizedCompress;
  }
  //
  // Compress the raw data
  //
  Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    CompData = malloc (CompSize);
    if (!CompData) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize);
  }

  if (EFI_ERROR (Status)) {
    if (CompData != NULL) {
      free (CompData);
    }

    return Status;
  }

  TotalSize = CompSize + sizeof (EFI_COMPRESSION_SECTION);

  //
  // Buffer too small?
  //
  if (TotalSize > *BufferSize) {
    *BufferSize = TotalSize;
    if (CompData != NULL) {
      free (CompData);
    }

    return EFI_BUFFER_TOO_SMALL;
  }
  //
  // Add the section header for the compressed data
  //
  CompressionSet.CommonHeader.Type    = EFI_SECTION_COMPRESSION;
  CompressionSet.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff);
  CompressionSet.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8);
  CompressionSet.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16);
  CompressionSet.CompressionType      = CompressionType;
  CompressionSet.UncompressedLength   = DataSize;

  //
  // Copy header and data to the buffer
  //
  memcpy (FileBuffer, &CompressionSet, sizeof (EFI_COMPRESSION_SECTION));
  memcpy (FileBuffer + sizeof (CompressionSet), CompData, CompSize);

  //
  // Make sure section ends on a DWORD boundary
  //
  while ((TotalSize & 0x03) != 0) {
    FileBuffer[TotalSize] = 0;
    TotalSize++;
  }

  *BufferSize = TotalSize;

  if (CompData != NULL) {
    free (CompData);
  }

  return EFI_SUCCESS;
}

static
void
StripParens (
  IN OUT CHAR8 *String
  )
/*++

Routine Description:

  Removes Parenthesis from around a string

Arguments:

 String    - String to remove parens from

Returns:

  None

--*/
{
  INT32 Index;

  if (String[0] != '(') {
    return ;
  }

  for (Index = 1; String[Index] != ')'; Index++) {
    String[Index - 1] = String[Index];
    if (String[Index] == 0) {
      return ;
    }
  }

  String[Index - 1] = 0;

  return ;
}

static
void
StripEqualMark (
  IN OUT CHAR8 *String
  )
/*++

Routine Description:

  Removes Equal Mark from around a string

Arguments:

 String    - String to remove equal mark from

Returns:

  None

--*/
{
  INT32 Index;

  if (String[0] != '=' && String[strlen (String) - 1] != '=') {
    return ;
  }

  if (String[0] == '=') {

    for (Index = 1; String[Index] != 0; Index++) {
      String[Index - 1] = String[Index];
    }

    String[Index - 1] = 0;
  }

  if (String[strlen (String) - 1] == '=') {
    String[strlen (String) - 1] = 0;
  }

  return ;
}

static
void
SplitAttributesField (
  IN CHAR8       *Buffer,
  IN CHAR8       *AttributesArray[],
  IN OUT UINT32  *NumberOfAttributes
  )
/*
  NumberOfAttributes: on input, it specifies the current number of attributes
                      stored in AttributeArray.
                      on output, it is updated to the latest number of attributes
                      stored in AttributesArray.
*/
{
  UINT32  Index;
  UINT32  Index2;
  UINT32  z;
  CHAR8   *CharBuffer;

  CharBuffer  = NULL;
  CharBuffer  = (CHAR8 *) malloc (_MAX_PATH);
  ZeroMem (CharBuffer, _MAX_PATH);

  for (Index = 0, z = 0, Index2 = 0; Index < strlen (Buffer); Index++) {

    if (Buffer[Index] != '|') {
      CharBuffer[z] = Buffer[Index];
      z++;
    } else {

      CharBuffer[z] = 0;
      AttributesArray[*NumberOfAttributes + Index2] = CharBuffer;
      Index2++;

      //
      // allocate new char buffer for the next attributes string
      //
      CharBuffer = (CHAR8 *) malloc (_MAX_PATH);
      ZeroMem (CharBuffer, _MAX_PATH);
      z = 0;
    }
  }

  CharBuffer[z] = 0;
  //
  // record the last attributes string in the Buffer
  //
  AttributesArray[*NumberOfAttributes + Index2] = CharBuffer;
  Index2++;

  *NumberOfAttributes += Index2;

  return ;
}

static
INT32
GetToolArguments (
  CHAR8       *ToolArgumentsArray[],
  FILE        *Package,
  CHAR8       **PtrInputFileName,
  CHAR8       **PtrOutputFileName,
  EFI_GUID    *Guid,
  UINT16      *GuidedSectionAttributes
  )
{
  CHAR8       Buffer[_MAX_PATH];
  BOOLEAN     ArgumentsFlag;
  BOOLEAN     InputFlag;
  BOOLEAN     OutputFlag;
  BOOLEAN     GuidFlag;
  BOOLEAN     AttributesFlag;
  UINT32      argc;
  UINT32      Index2;
  UINT32      z;
  CHAR8       *CharBuffer;
  INT32       ReturnValue;
  EFI_STATUS  Status;

  CHAR8       *AttributesArray[MAX_ARRAY_SIZE];
  UINT32      NumberOfAttributes;
  CHAR8       *InputFileName;
  CHAR8       *OutputFileName;
  UINT32      LineNumber;
  Buffer[_MAX_PATH];

  ArgumentsFlag   = FALSE;
  InputFlag       = FALSE;
  OutputFlag      = FALSE;
  GuidFlag        = FALSE;
  AttributesFlag  = FALSE;
  //
  // Start at 1, since ToolArgumentsArray[0]
  // is the program name.
  //
  argc            = 1;
  Index2              = 0;

  z                   = 0;
  ReturnValue         = 0;
  NumberOfAttributes  = 0;
  InputFileName       = NULL;
  OutputFileName      = NULL;

  ZeroMem (Buffer, _MAX_PATH);
  ZeroMem (AttributesArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE);
  LineNumber = 0;
  while (Buffer[0] != ')') {

    if (GetNextLine (Buffer, Package, &LineNumber) != -1) {
      CheckSlash (Buffer, Package, &LineNumber);
      StripEqualMark (Buffer);
    } else {
      Error (NULL, 0, 0, "failed to get next line from package file", NULL);
      return -1;
    }

    if (Buffer[0] == ')') {
      break;
    } else if (_strcmpi (Buffer, "ARGS") == 0) {

      ArgumentsFlag   = TRUE;
      AttributesFlag  = FALSE;
      continue;

    } else if (_strcmpi (Buffer, "INPUT") == 0) {

      InputFlag       = TRUE;
      ArgumentsFlag   = FALSE;
      AttributesFlag  = FALSE;
      continue;

    } else if (_strcmpi (Buffer, "OUTPUT") == 0) {

      OutputFlag      = TRUE;
      ArgumentsFlag   = FALSE;
      AttributesFlag  = FALSE;
      continue;

    } else if (_strcmpi (Buffer, "GUID") == 0) {

      GuidFlag        = TRUE;
      ArgumentsFlag   = FALSE;
      AttributesFlag  = FALSE;
      //
      // fetch the GUID for the section
      //
      continue;

    } else if (_strcmpi (Buffer, "ATTRIBUTES") == 0) {

      AttributesFlag  = TRUE;
      ArgumentsFlag   = FALSE;
      //
      // fetch the GUIDed Section's Attributes
      //
      continue;

    } else if (_strcmpi (Buffer, "") == 0) {
      continue;
    }
    //
    // get all command arguments into ToolArgumentsArray
    //
    if (ArgumentsFlag) {

      StripEqualMark (Buffer);

      CharBuffer = (CHAR8 *) malloc (_MAX_PATH);
      if (CharBuffer == NULL) {
        goto ErrorExit;
      }

      ZeroMem (CharBuffer, sizeof (_MAX_PATH));

      ToolArgumentsArray[argc] = CharBuffer;

      strcpy (ToolArgumentsArray[argc], Buffer);

      argc += 1;
      ToolArgumentsArray[argc] = NULL;
      continue;
    }

    if (InputFlag) {

      StripEqualMark (Buffer);

      InputFileName = (CHAR8 *) malloc (_MAX_PATH);
      if (InputFileName == NULL) {
        goto ErrorExit;
      }

      ZeroMem (InputFileName, sizeof (_MAX_PATH));

      strcpy (InputFileName, Buffer);

      InputFlag = FALSE;
      continue;
    }

    if (OutputFlag) {

      StripEqualMark (Buffer);

      OutputFileName = (CHAR8 *) malloc (_MAX_PATH);
      if (OutputFileName == NULL) {
        goto ErrorExit;
      }

      ZeroMem (OutputFileName, sizeof (_MAX_PATH));

      strcpy (OutputFileName, Buffer);

      OutputFlag = FALSE;
      continue;
    }

    if (GuidFlag) {

      StripEqualMark (Buffer);

      Status = StringToGuid (Buffer, Guid);
      if (EFI_ERROR (Status)) {
        ReturnValue = -1;
        goto ErrorExit;
      }

      GuidFlag = FALSE;
    }

    if (AttributesFlag) {

      StripEqualMark (Buffer);

      //
      // there might be no space between each attribute in the statement,
      // split them aside and return each attribute string
      // in the AttributesArray
      //
      SplitAttributesField (Buffer, AttributesArray, &NumberOfAttributes);
    }
  }
  //
  // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"INPUT",InputVariable,j);
  // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"OUTPUT",&TargetFileName,1);
  //
  for (z = 0; z < NumberOfAttributes; z++) {
    if (_strcmpi (AttributesArray[z], "PROCESSING_REQUIRED") == 0) {
      *GuidedSectionAttributes |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
    } else if (_strcmpi (AttributesArray[z], "AUTH_STATUS_VALID") == 0) {
      *GuidedSectionAttributes |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
    }
  }

ErrorExit:

  for (Index2 = 0; Index2 < MAX_ARRAY_SIZE; Index2++) {
    if (AttributesArray[Index2] == NULL) {
      break;
    }

    free (AttributesArray[Index2]);
  }

  *PtrInputFileName   = InputFileName;
  *PtrOutputFileName  = OutputFileName;

  return ReturnValue;
}

static
INT32
ProcessScript (
  IN OUT UINT8   *FileBuffer,
  IN FILE        *Package,
  IN CHAR8       *BuildDirectory,
  IN BOOLEAN     ForceUncompress
  )
/*++

Routine Description:

  Signs the section, data stays in same location

Arguments:

  FileBuffer  - Data Buffer

  Package     - Points to curly brace in Image Script

  BuildDirectory     - Name of the source directory parameter
  
  ForceUncompress   - Whether to force uncompress.

Returns:

  Number of bytes added to file buffer
  -1 on error

--*/
{
  EFI_STATUS  Status;
  UINT32      Size;
  UINT32      OldSize;
  UINT32      Adjust;
  UINT16      TeStrippedSize;
  CHAR8       Buffer[_MAX_PATH];
  CHAR8       Type[_MAX_PATH];
  CHAR8       FileName[_MAX_PATH];
  INT32       Index3;
  INT32       Index2;
  UINT32      ReturnValue;
  UINT8       ByteBuffer;
  FILE        *InFile;
  UINT32      SourceDataSize;
  CHAR8       *ToolArgumentsArray[MAX_ARRAY_SIZE];
  CHAR8       *OutputFileName;
  CHAR8       *InputFileName;
  CHAR8       ToolName[_MAX_PATH];
  FILE        *OutputFile;
  FILE        *InputFile;
  UINT8       Temp;
  int         returnint;
  UINT32      LineNumber;
  BOOLEAN     IsError;
  EFI_GUID    SignGuid;
  UINT16      GuidedSectionAttributes;
  UINT8       *TargetFileBuffer;

  OutputFileName          = NULL;
  InputFileName           = NULL;
  OutputFile              = NULL;
  InputFile               = NULL;
  IsError                 = FALSE;
  GuidedSectionAttributes = 0;
  TargetFileBuffer        = NULL;

  Size                    = 0;
  LineNumber              = 0;
  Buffer[0]               = 0;
  for (Index3 = 0; Index3 < MAX_ARRAY_SIZE; ++Index3) {
    ToolArgumentsArray[Index3] = NULL;
  }

  while (Buffer[0] != '}') {
    if (GetNextLine (Buffer, Package, &LineNumber) != -1) {
      CheckSlash (Buffer, Package, &LineNumber);
    } else {
      printf ("ERROR in IMAGE SCRIPT!\n");
      IsError = TRUE;
      goto Done;
    }

    if (_strcmpi (Buffer, "Compress") == 0) {
      //
      // Handle compress
      //
      //
      // read compression type
      //
      if (GetNextLine (Buffer, Package, &LineNumber) != -1) {
        CheckSlash (Buffer, Package, &LineNumber);
      }

      StripParens (Buffer);
      strcpy (Type, Buffer);
      //
      // build buffer
      //
      while (Buffer[0] != '{') {
        if (GetNextLine (Buffer, Package, &LineNumber) != -1) {
          CheckSlash (Buffer, Package, &LineNumber);
        }
      }

      ReturnValue = ProcessScript (&FileBuffer[Size], Package, BuildDirectory, ForceUncompress);
      if (ReturnValue == -1) {
        IsError = TRUE;
        goto Done;
      }
      //
      // Call compress routine on buffer.
      // Occasionally, compressed data + section header would
      // be largere than the source and EFI_BUFFER_TOO_SMALL is
      // returned from CompressSection()
      //
      SourceDataSize = ReturnValue;

      if (!ForceUncompress) {

        Status = CompressSection (
                  &FileBuffer[Size],
                  &ReturnValue,
                  SourceDataSize,
                  Type
                  );

        if (Status == EFI_BUFFER_TOO_SMALL) {
          Status = CompressSection (
                    &FileBuffer[Size],
                    &ReturnValue,
                    SourceDataSize,
                    Type
                    );
        }

        if (EFI_ERROR (Status)) {
          IsError = TRUE;
          goto Done;
        }
      }

      Size += ReturnValue;

    } else if (_strcmpi (Buffer, "Tool") == 0) {

      ZeroMem (ToolName, _MAX_PATH);
      ZeroMem (ToolArgumentsArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE);
      ZeroMem (&SignGuid, sizeof (EFI_GUID));

      //
      // handle signing Tool
      //
      while (Buffer[0] != '(') {
        if (GetNextLine (Buffer, Package, &LineNumber) != -1) {
          CheckSlash (Buffer, Package, &LineNumber);
        }
      }

      if (_strcmpi (Buffer, "(") == 0) {
        if (GetNextLine (Buffer, Package, &LineNumber) != -1) {
          CheckSlash (Buffer, Package, &LineNumber);
        }
      }

      StripParens (Buffer);
      strcpy (ToolName, Buffer);
      ToolArgumentsArray[0] = ToolName;

      //
      // read ARGS
      //
      if (GetToolArguments (
            ToolArgumentsArray,
            Package,
            &InputFileName,
            &OutputFileName,
            &SignGuid,
            &GuidedSectionAttributes
            ) == -1) {
        IsError = TRUE;
        goto Done;
      }
      //
      // if the tool need input file,
      // dump the file buffer to the specified input file.
      //
      if (InputFileName != NULL) {
        InputFile = fopen (InputFileName, "wb");
        if (InputFile == NULL) {
          Error (NULL, 0, 0, InputFileName, "failed to open output file for writing");
          IsError = TRUE;
          goto Done;
        }

        fwrite (FileBuffer, sizeof (UINT8), Size, InputFile);
        fclose (InputFile);
        InputFile = NULL;
        free (InputFileName);
        InputFileName = NULL;
      }
      //
      // dispatch signing tool
      //
      returnint = _spawnv (_P_WAIT, ToolName, ToolArgumentsArray);
      if (returnint != 0) {
        Error (NULL, 0, 0, ToolName, "external tool failed");
        IsError = TRUE;
        goto Done;
      }
      //
      // if the tool has output file,
      // dump the output file to the file buffer
      //
      if (OutputFileName != NULL) {

        OutputFile = fopen (OutputFileName, "rb");
        if (OutputFile == NULL) {
          Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");
          IsError = TRUE;
          goto Done;
        }

        TargetFileBuffer  = &FileBuffer[Size];
        SourceDataSize    = Size;

        fread (&Temp, sizeof (UINT8), 1, OutputFile);
        while (!feof (OutputFile)) {
          FileBuffer[Size++] = Temp;
          fread (&Temp, sizeof (UINT8), 1, OutputFile);
        }

        while ((Size & 0x03) != 0) {
          FileBuffer[Size] = 0;
          Size++;
        }

        SourceDataSize = Size - SourceDataSize;

        fclose (OutputFile);
        OutputFile = NULL;
        free (OutputFileName);
        OutputFileName = NULL;

        if (CompareGuid (&SignGuid, &mZeroGuid) != 0) {
          ReturnValue = SourceDataSize;
          Status = GenSimpleGuidSection (
                    TargetFileBuffer,
                    &ReturnValue,
                    SourceDataSize,
                    SignGuid,
                    GuidedSectionAttributes
                    );
          if (EFI_ERROR (Status)) {
            IsError = TRUE;
            goto Done;
          }

          Size = ReturnValue;
        }
      }

    } else if (Buffer[0] != '}') {
      //
      // if we are here, we should see either a file name,
      // or a }.
      //
      Index3      = 0;
      FileName[0] = 0;
      //
      // Prepend the build directory to the file name if the
      // file name does not already contain a full path.
      //
      if (!isalpha (Buffer[0]) || (Buffer[1] != ':')) {
        sprintf (FileName, "%s\\", BuildDirectory);
      }
      
      while (Buffer[Index3] != '\n') {
        if (Buffer[Index3] == 0) {
          break;
        } else {
          Index2              = strlen (FileName);
          FileName[Index2++]  = Buffer[Index3++];
          FileName[Index2]    = 0;
        }
      }

      InFile = fopen (FileName, "rb");
      if (InFile == NULL) {
        Error (NULL, 0, 0, FileName, "failed to open file for reading");
        IsError = TRUE;
        goto Done;
      }

      OldSize = Size;
      fread (&ByteBuffer, sizeof (UINT8), 1, InFile);
      while (!feof (InFile)) {
        FileBuffer[Size++] = ByteBuffer;
        fread (&ByteBuffer, sizeof (UINT8), 1, InFile);
      }

      fclose (InFile);
      InFile = NULL;

      //
      // Adjust the TE Section for IPF so that the function entries are 16-byte aligned.
      //
      if (Size - OldSize >= sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER) &&
          ((EFI_COMMON_SECTION_HEADER *) &FileBuffer[OldSize])->Type == EFI_SECTION_TE        &&
          ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->Machine == EFI_IMAGE_MACHINE_IA64) {
        TeStrippedSize = ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->StrippedSize;
        Adjust = TeStrippedSize - (OldSize + sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER));
        Adjust &= 15;
        if (Adjust > 0) {
          memmove (&FileBuffer[OldSize + Adjust], &FileBuffer[OldSize], Size - OldSize);
          //
          // Pad with RAW Section type
          //
          *(UINT32 *)&FileBuffer[OldSize] = 0x19000000 | Adjust;
          Size += Adjust;
          //
          // Make sure the Data alignment in FFS header is no less than 1 (16-byte aligned)
          //
          MinFfsDataAlignOverride = 1;
        }
      }

      //
      // Make sure section ends on a DWORD boundary
      //
      while ((Size & 0x03) != 0) {
        FileBuffer[Size] = 0;
        Size++;
      }

    }
  }

Done:
  for (Index3 = 1; Index3 < MAX_ARRAY_SIZE; Index3++) {
    if (ToolArgumentsArray[Index3] == NULL) {
      break;
    }

    free (ToolArgumentsArray[Index3]);
  }

  if (IsError) {
    return -1;
  }

  return Size;

}

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

--*/
{
  if (_strcmpi (String, "EFI_FV_FILETYPE_RAW") == 0) {
    return EFI_FV_FILETYPE_RAW;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_FREEFORM") == 0) {
    return EFI_FV_FILETYPE_FREEFORM;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_SECURITY_CORE") == 0) {
    return EFI_FV_FILETYPE_SECURITY_CORE;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_PEI_CORE") == 0) {
    return EFI_FV_FILETYPE_PEI_CORE;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_DXE_CORE") == 0) {
    return EFI_FV_FILETYPE_DXE_CORE;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_PEIM") == 0) {
    return EFI_FV_FILETYPE_PEIM;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_DRIVER") == 0) {
    return EFI_FV_FILETYPE_DRIVER;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER") == 0) {
    return EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_APPLICATION") == 0) {
    return EFI_FV_FILETYPE_APPLICATION;
  }

  if (_strcmpi (String, "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE") == 0) {
    return EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE;
  }

  return EFI_FV_FILETYPE_ALL;
}

static
UINT32
AdjustFileSize (
  IN UINT8  *FileBuffer,
  IN UINT32 FileSize
  )
/*++

Routine Description:
  Adjusts file size to insure sectioned file is exactly the right length such
  that it ends on exactly the last byte of the last section.  ProcessScript()
  may have padded beyond the end of the last section out to a 4 byte boundary.
  This padding is stripped.

Arguments:
  FileBuffer  - Data Buffer - contains a section stream
  FileSize    - Size of FileBuffer as returned from ProcessScript()

Returns:
  Corrected size of file.

--*/
{
  UINT32                    TotalLength;
  UINT32                    CurrentLength;
  UINT32                    SectionLength;
  UINT32                    SectionStreamLength;
  EFI_COMMON_SECTION_HEADER *SectionHeader;
  EFI_COMMON_SECTION_HEADER *NextSectionHeader;

  TotalLength         = 0;
  CurrentLength       = 0;
  SectionStreamLength = FileSize;

  SectionHeader       = (EFI_COMMON_SECTION_HEADER *) FileBuffer;

  while (TotalLength < SectionStreamLength) {
    SectionLength = *((UINT32 *) SectionHeader->Size) & 0x00ffffff;
    TotalLength += SectionLength;

    if (TotalLength == SectionStreamLength) {
      return TotalLength;
    }
    //
    // Move to the next byte following the section...
    //
    SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength);
    CurrentLength = (UINTN) SectionHeader - (UINTN) FileBuffer;

    //
    // Figure out where the next section begins
    //
    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + 3);
    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader &~ (UINTN) 3);
    TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader;
    SectionHeader = NextSectionHeader;
  }

  return CurrentLength;
}

static
INT32
MainEntry (
  INT32     argc,
  CHAR8     *argv[],
  BOOLEAN   ForceUncompress
  )
/*++

Routine Description:

  MainEntry function.

Arguments:

  argc            - Number of command line parameters.
  argv            - Array of pointers to command line parameter strings.
  ForceUncompress - If TRUE, force to do not compress the sections even if compression
                    is specified in the script. Otherwise, FALSE.

Returns:
  STATUS_SUCCESS  - Function exits successfully.
  STATUS_ERROR    - Some error occurred during execution.

--*/
{
  FILE                    *PrimaryPackage;
  FILE                    *OverridePackage;
  FILE                    *Out;
  CHAR8                   BaseName[_MAX_PATH];
  EFI_GUID                FfsGuid;
  CHAR8                   GuidString[_MAX_PATH];
  EFI_FFS_FILE_HEADER     FileHeader;
  CHAR8                   FileType[_MAX_PATH];
  EFI_FFS_FILE_ATTRIBUTES FfsAttrib;
  EFI_FFS_FILE_ATTRIBUTES FfsAttribDefined;
  UINT64                  FfsAlignment;
  UINT32                  FfsAlignment32;
  CHAR8                   InputString[_MAX_PATH];
  BOOLEAN                 ImageScriptInOveride;
  UINT32                  FileSize;
  UINT8                   *FileBuffer;
  EFI_STATUS              Status;
  UINT32                  LineNumber;
#if (PI_SPECIFICATION_VERSION < 0x00010000)  
  EFI_FFS_FILE_TAIL       TailValue;
#endif
  BaseName[0]       = 0;
  FileType[0]       = 0;
  FfsAttrib         = 0;
  FfsAttribDefined  = 0;
  FfsAlignment      = 0;
  FfsAlignment32    = 0;
  PrimaryPackage    = NULL;
  Out               = NULL;
  OverridePackage   = NULL;
  FileBuffer        = NULL;

  strcpy (GuidString, "00000000-0000-0000-0000-000000000000");
  Status = StringToGuid (GuidString, &FfsGuid);
  if (Status != 0) {
    Error (NULL, 0, 0, GuidString, "error parsing GUID string");
    return STATUS_ERROR;
  }

  GuidString[0]         = 0;
  ImageScriptInOveride  = FALSE;
  //
  // Initialize the simple file parsing routines. Then open
  // the primary package file for parsing.
  //
  SFPInit ();
  if (SFPOpenFile (mGlobals.PrimaryPackagePath) != STATUS_SUCCESS) {
    Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file");
    goto Done;
  }
  //
  // First token in the file must be "PACKAGE.INF"
  //
  if (!SFPIsToken ("PACKAGE.INF")) {
    Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'PACKAGE.INF'", NULL);
    goto Done;
  }
  //
  // Find the [.] section
  //
  if (!SFPSkipToToken ("[.]")) {
    Error (mGlobals.PrimaryPackagePath, 1, 0, "could not locate [.] section in package file", NULL);
    goto Done;
  }
  //
  // Start parsing the data. The algorithm is essentially the same for each keyword:
  //   1. Identify the keyword
  //   2. Verify that the keyword/value pair has not already been defined
  //   3. Set some flag indicating that the keyword/value pair has been defined
  //   4. Skip over the "="
  //   5. Get the value, which may be a number, TRUE, FALSE, or a string.
  //
  while (1) {
    if (SFPIsToken ("BASE_NAME")) {
      //
      // Found BASE_NAME, format:
      //   BASE_NAME = MyBaseName
      //
      if (BaseName[0] != 0) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "BASE_NAME already defined", NULL);
        goto Done;
      }

      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (!SFPGetNextToken (BaseName, sizeof (BaseName))) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid base name", NULL);
        goto Done;
      }
    } else if (SFPIsToken ("IMAGE_SCRIPT")) {
      //
      // Found IMAGE_SCRIPT. Break out and process below.
      //
      break;
    } else if (SFPIsToken ("FFS_FILEGUID")) {
      //
      // found FILEGUID, format:
      //   FFS_FILEGUID = F7845C4F-EDF5-42C5-BD8F-A02AF63DD93A
      //
      if (GuidString[0] != 0) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILEGUID already defined", NULL);
        goto Done;
      }

      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (SFPGetGuidToken (GuidString, sizeof (GuidString)) != TRUE) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected file GUID", NULL);
        goto Done;
      }

      Status = StringToGuid (GuidString, &FfsGuid);
      if (Status != 0) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid file GUID", NULL);
        goto Done;
      }
    } else if (SFPIsToken ("FFS_FILETYPE")) {
      //
      // ***********************************************************************
      //
      // Found FFS_FILETYPE, format:
      //  FFS_FILETYPE = EFI_FV_FILETYPE_APPLICATION
      //
      if (FileType[0] != 0) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILETYPE previously defined", NULL);
        goto Done;
      }

      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (!SFPGetNextToken (FileType, sizeof (FileType))) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid FFS_FILETYPE", NULL);
        goto Done;
      }
    }
#if (PI_SPECIFICATION_VERSION < 0x00010000)    
    else if (SFPIsToken ("FFS_ATTRIB_HEADER_EXTENSION")) {
      //
      // ***********************************************************************
      //
      // Found: FFS_ATTRIB_HEADER_EXTENSION = FALSE
      // Spec says the bit is for future expansion, and must be false.
      //
      if (FfsAttribDefined & FFS_ATTRIB_HEADER_EXTENSION) {
        Error (
          mGlobals.PrimaryPackagePath,
          SFPGetLineNumber (),
          0,
          "FFS_ATTRIB_HEADER_EXTENSION previously defined",
          NULL
          );
        goto Done;
      }

      FfsAttribDefined |= FFS_ATTRIB_HEADER_EXTENSION;
      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (SFPIsToken ("TRUE")) {
        Error (
          mGlobals.PrimaryPackagePath,
          SFPGetLineNumber (),
          0,
          "only FFS_ATTRIB_HEADER_EXTENSION = FALSE is supported",
          NULL
          );
        goto Done;
      } else if (SFPIsToken ("FALSE")) {
        //
        // Default is FALSE
        //
      } else {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'FALSE'", NULL);
        goto Done;
      }
    }
#else
    else if (SFPIsToken ("FFS_ATTRIB_FIXED")) {
      //
      // ***********************************************************************
      //
      // Found: FFS_ATTRIB_FIXED = TRUE | FALSE
      //
      if (FfsAttribDefined & FFS_ATTRIB_FIXED) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_FIXED previously defined", NULL);
        goto Done;
      }

      FfsAttribDefined |= FFS_ATTRIB_FIXED;
      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (SFPIsToken ("TRUE")) {
        FfsAttrib |= FFS_ATTRIB_FIXED;
      } else if (SFPIsToken ("FALSE")) {
        //
        // Default is FALSE
        //
      } else {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
        goto Done;
      }
    } 
#endif
    else if (SFPIsToken ("FFS_ATTRIB_TAIL_PRESENT")) {
      //
      // ***********************************************************************
      //
      // Found: FFS_ATTRIB_TAIL_PRESENT = TRUE | FALSE
      //
      if (FfsAttribDefined & FFS_ATTRIB_TAIL_PRESENT) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_TAIL_PRESENT previously defined", NULL);
        goto Done;
      }

      FfsAttribDefined |= FFS_ATTRIB_TAIL_PRESENT;
      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (SFPIsToken ("TRUE")) {
        FfsAttrib |= FFS_ATTRIB_TAIL_PRESENT;
      } else if (SFPIsToken ("FALSE")) {
        //
        // Default is FALSE
        //
      } else {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
        goto Done;
      }
    } else if (SFPIsToken ("FFS_ATTRIB_RECOVERY")) {
      //
      // ***********************************************************************
      //
      // Found: FFS_ATTRIB_RECOVERY = TRUE | FALSE
      //
      if (FfsAttribDefined & FFS_ATTRIB_RECOVERY) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_RECOVERY previously defined", NULL);
        goto Done;
      }

      FfsAttribDefined |= FFS_ATTRIB_RECOVERY;
      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (SFPIsToken ("TRUE")) {
        FfsAttrib |= FFS_ATTRIB_RECOVERY;
      } else if (SFPIsToken ("FALSE")) {
        //
        // Default is FALSE
        //
      } else {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
        goto Done;
      }
    } else if (SFPIsToken ("FFS_ATTRIB_CHECKSUM")) {
      //
      // ***********************************************************************
      //
      // Found: FFS_ATTRIB_CHECKSUM = TRUE | FALSE
      //
      if (FfsAttribDefined & FFS_ATTRIB_CHECKSUM) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_CHECKSUM previously defined", NULL);
        goto Done;
      }

      FfsAttribDefined |= FFS_ATTRIB_CHECKSUM;
      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (SFPIsToken ("TRUE")) {
        FfsAttrib |= FFS_ATTRIB_CHECKSUM;
      } else if (SFPIsToken ("FALSE")) {
        //
        // Default is FALSE
        //
      } else {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
        goto Done;
      }
    } else if (SFPIsToken ("FFS_ALIGNMENT") || SFPIsToken ("FFS_ATTRIB_DATA_ALIGNMENT")) {
      //
      // ***********************************************************************
      //
      // Found FFS_ALIGNMENT, formats:
      //   FFS_ALIGNMENT = 0-7
      //   FFS_ATTRIB_DATA_ALIGNMENT = 0-7
      //
      if (FfsAttribDefined & FFS_ATTRIB_DATA_ALIGNMENT) {
        Error (
          mGlobals.PrimaryPackagePath,
          SFPGetLineNumber (),
          0,
          "FFS_ALIGNMENT/FFS_ATTRIB_DATA_ALIGNMENT previously defined",
          NULL
          );
        goto Done;
      }

      FfsAttribDefined |= FFS_ATTRIB_DATA_ALIGNMENT;
      if (!SFPIsToken ("=")) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);
        goto Done;
      }

      if (!SFPGetNumber (&FfsAlignment32)) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected numeric value for alignment", NULL);
        goto Done;
      }

      if (FfsAlignment32 > 7) {
        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 0 <= alignment <= 7", NULL);
        goto Done;
      }

      FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment32) << 3);
    } else {
      SFPGetNextToken (InputString, sizeof (InputString));
      Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, InputString, "unrecognized/unexpected token");
      goto Done;
    }
  }
  //
  // Close the primary package file
  //
  SFPCloseFile ();
  //
  // TODO: replace code below with basically a copy of the code above. Don't
  // forget to reset the FfsAttribDefined variable first. Also, you'll need
  // to somehow keep track of whether or not the basename is defined multiple
  // times in the override package. Ditto on the file GUID.
  //
  if (mGlobals.OverridePackagePath[0] != 0) {
    OverridePackage = fopen (mGlobals.OverridePackagePath, "r");
    //
    // NOTE: For package override to work correctly, the code below must be modified to
    //       SET or CLEAR bits properly. For example, if the primary package set
    //       FFS_ATTRIB_CHECKSUM = TRUE, and the override set FFS_ATTRIB_CHECKSUM = FALSE, then
    //       we'd need to clear the bit below. Since this is not happening, I'm guessing that
    //       the override functionality is not being used, so should be made obsolete. If I'm
    //       wrong, and it is being used, then it needs to be fixed. Thus emit an error if it is
    //       used, and we'll address it then.  4/10/2003
    //
    Error (__FILE__, __LINE__, 0, "package override functionality is not implemented correctly", NULL);
    goto Done;
  } else {
    OverridePackage = NULL;
  }

#ifdef OVERRIDE_SUPPORTED
  if (OverridePackage != NULL) {
    //
    // Parse override package file
    //
    fscanf (OverridePackage, "%s", &InputString);
    if (_strcmpi (InputString, "PACKAGE.INF") != 0) {
      Error (mGlobals.OverridePackagePath, 1, 0, "invalid package file", "expected 'PACKAGE.INF'");
      goto Done;
    }
    //
    // Match [dir] to Build Directory
    //
    if (FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber) != 0) {
      Error (mGlobals.OverridePackagePath, 1, 0, mGlobals.BuildDirectory, "section not found in package file");
      goto Done;
    }

    InputString[0] = 0;
    while ((InputString[0] != '[') && (!feof (OverridePackage))) {
      if (GetNextLine (InputString, OverridePackage, &LineNumber) != -1) {
        if (InputString[0] != '[') {
here:
          if (_strcmpi (InputString, "BASE_NAME") == 0) {
            //
            // found BASE_NAME, next is = and string.
            //
            fscanf (OverridePackage, "%s", &InputString);
            CheckSlash (InputString, OverridePackage, &LineNumber);
            if (strlen (InputString) == 1) {
              //
              // string is just =
              //
              fscanf (OverridePackage, "%s", &InputString);
              CheckSlash (InputString, OverridePackage, &LineNumber);
              strcpy (BaseName, InputString);
            } else {
              BreakString (InputString, InputString, 1);
              strcpy (BaseName, InputString);
            }
          } else if (_strcmpi (InputString, "IMAGE_SCRIPT") == 0) {
            //
            // found IMAGE_SCRIPT, come back later to process it
            //
            ImageScriptInOveride = TRUE;
            fscanf (OverridePackage, "%s", &InputString);
          } else if (_strcmpi (InputString, "FFS_FILEGUID") == 0) {
            //
            // found FILEGUID, next is = and string.
            //
            fscanf (OverridePackage, "%s", &InputString);
            CheckSlash (InputString, OverridePackage, &LineNumber);
            if (strlen (InputString) == 1) {
              //
              // string is just =
              //
              fscanf (OverridePackage, "%s", &InputString);
              CheckSlash (InputString, OverridePackage, &LineNumber);
              Status = StringToGuid (InputString, &FfsGuid);
              if (Status != 0) {
                Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format");
                goto Done;
              }
            } else {
              BreakString (InputString, InputString, 1);
              Status = StringToGuid (InputString, &FfsGuid);
              if (Status != 0) {
                Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format");
                goto Done;
              }
            }
          } else if (_strcmpi (InputString, "FFS_FILETYPE") == 0) {
            //
            // found FILETYPE, next is = and string.
            //
            fscanf (OverridePackage, "%s", &InputString);
            CheckSlash (InputString, OverridePackage, &LineNumber);
            if (strlen (InputString) == 1) {
              //
              // string is just =
              //
              fscanf (OverridePackage, "%s", &InputString);
              CheckSlash (InputString, OverridePackage, &LineNumber);
              strcpy (FileType, InputString);
            } else {
              BreakString (InputString, InputString, 1);
              strcpy (FileType, InputString);
            }

          } else if (_strcmpi (InputString, "FFS_ATTRIB_RECOVERY") == 0) {
            //
            // found FFS_ATTRIB_RECOVERY, next is = and string.
            //
            fscanf (OverridePackage, "%s", &InputString);
            CheckSlash (InputString, OverridePackage, &LineNumber);
            if (strlen (InputString) == 1) {
              //
              // string is just =
              //
              fscanf (OverridePackage, "%s", &InputString);
              CheckSlash (InputString, OverridePackage, &LineNumber);
              if (_strcmpi (InputString, "TRUE") == 0) {
                FfsAttrib |= FFS_ATTRIB_RECOVERY;
              }
            } else {
              BreakString (InputString, InputString, 1);
              if (_strcmpi (InputString, "TRUE") == 0) {
                FfsAttrib |= FFS_ATTRIB_RECOVERY;
              }
            }
          } else if (_strcmpi (InputString, "FFS_ATTRIB_CHECKSUM") == 0) {
            //
            // found FFS_ATTRIB_CHECKSUM, next is = and string.
            //
            fscanf (OverridePackage, "%s", &InputString);
            CheckSlash (InputString, OverridePackage, &LineNumber);
            if (strlen (InputString) == 1) {
              //
              // string is just =
              //
              fscanf (OverridePackage, "%s", &InputString);
              CheckSlash (InputString, OverridePackage, &LineNumber);
              if (_strcmpi (InputString, "TRUE") == 0) {
                FfsAttrib |= FFS_ATTRIB_CHECKSUM;
              }
            } else {
              BreakString (InputString, InputString, 1);
              if (_strcmpi (InputString, "TRUE") == 0) {
                FfsAttrib |= FFS_ATTRIB_CHECKSUM;
              }
            }
          } else if (_strcmpi (InputString, "FFS_ALIGNMENT") == 0) {
            //
            // found FFS_ALIGNMENT, next is = and string.
            //
            fscanf (OverridePackage, "%s", &InputString);
            CheckSlash (InputString, OverridePackage, &LineNumber);
            if (strlen (InputString) == 1) {
              //
              // string is just =
              //
              fscanf (OverridePackage, "%s", &InputString);
              CheckSlash (InputString, OverridePackage, &LineNumber);
            } else {
              BreakString (InputString, InputString, 1);
            }

            AsciiStringToUint64 (InputString, FALSE, &FfsAlignment);
            if (FfsAlignment > 7) {
              Error (mGlobals.OverridePackagePath, 1, 0, InputString, "invalid FFS_ALIGNMENT value");
              goto Done;
            }

            FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment) << 3);
          } else if (strchr (InputString, '=') != NULL) {
            BreakString (InputString, String, 1);
            fseek (OverridePackage, (-1 * (strlen (String) + 1)), SEEK_CUR);
            BreakString (InputString, InputString, 0);
            goto here;
          }
        }
      }
    }
  }
#endif // #ifdef OVERRIDE_SUPPORTED
  //
  // Require that they specified a file GUID at least, since that's how we're
  // naming the file.
  //
  if (GuidString[0] == 0) {
    Error (mGlobals.PrimaryPackagePath, 1, 0, "FFS_FILEGUID must be specified", NULL);
    return STATUS_ERROR;
  }
  //
  // Build Header and process image script
  //
  FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 16) * sizeof (UINT8));
  if (FileBuffer == NULL) {
    Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL);
    goto Done;
  }

  FileSize = 0;
  if (ImageScriptInOveride) {
#ifdef OVERRIDE_SUPPORTED
    rewind (OverridePackage);
    LineNumber = 0;
    FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber);
    while (_strcmpi (InputString, "IMAGE_SCRIPT") != 0) {
      GetNextLine (InputString, OverridePackage, &LineNumber);
      CheckSlash (InputString, OverridePackage, &LineNumber);
      if (strchr (InputString, '=') != NULL) {
        BreakString (InputString, InputString, 0);
      }
    }

    while (InputString[0] != '{') {
      GetNextLine (InputString, OverridePackage, &LineNumber);
      CheckSlash (InputString, OverridePackage, &LineNumber);
    }
    //
    // Found start of image script, process it
    //
    FileSize += ProcessScript (FileBuffer, OverridePackage, mGlobals.BuildDirectory, ForceUncompress);
    if (FileSize == -1) {
      Error (NULL, 0, 0, "failed to process script", NULL);
      goto Done;
    }

    if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) {
      FileSize = AdjustFileSize (FileBuffer, FileSize);
    }

    if (BaseName[0] == '\"') {
      StripQuotes (BaseName);
    }

    if (BaseName[0] != 0) {
      sprintf (InputString, "%s-%s", GuidString, BaseName);
    } else {
      strcpy (InputString, GuidString);
    }

    switch (StringToType (FileType)) {

    case EFI_FV_FILETYPE_SECURITY_CORE:
      strcat (InputString, ".SEC");
      break;

    case EFI_FV_FILETYPE_PEIM:
    case EFI_FV_FILETYPE_PEI_CORE:
    case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
      strcat (InputString, ".PEI");
      break;

    case EFI_FV_FILETYPE_DRIVER:
    case EFI_FV_FILETYPE_DXE_CORE:
      strcat (InputString, ".DXE");
      break;

    case EFI_FV_FILETYPE_APPLICATION:
      strcat (InputString, ".APP");
      break;

    case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
      strcat (InputString, ".FVI");
      break;

    case EFI_FV_FILETYPE_RAW:
      strcat (InputString, ".RAW");
      break;

    case EFI_FV_FILETYPE_ALL:
      Error (mGlobals.OverridePackagePath, 1, 0, "invalid FFS file type for this utility", NULL);
      goto Done;

    default:
      strcat (InputString, ".FFS");
      break;
    }

    if (ForceUncompress) {
      strcat (InputString, ".ORG");
    }

    Out = fopen (InputString, "wb");
    if (Out == NULL) {
      Error (NULL, 0, 0, InputString, "could not open output file for writing");
      goto Done;
    }
    //
    // create ffs header
    //
    memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
    memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID));
    FileHeader.Type       = StringToType (FileType);
    if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) {
      FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3);
    }
    FileHeader.Attributes = FfsAttrib;
    //
    // Now FileSize includes the EFI_FFS_FILE_HEADER
    //
    FileSize += sizeof (EFI_FFS_FILE_HEADER);
    FileHeader.Size[0]  = (UINT8) (FileSize & 0xFF);
    FileHeader.Size[1]  = (UINT8) ((FileSize & 0xFF00) >> 8);
    FileHeader.Size[2]  = (UINT8) ((FileSize & 0xFF0000) >> 16);
    //
    // Fill in checksums and state, these must be zero for checksumming
    //
    // FileHeader.IntegrityCheck.Checksum.Header = 0;
    // FileHeader.IntegrityCheck.Checksum.File = 0;
    // FileHeader.State = 0;
    //
    FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (
                                                  (UINT8 *) &FileHeader,
                                                  sizeof (EFI_FFS_FILE_HEADER)
                                                  );
    if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {
      FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) &FileHeader, FileSize);
    } else {
      FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
    }

    FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
    //
    // write header
    //
    if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) {
      Error (NULL, 0, 0, "failed to write file header to output file", NULL);
      goto Done;
    }
    //
    // write data
    //
    if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) {
      Error (NULL, 0, 0, "failed to write all bytes to output file", NULL);
      goto Done;
    }

    fclose (Out);
    Out = NULL;
#endif // #ifdef OVERRIDE_SUPPORTED
  } else {
    //
    // Open primary package file and process the IMAGE_SCRIPT section
    //
    PrimaryPackage = fopen (mGlobals.PrimaryPackagePath, "r");
    if (PrimaryPackage == NULL) {
      Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file");
      goto Done;
    }

    LineNumber = 1;
    FindSectionInPackage (".", PrimaryPackage, &LineNumber);
    while (_strcmpi (InputString, "IMAGE_SCRIPT") != 0) {
      GetNextLine (InputString, PrimaryPackage, &LineNumber);
      CheckSlash (InputString, PrimaryPackage, &LineNumber);
      if (strchr (InputString, '=') != NULL) {
        BreakString (InputString, InputString, 0);
      }
    }

    while (InputString[0] != '{') {
      GetNextLine (InputString, PrimaryPackage, &LineNumber);
      CheckSlash (InputString, PrimaryPackage, &LineNumber);
    }
    //
    // Found start of image script, process it
    //
    FileSize += ProcessScript (FileBuffer, PrimaryPackage, mGlobals.BuildDirectory, ForceUncompress);
    if (FileSize == -1) {
      Error (NULL, 0, 0, "failed to process script", NULL);
      goto Done;
    }

    if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) {
      FileSize = AdjustFileSize (FileBuffer, FileSize);
    }

    if (BaseName[0] == '\"') {
      StripQuotes (BaseName);
    }

    if (BaseName[0] != 0) {
      sprintf (InputString, "%s-%s", GuidString, BaseName);
    } else {
      strcpy (InputString, GuidString);
    }

    switch (StringToType (FileType)) {

    case EFI_FV_FILETYPE_SECURITY_CORE:
      strcat (InputString, ".SEC");
      break;

    case EFI_FV_FILETYPE_PEIM:
    case EFI_FV_FILETYPE_PEI_CORE:
    case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
      strcat (InputString, ".PEI");
      break;

    case EFI_FV_FILETYPE_DRIVER:
    case EFI_FV_FILETYPE_DXE_CORE:
      strcat (InputString, ".DXE");
      break;

    case EFI_FV_FILETYPE_APPLICATION:
      strcat (InputString, ".APP");
      break;

    case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
      strcat (InputString, ".FVI");
      break;

    case EFI_FV_FILETYPE_RAW:
      strcat (InputString, ".RAW");
      break;

    case EFI_FV_FILETYPE_ALL:
      Error (mGlobals.PrimaryPackagePath, 1, 0, "invalid FFS file type for this utility", NULL);
      goto Done;

    default:
      strcat (InputString, ".FFS");
      break;
    }

    if (ForceUncompress) {
      strcat (InputString, ".ORG");
    }

    Out = fopen (InputString, "wb");
    if (Out == NULL) {
      Error (NULL, 0, 0, InputString, "failed to open output file for writing");
      goto Done;
    }
    //
    // Initialize the FFS file header
    //
    memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
    memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID));
    FileHeader.Type       = StringToType (FileType);
    if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) {
      FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3);
    }
    FileHeader.Attributes = FfsAttrib;
    //
    // From this point on FileSize includes the size of the EFI_FFS_FILE_HEADER
    //
    FileSize += sizeof (EFI_FFS_FILE_HEADER);
    //
    // If using a tail, then it adds two bytes
    //
    if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) {
      //
      // Tail is not allowed for pad and 0-length files
      //
      if ((FileHeader.Type == EFI_FV_FILETYPE_FFS_PAD) || (FileSize == sizeof (EFI_FFS_FILE_HEADER))) {
        Error (
          mGlobals.PrimaryPackagePath,
          1,
          0,
          "FFS_ATTRIB_TAIL_PRESENT=TRUE is invalid for PAD or 0-length files",
          NULL
          );
        goto Done;
      }

      FileSize += sizeof (EFI_FFS_FILE_TAIL);
    }

    FileHeader.Size[0]  = (UINT8) (FileSize & 0xFF);
    FileHeader.Size[1]  = (UINT8) ((FileSize & 0xFF00) >> 8);
    FileHeader.Size[2]  = (UINT8) ((FileSize & 0xFF0000) >> 16);
    //
    // Fill in checksums and state, they must be 0 for checksumming.
    //
    // FileHeader.IntegrityCheck.Checksum.Header = 0;
    // FileHeader.IntegrityCheck.Checksum.File = 0;
    // FileHeader.State = 0;
    //
    FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (
                                                  (UINT8 *) &FileHeader,
                                                  sizeof (EFI_FFS_FILE_HEADER)
                                                  );
    if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {
      //
      // Cheating here.  Since the header checksums, just calculate the checksum of the body.
      // Checksum does not include the tail
      //
      if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) {
        FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (
                                                    FileBuffer,
                                                    FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL)
                                                    );
      } else {
        FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (
                                                    FileBuffer,
                                                    FileSize - sizeof (EFI_FFS_FILE_HEADER)
                                                    );
      }
    } else {
      FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
    }
    //
    // Set the state now. Spec says the checksum assumes the state is 0
    //
    FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

#if (PI_SPECIFICATION_VERSION < 0x00010000)

    //
    // If there is a tail, then set it
    //
    if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) {
      TailValue = FileHeader.IntegrityCheck.TailReference;
      TailValue = (UINT16) (~TailValue);
      memcpy (
        (UINT8 *) FileBuffer + FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL),
        &TailValue,
        sizeof (TailValue)
        );
    }
#endif    
    //
    // Write the FFS file header
    //
    if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) {
      Error (NULL, 0, 0, "failed to write file header contents", NULL);
      goto Done;
    }
    //
    // Write data
    //
    if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) {
      Error (NULL, 0, 0, "failed to write file contents", NULL);
      goto Done;
    }
  }

Done:
  SFPCloseFile ();
  if (Out != NULL) {
    fclose (Out);
  }

  if (PrimaryPackage != NULL) {
    fclose (PrimaryPackage);
  }

  if (FileBuffer != NULL) {
    free (FileBuffer);
  }

  if (OverridePackage != NULL) {
    fclose (OverridePackage);
  }

  return GetUtilityStatus ();
}

int
main (
  INT32 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.

--*/
{
  STATUS  Status;
  //
  // Set the name of our utility for error reporting purposes.
  //
  SetUtilityName (UTILITY_NAME);
  Status = ProcessCommandLineArgs (argc, argv);
  FreeMacros ();
  if (Status != STATUS_SUCCESS) {
    return Status;
  }

  Status = MainEntry (argc, argv, TRUE);
  if (Status == STATUS_SUCCESS) {
    MainEntry (argc, argv, FALSE);
  }
  //
  // 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.
  //
  return GetUtilityStatus ();
}

static
STATUS
ProcessCommandLineArgs (
  int     Argc,
  char    *Argv[]
  )
/*++

Routine Description:
  Process the command line arguments.

Arguments:
  Argc - as passed in to main()
  Argv - as passed in to main()

Returns:
  STATUS_SUCCESS    - arguments all ok
  STATUS_ERROR      - problem with args, so caller should exit

--*/
{
  STATUS       Status;
  UINT8        *OriginalPrimaryPackagePath;
  UINT8        *OriginalOverridePackagePath;
  UINT8        *PackageName;
  
  //
  // If no args, then print usage instructions and return an error
  //
  if (Argc == 1) {
    PrintUsage ();
    return STATUS_ERROR;
  }
  
  OriginalPrimaryPackagePath = NULL;
  OriginalOverridePackagePath = NULL;
  memset (&mGlobals, 0, sizeof (mGlobals));
  Argc--;
  Argv++;
  while (Argc > 0) {
    if (_strcmpi (Argv[0], "-b") == 0) {
      //
      // OPTION: -b BuildDirectory
      // Make sure there is another argument, then save it to our globals.
      //
      if (Argc < 2) {
        Error (NULL, 0, 0, "-b option requires the build directory name", NULL);
        return STATUS_ERROR;
      }

      if (mGlobals.BuildDirectory[0]) {
        Error (NULL, 0, 0, Argv[0], "option can only be specified once");
        return STATUS_ERROR;
      }

      strcpy (mGlobals.BuildDirectory, Argv[1]);
      Argc--;
      Argv++;
    } else if (_strcmpi (Argv[0], "-p1") == 0) {
      //
      // OPTION: -p1 PrimaryPackageFile
      // Make sure there is another argument, then save it to our globals.
      //
      if (Argc < 2) {
        Error (NULL, 0, 0, Argv[0], "option requires the primary package file name");
        return STATUS_ERROR;
      }

      if (OriginalPrimaryPackagePath) {
        Error (NULL, 0, 0, Argv[0], "option can only be specified once");
        return STATUS_ERROR;
      }
      
      OriginalPrimaryPackagePath = Argv[1];
      Argc--;
      Argv++;
    } else if (_strcmpi (Argv[0], "-p2") == 0) {
      //
      // OPTION: -p2 OverridePackageFile
      // Make sure there is another argument, then save it to our globals.
      //
      if (Argc < 2) {
        Error (NULL, 0, 0, Argv[0], "option requires the override package file name");
        return STATUS_ERROR;
      }

      if (OriginalOverridePackagePath) {
        Error (NULL, 0, 0, Argv[0], "option can only be specified once");
        return STATUS_ERROR;
      }
      
      OriginalOverridePackagePath = Argv[1];
      Argc--;
      Argv++;
    } else if (_strcmpi (Argv[0], "-v") == 0) {
      //
      // OPTION: -v       verbose
      //
      mGlobals.Verbose = TRUE;
    } else if (_strcmpi (Argv[0], "-d") == 0) {
      //
      // OPTION: -d  name=value
      // Make sure there is another argument, then add it to our macro list.
      //
      if (Argc < 2) {
        Error (NULL, 0, 0, Argv[0], "option requires the macro definition");
        return STATUS_ERROR;
      }
      
      AddMacro (Argv[1]);
      Argc--;
      Argv++;
    } else if (_strcmpi (Argv[0], "-h") == 0) {
      //
      // OPTION: -h      help
      //
      PrintUsage ();
      return STATUS_ERROR;
    } else if (_strcmpi (Argv[0], "-?") == 0) {
      //
      // OPTION:  -?      help
      //
      PrintUsage ();
      return STATUS_ERROR;
    } else {
      Error (NULL, 0, 0, Argv[0], "unrecognized option");
      PrintUsage ();
      return STATUS_ERROR;
    }

    Argv++;
    Argc--;
  }

  //
  // Must have at least specified the build directory
  //
  if (!mGlobals.BuildDirectory[0]) {
    Error (NULL, 0, 0, "must specify build directory", NULL);
    return STATUS_ERROR;
  }
  
  //
  // Must have at least specified the package file name
  //
  if (OriginalPrimaryPackagePath == NULL) {
    Error (NULL, 0, 0, "must specify primary package file", NULL);
    return STATUS_ERROR;
  }

  PackageName = OriginalPrimaryPackagePath + strlen (OriginalPrimaryPackagePath);
  while ((*PackageName != '\\') && (*PackageName != '/') && 
         (PackageName != OriginalPrimaryPackagePath)) {
    PackageName--;
  }
  //
  // Skip the '\' or '/'
  //
  if (PackageName != OriginalPrimaryPackagePath) {
    PackageName++;
  }
  sprintf (mGlobals.PrimaryPackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName);
  Status = ReplaceMacros (OriginalPrimaryPackagePath, mGlobals.PrimaryPackagePath);
  if (Status == STATUS_WARNING) {
    //
    // No macro replacement, use the previous package file
    //
    strcpy (mGlobals.PrimaryPackagePath, OriginalPrimaryPackagePath);
  } else if (Status != STATUS_SUCCESS) {
    return Status;
  }
  
  if (OriginalOverridePackagePath != NULL) {
    PackageName = OriginalOverridePackagePath + strlen (OriginalOverridePackagePath);
    while ((*PackageName != '\\') && (*PackageName != '/') && 
           (PackageName != OriginalOverridePackagePath)) {
      PackageName--;
    }
    //
    // Skip the '\' or '/'
    //
    if (PackageName != OriginalOverridePackagePath) {
      PackageName++;
    }    
    sprintf (mGlobals.OverridePackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName);
    Status = ReplaceMacros (OriginalOverridePackagePath, mGlobals.OverridePackagePath);
    if (Status == STATUS_WARNING) {
      //
      // No macro replacement, use the previous package file
      //
      strcpy (mGlobals.OverridePackagePath, OriginalOverridePackagePath);
    } else if (Status != STATUS_SUCCESS) {
        return Status;
    }    
  }

  return STATUS_SUCCESS;
}

static
void
AddMacro (
  UINT8   *MacroString
  )
/*++

Routine Description:

  Add or override a macro definition.

Arguments:

  MacroString  - macro definition string: name=value

Returns:

  None

--*/  
{
  MACRO    *Macro;
  MACRO    *NewMacro;
  UINT8    *Value;
  
  //
  // Seperate macro name and value by '\0'
  //
  for (Value = MacroString; *Value && (*Value != '='); Value++);
  
  if (*Value == '=') {
    *Value = '\0';
    Value ++;
  }
  
  //
  // We now have a macro name and value. 
  // Look for an existing macro and overwrite it.
  //
  Macro = mGlobals.MacroList;
  while (Macro) {
    if (_strcmpi (MacroString, Macro->Name) == 0) {
      Macro->Value = Value;
      return;
    }

    Macro = Macro->Next;
  }
  
  //
  // Does not exist, create a new one
  //
  NewMacro = (MACRO *) malloc (sizeof (MACRO));
  memset ((UINT8 *) NewMacro, 0, sizeof (MACRO));
  NewMacro->Name   = MacroString;
  NewMacro->Value  = Value;

  //
  // Add it to the head of the list.
  //
  NewMacro->Next = mGlobals.MacroList;
  mGlobals.MacroList = NewMacro;
  
  return;
}

static
UINT8 *
GetMacroValue (
  UINT8   *MacroName
  )
/*++

Routine Description:

  Look up a macro.

Arguments:

  MacroName  - The name of macro

Returns:

  Pointer to the value of the macro if found
  NULL if the macro is not found

--*/   
{

  MACRO  *Macro;
  UINT8  *Value;

  //
  // Scan for macro
  //
  Macro = mGlobals.MacroList;
  while (Macro) {
    if (_strcmpi (MacroName, Macro->Name) == 0) {
      return Macro->Value;
    }
    Macro = Macro->Next;
  }
  
  //
  // Try environment variable
  //
  Value = getenv (MacroName);
  if (Value == NULL) {
    printf ("Environment variable %s not found!\n", MacroName);
  }   
  return Value;
}
  
static
void
FreeMacros (
  )
/*++

Routine Description:

  Free the macro list.

Arguments:

  None

Returns:

  None

--*/    
{
  MACRO    *Macro;
  MACRO    *NextMacro;
  
  Macro = mGlobals.MacroList;
  while (Macro) {
    NextMacro = Macro->Next;
    free (Macro);
    Macro = NextMacro;
  }
  mGlobals.MacroList = NULL;
  
  return;
}

static
STATUS
ReplaceMacros (
  UINT8   *InputFile,
  UINT8   *OutputFile
  )
/*++

Routine Description:

  Replace all the macros in InputFile to create the OutputFile.

Arguments:

  InputFile         - Input package file for macro replacement
  OutputFile        - Output package file after macro replacement

Returns:

  STATUS_SUCCESS    - Output package file is created successfully after the macro replacement.
  STATUS_WARNING    - Output package file is not created because of no macro replacement.
  STATUS_ERROR      - Some error occurred during execution.

--*/    
{
  FILE   *Fptr;
  UINT8  *SaveStart;
  UINT8  *FromPtr;
  UINT8  *ToPtr;
  UINT8  *Value;
  UINT8  *FileBuffer;
  UINTN  FileSize;
  
  //
  // Get the file size, and then read the entire thing into memory.
  // Allocate extra space for a terminator character.
  //
  if ((Fptr = fopen (InputFile, "r")) == NULL) {
    Error (NULL, 0, 0, InputFile, "can't open input file");
    return STATUS_ERROR;    
  }
  fseek (Fptr, 0, SEEK_END);
  FileSize = ftell (Fptr);
  fseek (Fptr, 0, SEEK_SET);
  FileBuffer = malloc (FileSize + 1);
  if (FileBuffer == NULL) {
    fclose (Fptr);
    Error (NULL, 0, 0, InputFile, "file buffer memory allocation failure");
    return STATUS_ERROR;
  }
  fread (FileBuffer, FileSize, 1, Fptr);
  FileBuffer[FileSize] = '\0';
  fclose (Fptr);
    
  //
  // Walk the entire file, replacing $(MACRO_NAME).
  //
  Fptr = NULL;
  FromPtr = FileBuffer;
  SaveStart = FromPtr;
  while (*FromPtr) {
    if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {
      FromPtr += 2;
      for (ToPtr = FromPtr; *ToPtr && (*ToPtr != ')'); ToPtr++);
      if (*ToPtr) {
        //
        // Find an $(MACRO_NAME), replace it
        //
        *ToPtr = '\0';
        Value = GetMacroValue (FromPtr);
        *(FromPtr-2)= '\0';
        if (Fptr == NULL) {
          if ((Fptr = fopen (OutputFile, "w")) == NULL) {
            free (FileBuffer);
            Error (NULL, 0, 0, OutputFile, "can't open output file");
            return STATUS_ERROR;    
          }
        }
        if (Value != NULL) {
          fprintf (Fptr, "%s%s", SaveStart, Value);
        } else {
          fprintf (Fptr, "%s", SaveStart);
        }
        //
        // Continue macro replacement for the remaining string line
        //
        FromPtr = ToPtr+1;
        SaveStart = FromPtr;
        continue;
      } else {
        break;
      }
    } else {
      FromPtr++;
    }
  }
  if (Fptr != NULL) {
    fprintf (Fptr, "%s", SaveStart);
  }
  
  free (FileBuffer);
  if (Fptr != NULL) {
    fclose (Fptr);
    return STATUS_SUCCESS;
  } else {
    return STATUS_WARNING;
  }
}
