(2) Remove unused library class EdkPeCoffLoaderX64Lib and library instance EdkPeCoffLoaderX64Lib, because current BasePeCoffLib can supports IA32, EBC, & X64 images all. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2069 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			2647 lines
		
	
	
		
			70 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2647 lines
		
	
	
		
			70 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c) 2004, 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 <stdio.h>
 | 
						|
#include <ctype.h>  // for isalpha()
 | 
						|
//
 | 
						|
// include file for _spawnv
 | 
						|
//
 | 
						|
#ifndef __GNUC__
 | 
						|
#include <process.h>
 | 
						|
#endif
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include <Common/UefiBaseTypes.h>
 | 
						|
#include <Common/FirmwareVolumeImageFormat.h>
 | 
						|
#include <Common/FirmwareFileSystem.h>
 | 
						|
#include <Common/FirmwareVolumeHeader.h>
 | 
						|
#include <Common/FirmwareVolumeImageFormat.h>
 | 
						|
 | 
						|
#include "ParseInf.h"
 | 
						|
#include "Compress.h"
 | 
						|
#include "EfiCustomizedCompress.h"
 | 
						|
#include "Crc32.h"
 | 
						|
#include "GenFfsFile.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) EfiCompress;
 | 
						|
 | 
						|
  } else if (strcmpi (Type, "LZH") == 0) {
 | 
						|
    //
 | 
						|
    // EFI stardard compression (LZH)
 | 
						|
    //
 | 
						|
    CompressionType   = EFI_STANDARD_COMPRESSION;
 | 
						|
    CompressFunction  = (COMPRESS_FUNCTION) EfiCompress;
 | 
						|
 | 
						|
  } 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
 | 
						|
      //
 | 
						|
#ifdef __GNUC__
 | 
						|
      {
 | 
						|
        char CommandLine[1000];
 | 
						|
        sprintf(CommandLine, "%s %s", ToolName, ToolArgumentsArray);
 | 
						|
        returnint = system(CommandLine);
 | 
						|
      }
 | 
						|
#else
 | 
						|
      returnint = _spawnv (_P_WAIT, ToolName, ToolArgumentsArray);
 | 
						|
#endif
 | 
						|
      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;
 | 
						|
  EFI_FFS_FILE_TAIL       TailValue;
 | 
						|
 | 
						|
  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;
 | 
						|
      }
 | 
						|
    } 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 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_SUPORTED
 | 
						|
    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) {
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    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_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) {
 | 
						|
      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_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 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)
 | 
						|
        );
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // 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;
 | 
						|
}
 |