+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
-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
- HiiPack.c\r
-\r
-Abstract:\r
-\r
- Process HII package files to generate HII package list binary file or PE/COFF\r
- resource script file (i.e. .rc file).\r
-\r
---*/\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#include "Tiano.h"\r
-#include "EfiHii.h"\r
-\r
-#include "EfiUtilityMsgs.h"\r
-#include "ParseInf.h"\r
-\r
-#define UTILITY_VERSION "v1.0"\r
-#define UTILITY_NAME "HiiPack"\r
-#define MAX_PATH 260\r
-\r
-//\r
-// Define HII resource section type and name\r
-//\r
-#define HII_RESOURCE_TYPE "HII"\r
-#define HII_RESOURCE_NAME 1\r
-\r
-//\r
-// We'll store lists of file names from the command line in\r
-// a linked list of these\r
-//\r
-typedef struct _FILE_NAME_LIST {\r
- struct _FILE_NAME_LIST *Next;\r
- UINT8 FileName[MAX_PATH];\r
- UINT32 PackageType;\r
- UINT32 Length;\r
- UINT8 *Data;\r
-} FILE_NAME_LIST;\r
-\r
-//\r
-// Create some defines for the different operation modes supported by this utility\r
-//\r
-#define MODE_CREATE_HII_RESOURCE_FILE 0x0001\r
-#define MODE_CREATE_HII_PACKAGE_LIST 0x0002\r
-\r
-//\r
-// Here's all our globals.\r
-//\r
-static struct {\r
- FILE_NAME_LIST *PackageFile; // all include paths to search\r
- FILE_NAME_LIST *LastPackageFile;\r
- UINT8 PackageListFileName[MAX_PATH]; // Output package list file name\r
- UINT8 ResourceFileName[MAX_PATH]; // Output HII resource file name\r
- EFI_GUID Guid; // Guid specified on command line\r
- BOOLEAN GuidSpecified;\r
- BOOLEAN Verbose;\r
- UINT32 Mode; // Mode this utility is operating in\r
-} mGlobals;\r
-\r
-static\r
-void\r
-Usage (\r
- VOID\r
- );\r
-\r
-static\r
-STATUS\r
-ProcessArgs (\r
- int Argc,\r
- char *Argv[]\r
- );\r
-\r
-static\r
-void\r
-FreeGlobals (\r
- VOID\r
- );\r
-\r
-static\r
-void\r
-DumpRawBytes (\r
- FILE *OutFptr,\r
- UINT8 *Buffer,\r
- int Count,\r
- int Indent\r
- );\r
-\r
-static\r
-STATUS\r
-CreateResourceScript (\r
- char *OutputFileName,\r
- EFI_GUID *PackageListGuid,\r
- FILE_NAME_LIST *PackageFiles\r
- );\r
-\r
-static\r
-STATUS\r
-CreatePackageList (\r
- char *OutputFileName,\r
- EFI_GUID *PackageListGuid,\r
- FILE_NAME_LIST *PackageFiles\r
- );\r
-\r
-int\r
-main (\r
- int Argc,\r
- char *Argv[]\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Call the routine to parse the command-line options, then process the file.\r
-\r
-Arguments:\r
-\r
- Standard C main() argc and argv.\r
-\r
-Returns:\r
-\r
- 0 if successful\r
- nonzero otherwise\r
-\r
---*/\r
-{\r
- STATUS Status;\r
-\r
- //\r
- // Set the utility name for error reporting purposes\r
- //\r
- SetUtilityName (UTILITY_NAME);\r
-\r
- //\r
- // Process the command-line arguments\r
- //\r
- Status = ProcessArgs (Argc, Argv);\r
- if (Status != STATUS_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Switch based on args\r
- //\r
- if (mGlobals.Mode & MODE_CREATE_HII_RESOURCE_FILE) {\r
- CreateResourceScript (mGlobals.ResourceFileName, &mGlobals.Guid, mGlobals.PackageFile);\r
- }\r
-\r
- if (mGlobals.Mode & MODE_CREATE_HII_PACKAGE_LIST) {\r
- CreatePackageList (mGlobals.PackageListFileName, &mGlobals.Guid, mGlobals.PackageFile);\r
- }\r
-\r
- FreeGlobals ();\r
-\r
- return GetUtilityStatus ();\r
-}\r
-\r
-/******************************************************************************/\r
-static const char *gRcFileHeader[] = {\r
- "//",\r
- "// DO NOT EDIT -- auto-generated file",\r
- "//",\r
- "// This file is generated by the hiipack utility",\r
- "//",\r
- NULL\r
-};\r
-\r
-static\r
-STATUS\r
-CreateResourceScript (\r
- char *OutputFileName,\r
- EFI_GUID *PackageListGuid,\r
- FILE_NAME_LIST *PackageFiles\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Given a linked list of HII package files, walk the list to\r
- process them and create a single HII resource script file.\r
-\r
-Arguments:\r
-\r
- OutputFileName - name of output HII resource script file to create\r
- PackageListGuid - the specified package list GUID\r
- PackageFiles - linked list of HII package files to process\r
-\r
-Returns:\r
-\r
- STATUS_SUCCESS - if successful\r
- STATUS_ERROR - otherwise\r
-\r
---*/\r
-{\r
- STATUS Status;\r
- UINT8 *PackageList;\r
- UINT8 *Buffer;\r
- UINT32 PackageListLen;\r
- FILE *OutFptr;\r
- UINTN Index;\r
- FILE_NAME_LIST *Package;\r
-\r
- //\r
- // If no input HII pack files, then why are we here? Should have been caught when\r
- // args were processed though.\r
- //\r
- if (PackageFiles == NULL) {\r
- Error (NULL, 0, 0, "no input package file(s) specified", NULL);\r
- return STATUS_ERROR;\r
- }\r
-\r
- OutFptr = NULL;\r
- Status = STATUS_ERROR;\r
-\r
- //\r
- // Open the output file for writing\r
- //\r
- if ((OutFptr = fopen (OutputFileName, "w")) == NULL) {\r
- Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");\r
- goto Done;\r
- }\r
-\r
- //\r
- // Write file header\r
- //\r
- for (Index = 0; gRcFileHeader[Index] != NULL; Index++) {\r
- fprintf (OutFptr, "%s\n", gRcFileHeader[Index]);\r
- }\r
-\r
- //\r
- // Write nameID and typeID\r
- //\r
- fprintf (OutFptr, "\n");\r
- fprintf (OutFptr, "%d %s\n", HII_RESOURCE_NAME, HII_RESOURCE_TYPE);\r
- fprintf (OutFptr, "{\n");\r
-\r
- //\r
- // Prepare package list\r
- //\r
- PackageListLen = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
- Package = PackageFiles;\r
- while (Package != NULL) {\r
- PackageListLen += Package->Length;\r
- Package = Package->Next;\r
- }\r
- //\r
- // Inlucde the length of EFI_HII_PACKAGE_END\r
- //\r
- PackageListLen += sizeof (EFI_HII_PACKAGE_HEADER);\r
-\r
- Buffer = (UINT8 *) malloc (PackageListLen);\r
- if (Buffer == NULL) {\r
- Error (NULL, 0, 0, "memory allocation failure", NULL);\r
- goto Done;\r
- }\r
- PackageList = Buffer;\r
-\r
- memcpy (Buffer, PackageListGuid, sizeof (EFI_GUID));\r
- Buffer += sizeof (EFI_GUID);\r
- memcpy (Buffer, &PackageListLen, sizeof (UINT32));\r
- Buffer += sizeof (UINT32);\r
-\r
- Package = PackageFiles;\r
- while (Package != NULL) {\r
- memcpy (Buffer, Package->Data, Package->Length);\r
- Buffer += Package->Length;\r
- Package = Package->Next;\r
- }\r
- //\r
- // Append EFI_HII_PACKAGE_END\r
- //\r
- ((EFI_HII_PACKAGE_HEADER *) Buffer)->Type = EFI_HII_PACKAGE_END;\r
- ((EFI_HII_PACKAGE_HEADER *) Buffer)->Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
-\r
- //\r
- // Dump package list\r
- //\r
- DumpRawBytes (OutFptr, PackageList, PackageListLen, 2);\r
-\r
- //\r
- // Write file tail\r
- //\r
- fprintf (OutFptr, "}\n");\r
-\r
- Status = STATUS_SUCCESS;\r
-\r
-Done:\r
- if (OutFptr != NULL) {\r
- fclose (OutFptr);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-static\r
-STATUS\r
-CreatePackageList (\r
- char *OutputFileName,\r
- EFI_GUID *PackageListGuid,\r
- FILE_NAME_LIST *PackageFiles\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Given a linked list of HII package files, walk the list to\r
- process them and create a binary HII package list file.\r
-\r
-Arguments:\r
-\r
- OutputFileName - name of output HII package list file to create\r
- PackageListGuid - the specified package list GUID\r
- PackageFiles - linked list of HII package files to process\r
-\r
-Returns:\r
-\r
- STATUS_SUCCESS - if successful\r
- STATUS_ERROR - otherwise\r
-\r
---*/\r
-{\r
- FILE *OutFptr;\r
- UINT32 PackageListLen;\r
- FILE_NAME_LIST *Package;\r
-\r
- if (OutputFileName == NULL || PackageListGuid == NULL || PackageFiles == NULL) {\r
- return STATUS_ERROR;\r
- }\r
-\r
- //\r
- // Open the output file for writing\r
- //\r
- if ((OutFptr = fopen (OutputFileName, "wb")) == NULL) {\r
- Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");\r
- goto Done;\r
- }\r
-\r
- //\r
- // Write package list header\r
- //\r
- PackageListLen = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
- Package = PackageFiles;\r
- while (Package != NULL) {\r
- PackageListLen += Package->Length;\r
- Package = Package->Next;\r
- }\r
- fwrite (PackageListGuid, sizeof (UINT8), sizeof (EFI_GUID), OutFptr);\r
- fwrite (&PackageListLen, sizeof (UINT8), sizeof (UINT32), OutFptr);\r
-\r
- //\r
- // Write packages\r
- //\r
- Package = PackageFiles;\r
- while (Package != NULL) {\r
- fwrite (Package->Data, sizeof (UINT8), Package->Length, OutFptr);\r
- Package = Package->Next;\r
- }\r
-\r
-Done:\r
- if (OutFptr != NULL) {\r
- fclose (OutFptr);\r
- }\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-static\r
-void\r
-FreeGlobals (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Free up an memory we allocated so we can exit cleanly\r
-\r
-Arguments:\r
-\r
-Returns: NA\r
-\r
---*/\r
-{\r
- FILE_NAME_LIST *Next;\r
-\r
- //\r
- // Free up input package file names\r
- //\r
- while (mGlobals.PackageFile != NULL) {\r
- Next = mGlobals.PackageFile->Next;\r
- if (mGlobals.PackageFile->Data != NULL) {\r
- free (mGlobals.PackageFile->Data);\r
- }\r
- free (mGlobals.PackageFile);\r
- mGlobals.PackageFile = Next;\r
- }\r
-}\r
-\r
-static\r
-void\r
-DumpRawBytes (\r
- FILE *OutFptr,\r
- UINT8 *Buffer,\r
- int Count,\r
- int Indent\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Dump buffer data into output file.\r
-\r
-Arguments:\r
-\r
- OutFptr - FILE pointer to output file.\r
- Buffer - the buffer to dump\r
- Count - number of bytes to dump\r
- Indent - indent at each line start\r
-\r
-Returns:\r
-\r
- Nothing.\r
-\r
---*/\r
-{\r
- int Counter;\r
- int Count2;\r
- UINT16 *Ptr16;\r
-\r
- Ptr16 = (UINT16 *) Buffer;\r
- Count2 = Count - (Count & 0x1);\r
-\r
- for (Counter = 0; Counter < Count2; Counter += 2) {\r
- if ((Counter & 0xF) == 0) {\r
- if (Counter == 0) {\r
- fprintf (OutFptr, "%*c", Indent, ' ');\r
- } else {\r
- fprintf (OutFptr, "\n%*c", Indent, ' ');\r
- }\r
- }\r
-\r
- fprintf (OutFptr, "0x%04X, ", (unsigned int) *Ptr16);\r
- Ptr16++;\r
- }\r
-\r
- //\r
- // Handle the last byte\r
- //\r
- if ((Count & 0x1) != 0) {\r
- if ((Counter & 0xF) == 0) {\r
- if (Counter == 0) {\r
- fprintf (OutFptr, "%*c", Indent, ' ');\r
- } else {\r
- fprintf (OutFptr, "\n%*c", Indent, ' ');\r
- }\r
- }\r
-\r
- fprintf (OutFptr, "0x%04X, ", (unsigned int) (*Ptr16 & 0xff));\r
- }\r
-\r
- fprintf (OutFptr, "\n");\r
-}\r
-\r
-static\r
-STATUS\r
-LoadPackage (\r
- FILE_NAME_LIST *NameList\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process the command line arguments\r
-\r
-Arguments:\r
-\r
- NameList - the FILE_NAME_LIST linked list node\r
-\r
-Returns:\r
-\r
- STATUS_SUCCESS - if successful\r
- STATUS_ERROR - otherwise\r
-\r
---*/\r
-{\r
- STATUS Status;\r
- FILE *InFptr;\r
- UINT32 BufferSize;\r
- UINT8 *Buffer;\r
- EFI_HII_PACKAGE_HEADER *PackageHeader;\r
- EFI_IFR_FORM_SET *FormSet;\r
-\r
- Status = STATUS_SUCCESS;\r
- if (NameList == NULL) {\r
- return STATUS_ERROR;\r
- }\r
-\r
- //\r
- // Try to open the package file\r
- //\r
- if ((InFptr = fopen (NameList->FileName, "rb")) == NULL) {\r
- Error (NULL, 0, 0, NameList->FileName, "failed to open input file for read");\r
- return STATUS_ERROR;\r
- }\r
-\r
- //\r
- // Get the file size, then allocate a buffer and read in the file contents.\r
- //\r
- fseek (InFptr, 0, SEEK_END);\r
- BufferSize = (UINT32) ftell (InFptr);\r
- fseek (InFptr, 0, SEEK_SET);\r
- Buffer = (UINT8 *) malloc (BufferSize);\r
- if (Buffer == NULL) {\r
- Error (NULL, 0, 0, "memory allocation failure", NULL);\r
- goto Done;\r
- }\r
-\r
- if (fread (Buffer, sizeof (UINT8), BufferSize, InFptr) != BufferSize) {\r
- Error (NULL, 0, 0, NameList->FileName, "error reading file contents");\r
- Status = STATUS_ERROR;\r
- goto Done;\r
- }\r
-\r
- NameList->Length = BufferSize;\r
- NameList->Data = Buffer;\r
-\r
- PackageHeader = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
- NameList->PackageType = PackageHeader->Type;\r
-\r
- if (!mGlobals.GuidSpecified && NameList->PackageType == EFI_HII_PACKAGE_FORMS) {\r
- FormSet = (EFI_IFR_FORM_SET *) (Buffer + sizeof (EFI_HII_PACKAGE_HEADER));\r
- memcpy (&mGlobals.Guid, &FormSet->Guid, sizeof (EFI_GUID));\r
- mGlobals.GuidSpecified = TRUE;\r
- }\r
-\r
-Done:\r
- fclose (InFptr);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-static\r
-STATUS\r
-ProcessArgs (\r
- int Argc,\r
- char *Argv[]\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process the command line arguments\r
-\r
-Arguments:\r
-\r
- As per standard C main()\r
-\r
-Returns:\r
-\r
- STATUS_SUCCESS - if successful\r
- STATUS_ERROR - otherwise\r
-\r
---*/\r
-{\r
- FILE_NAME_LIST *NewList;\r
- STATUS Status;\r
-\r
- Status = STATUS_SUCCESS;\r
- memset ((void *) &mGlobals, 0, sizeof (mGlobals));\r
-\r
- //\r
- // Skip program name\r
- //\r
- Argc--;\r
- Argv++;\r
-\r
- if (Argc == 0) {\r
- Usage ();\r
- return STATUS_ERROR;\r
- }\r
-\r
- if (_stricmp (Argv[0], "-h") == 0 || _stricmp (Argv[0], "-?") == 0) {\r
- Usage ();\r
- return STATUS_ERROR;\r
- }\r
-\r
- //\r
- // Process until no more args.\r
- //\r
- while (Argc > 0) {\r
- if (_stricmp (Argv[0], "-rc") == 0) {\r
- Argc--;\r
- Argv++;\r
-\r
- if (Argc == 0) {\r
- Error (UTILITY_NAME, 0, 0, "mising HII resource file name", NULL);\r
- Status = STATUS_ERROR;\r
- goto Done;\r
- }\r
-\r
- strcpy (mGlobals.ResourceFileName, Argv[0]);\r
- mGlobals.Mode |= MODE_CREATE_HII_RESOURCE_FILE;\r
-\r
- } else if (_stricmp (Argv[0], "-hii") == 0) {\r
- Argc--;\r
- Argv++;\r
-\r
- if (Argc == 0) {\r
- Error (UTILITY_NAME, 0, 0, "mising HII package list file name", NULL);\r
- Status = STATUS_ERROR;\r
- goto Done;\r
- }\r
-\r
- strcpy (mGlobals.PackageListFileName, Argv[0]);\r
- mGlobals.Mode |= MODE_CREATE_HII_PACKAGE_LIST;\r
-\r
- } else if (_stricmp (Argv[0], "-g") == 0) {\r
- Argc--;\r
- Argv++;\r
-\r
- if (Argc == 0) {\r
- Error (UTILITY_NAME, 0, 0, "mising package list GUID", NULL);\r
- Status = STATUS_ERROR;\r
- goto Done;\r
- }\r
-\r
- Status = StringToGuid (Argv[0], &mGlobals.Guid);\r
- if (Status != STATUS_SUCCESS) {\r
- goto Done;\r
- }\r
- mGlobals.GuidSpecified = TRUE;\r
-\r
- } else {\r
- //\r
- // This is a package file\r
- //\r
- NewList = malloc (sizeof (FILE_NAME_LIST));\r
- if (NewList == NULL) {\r
- Error (UTILITY_NAME, 0, 0, "memory allocation failure", NULL);\r
- Status = STATUS_ERROR;\r
- goto Done;\r
- }\r
-\r
- memset (NewList, 0, sizeof (FILE_NAME_LIST));\r
- strcpy (NewList->FileName, Argv[0]);\r
-\r
- if (mGlobals.PackageFile == NULL) {\r
- mGlobals.PackageFile = NewList;\r
- } else {\r
- mGlobals.LastPackageFile->Next = NewList;\r
- }\r
- mGlobals.LastPackageFile = NewList;\r
-\r
- Status = LoadPackage (NewList);\r
- if (Status != STATUS_SUCCESS) {\r
- goto Done;\r
- }\r
- }\r
-\r
- Argc--;\r
- Argv++;\r
- }\r
-\r
- if (!mGlobals.GuidSpecified) {\r
- Error (UTILITY_NAME, 0, 0, "please specify HII pakcage list GUID", NULL);\r
- Status = STATUS_ERROR;\r
- }\r
-\r
-Done:\r
- if (Status != STATUS_SUCCESS) {\r
- FreeGlobals ();\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-static\r
-void\r
-Usage (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Print usage information for this utility.\r
-\r
-Arguments:\r
-\r
- None.\r
-\r
-Returns:\r
-\r
- Nothing.\r
-\r
---*/\r
-{\r
- int i;\r
- const char *Str[] = {\r
- UTILITY_NAME" "UTILITY_VERSION" - UEFI HII Package List Utility",\r
- " Copyright (C), 2008 Intel Corporation",\r
- \r
-#if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )\r
- " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,\r
-#endif\r
- "",\r
- "Usage:",\r
- " "UTILITY_NAME" [OPTION] PACKAGE [PACKAGE [...]]",\r
- "Description:",\r
- " Merge HII package files into a single HII Package List.",\r
- "Options:",\r
- " -rc FileName write output to PE/COFF Resource Script file",\r
- " -hii FileName write output to binary Package List file",\r
- " -g GUID use GUID for the HII Package List Guid",\r
- "",\r
- "PACKAGE is the raw binary HII package file generated by StrGather or",\r
- "VfrCompiler which named as *.hpk. For example, merge a Form package and",\r
- "a String package into one HII package list:",\r
- " \""UTILITY_NAME" -rc Sample.rc -hii Sample.hii \\",\r
- " -g 12345678-1234-1234-1234-123456789abc Vfr.hpk Strings.hpk\"",\r
- NULL\r
- };\r
- for (i = 0; Str[i] != NULL; i++) {\r
- fprintf (stdout, "%s\n", Str[i]);\r
- }\r
-}\r