/*++

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 "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
  );

//
// Keep globals in this structure
//
static struct {
  UINT8   BuildDirectory[_MAX_PATH];
  UINT8   PrimaryPackagePath[_MAX_PATH];
  UINT8   OverridePackagePath[_MAX_PATH];
  BOOLEAN Verbose;
} mGlobals;

static EFI_GUID mZeroGuid = { 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\" -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");
}

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
INT32
ProcessEnvironmentVariable (
  IN CHAR8  *Buffer,
  OUT CHAR8 *NewBuffer
  )
/*++

Routine Description:

  Converts environment variables to values

Arguments:

  Buffer      - Buffer containing Environment Variable String

  NewBuffer   - Buffer containing value of environment variable


Returns:

  Number of characters from Buffer used

--*/
{
  INT32 Index;
  INT32 Index2;
  CHAR8 VariableBuffer[_MAX_PATH];

  Index   = 2;
  Index2  = 0;

  while (Buffer[Index] != ')') {
    VariableBuffer[Index - 2] = Buffer[Index++];
  }

  VariableBuffer[Index - 2] = 0;
  Index++;

  if (getenv (VariableBuffer) != NULL) {
    strcpy (NewBuffer, getenv (VariableBuffer));
  } else {
    printf ("Environment variable %s not found!\n", VariableBuffer);
  }

  return Index;
}

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       Index;
  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;

      if (Buffer[0] == '$') {
        Index = ProcessEnvironmentVariable (&Buffer[0], ToolArgumentsArray[argc]);
        //
        // if there is string after the environment variable, cat it.
        //
        if ((UINT32) Index < strlen (Buffer)) {
          strcat (ToolArgumentsArray[argc], &Buffer[Index]);
        }
      } else {
        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));

      if (Buffer[0] == '$') {
        Index = ProcessEnvironmentVariable (&Buffer[0], InputFileName);
        //
        // if there is string after the environment variable, cat it.
        //
        if ((UINT32) Index < strlen (Buffer)) {
          strcat (InputFileName, &Buffer[Index]);
        }
      } else {
        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));

      if (Buffer[0] == '$') {
        Index = ProcessEnvironmentVariable (&Buffer[0], OutputFileName);
        //
        // if there is string after the environment variable, cat it.
        //
        if ((UINT32) Index < strlen (Buffer)) {
          strcat (OutputFileName, &Buffer[Index]);
        }
      } else {
        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;
  CHAR8       Buffer[_MAX_PATH];
  CHAR8       Type[_MAX_PATH];
  CHAR8       FileName[_MAX_PATH];
  CHAR8       NewBuffer[_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;
  INT32       Index;
  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);
      if (Buffer[0] == '$') {
        ProcessEnvironmentVariable (&Buffer[0], Type);
      } else {
        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);

      if (Buffer[0] == '$') {
        Index = ProcessEnvironmentVariable (&Buffer[0], ToolName);
        //
        // if there is string after the environment variable, cat it.
        //
        if ((UINT32) Index < strlen (Buffer)) {
          strcat (ToolName, &Buffer[Index]);
        }
      } else {
        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] == '$') {
          Index3 += ProcessEnvironmentVariable (&Buffer[Index3], NewBuffer);
          strcat (FileName, NewBuffer);
        }

        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;
      }

      fread (&ByteBuffer, sizeof (UINT8), 1, InFile);
      while (!feof (InFile)) {
        FileBuffer[Size++] = ByteBuffer;
        fread (&ByteBuffer, sizeof (UINT8), 1, InFile);
      }

      fclose (InFile);
      InFile = NULL;

      //
      // 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);
    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);
    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);
  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

--*/
{
  //
  // If no args, then print usage instructions and return an error
  //
  if (Argc == 1) {
    PrintUsage ();
    return STATUS_ERROR;
  }

  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 (mGlobals.PrimaryPackagePath[0]) {
        Error (NULL, 0, 0, Argv[0], "option can only be specified once");
        return STATUS_ERROR;
      }

      strcpy (mGlobals.PrimaryPackagePath, 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 (mGlobals.OverridePackagePath[0]) {
        Error (NULL, 0, 0, Argv[0], "option can only be specified once");
        return STATUS_ERROR;
      }

      strcpy (mGlobals.OverridePackagePath, Argv[1]);
      Argc--;
      Argv++;
    } else if (_strcmpi (Argv[0], "-v") == 0) {
      //
      // OPTION: -v       verbose
      //
      mGlobals.Verbose = TRUE;
    } 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 package file name
  //
  if (mGlobals.PrimaryPackagePath[0] == 0) {
    Error (NULL, 0, 0, "must specify primary package file", NULL);
    return STATUS_ERROR;
  }

  return STATUS_SUCCESS;
}
