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