3 Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Process HII package files to generate HII package list binary file or PE/COFF
19 resource script file (i.e. .rc file).
29 #include "EfiUtilityMsgs.h"
32 #define UTILITY_VERSION "v1.0"
33 #define UTILITY_NAME "HiiPack"
37 // Define HII resource section type and name
39 #define HII_RESOURCE_TYPE "HII"
40 #define HII_RESOURCE_NAME 1
43 // We'll store lists of file names from the command line in
44 // a linked list of these
46 typedef struct _FILE_NAME_LIST
{
47 struct _FILE_NAME_LIST
*Next
;
48 UINT8 FileName
[MAX_PATH
];
55 // Create some defines for the different operation modes supported by this utility
57 #define MODE_CREATE_HII_RESOURCE_FILE 0x0001
58 #define MODE_CREATE_HII_PACKAGE_LIST 0x0002
61 // Here's all our globals.
64 FILE_NAME_LIST
*PackageFile
; // all include paths to search
65 FILE_NAME_LIST
*LastPackageFile
;
66 UINT8 PackageListFileName
[MAX_PATH
]; // Output package list file name
67 UINT8 ResourceFileName
[MAX_PATH
]; // Output HII resource file name
68 EFI_GUID Guid
; // Guid specified on command line
69 BOOLEAN GuidSpecified
;
71 UINT32 Mode
; // Mode this utility is operating in
104 CreateResourceScript (
105 char *OutputFileName
,
106 EFI_GUID
*PackageListGuid
,
107 FILE_NAME_LIST
*PackageFiles
113 char *OutputFileName
,
114 EFI_GUID
*PackageListGuid
,
115 FILE_NAME_LIST
*PackageFiles
127 Call the routine to parse the command-line options, then process the file.
131 Standard C main() argc and argv.
143 // Set the utility name for error reporting purposes
145 SetUtilityName (UTILITY_NAME
);
148 // Process the command-line arguments
150 Status
= ProcessArgs (Argc
, Argv
);
151 if (Status
!= STATUS_SUCCESS
) {
156 // Switch based on args
158 if (mGlobals
.Mode
& MODE_CREATE_HII_RESOURCE_FILE
) {
159 CreateResourceScript (mGlobals
.ResourceFileName
, &mGlobals
.Guid
, mGlobals
.PackageFile
);
162 if (mGlobals
.Mode
& MODE_CREATE_HII_PACKAGE_LIST
) {
163 CreatePackageList (mGlobals
.PackageListFileName
, &mGlobals
.Guid
, mGlobals
.PackageFile
);
168 return GetUtilityStatus ();
171 /******************************************************************************/
172 static const char *gRcFileHeader
[] = {
174 "// DO NOT EDIT -- auto-generated file",
176 "// This file is generated by the hiipack utility",
183 CreateResourceScript (
184 char *OutputFileName
,
185 EFI_GUID
*PackageListGuid
,
186 FILE_NAME_LIST
*PackageFiles
192 Given a linked list of HII package files, walk the list to
193 process them and create a single HII resource script file.
197 OutputFileName - name of output HII resource script file to create
198 PackageListGuid - the specified package list GUID
199 PackageFiles - linked list of HII package files to process
203 STATUS_SUCCESS - if successful
204 STATUS_ERROR - otherwise
211 UINT32 PackageListLen
;
214 FILE_NAME_LIST
*Package
;
217 // If no input HII pack files, then why are we here? Should have been caught when
218 // args were processed though.
220 if (PackageFiles
== NULL
) {
221 Error (NULL
, 0, 0, "no input package file(s) specified", NULL
);
226 Status
= STATUS_ERROR
;
229 // Open the output file for writing
231 if ((OutFptr
= fopen (OutputFileName
, "w")) == NULL
) {
232 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
239 for (Index
= 0; gRcFileHeader
[Index
] != NULL
; Index
++) {
240 fprintf (OutFptr
, "%s\n", gRcFileHeader
[Index
]);
244 // Write nameID and typeID
246 fprintf (OutFptr
, "\n");
247 fprintf (OutFptr
, "%d %s\n", HII_RESOURCE_NAME
, HII_RESOURCE_TYPE
);
248 fprintf (OutFptr
, "{\n");
251 // Prepare package list
253 PackageListLen
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
254 Package
= PackageFiles
;
255 while (Package
!= NULL
) {
256 PackageListLen
+= Package
->Length
;
257 Package
= Package
->Next
;
260 // Inlucde the length of EFI_HII_PACKAGE_END
262 PackageListLen
+= sizeof (EFI_HII_PACKAGE_HEADER
);
264 Buffer
= (UINT8
*) malloc (PackageListLen
);
265 if (Buffer
== NULL
) {
266 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
269 PackageList
= Buffer
;
271 memcpy (Buffer
, PackageListGuid
, sizeof (EFI_GUID
));
272 Buffer
+= sizeof (EFI_GUID
);
273 memcpy (Buffer
, &PackageListLen
, sizeof (UINT32
));
274 Buffer
+= sizeof (UINT32
);
276 Package
= PackageFiles
;
277 while (Package
!= NULL
) {
278 memcpy (Buffer
, Package
->Data
, Package
->Length
);
279 Buffer
+= Package
->Length
;
280 Package
= Package
->Next
;
283 // Append EFI_HII_PACKAGE_END
285 ((EFI_HII_PACKAGE_HEADER
*) Buffer
)->Type
= EFI_HII_PACKAGE_END
;
286 ((EFI_HII_PACKAGE_HEADER
*) Buffer
)->Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
291 DumpRawBytes (OutFptr
, PackageList
, PackageListLen
, 2);
296 fprintf (OutFptr
, "}\n");
298 Status
= STATUS_SUCCESS
;
301 if (OutFptr
!= NULL
) {
311 char *OutputFileName
,
312 EFI_GUID
*PackageListGuid
,
313 FILE_NAME_LIST
*PackageFiles
319 Given a linked list of HII package files, walk the list to
320 process them and create a binary HII package list file.
324 OutputFileName - name of output HII package list file to create
325 PackageListGuid - the specified package list GUID
326 PackageFiles - linked list of HII package files to process
330 STATUS_SUCCESS - if successful
331 STATUS_ERROR - otherwise
336 UINT32 PackageListLen
;
337 FILE_NAME_LIST
*Package
;
339 if (OutputFileName
== NULL
|| PackageListGuid
== NULL
|| PackageFiles
== NULL
) {
344 // Open the output file for writing
346 if ((OutFptr
= fopen (OutputFileName
, "wb")) == NULL
) {
347 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
352 // Write package list header
354 PackageListLen
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
355 Package
= PackageFiles
;
356 while (Package
!= NULL
) {
357 PackageListLen
+= Package
->Length
;
358 Package
= Package
->Next
;
360 fwrite (PackageListGuid
, sizeof (UINT8
), sizeof (EFI_GUID
), OutFptr
);
361 fwrite (&PackageListLen
, sizeof (UINT8
), sizeof (UINT32
), OutFptr
);
366 Package
= PackageFiles
;
367 while (Package
!= NULL
) {
368 fwrite (Package
->Data
, sizeof (UINT8
), Package
->Length
, OutFptr
);
369 Package
= Package
->Next
;
373 if (OutFptr
!= NULL
) {
377 return STATUS_SUCCESS
;
389 Free up an memory we allocated so we can exit cleanly
397 FILE_NAME_LIST
*Next
;
400 // Free up input package file names
402 while (mGlobals
.PackageFile
!= NULL
) {
403 Next
= mGlobals
.PackageFile
->Next
;
404 if (mGlobals
.PackageFile
->Data
!= NULL
) {
405 free (mGlobals
.PackageFile
->Data
);
407 free (mGlobals
.PackageFile
);
408 mGlobals
.PackageFile
= Next
;
424 Dump buffer data into output file.
428 OutFptr - FILE pointer to output file.
429 Buffer - the buffer to dump
430 Count - number of bytes to dump
431 Indent - indent at each line start
443 Ptr16
= (UINT16
*) Buffer
;
444 Count2
= Count
- (Count
& 0x1);
446 for (Counter
= 0; Counter
< Count2
; Counter
+= 2) {
447 if ((Counter
& 0xF) == 0) {
449 fprintf (OutFptr
, "%*c", Indent
, ' ');
451 fprintf (OutFptr
, "\n%*c", Indent
, ' ');
455 fprintf (OutFptr
, "0x%04X, ", (unsigned int) *Ptr16
);
460 // Handle the last byte
462 if ((Count
& 0x1) != 0) {
463 if ((Counter
& 0xF) == 0) {
465 fprintf (OutFptr
, "%*c", Indent
, ' ');
467 fprintf (OutFptr
, "\n%*c", Indent
, ' ');
471 fprintf (OutFptr
, "0x%04X, ", (unsigned int) (*Ptr16
& 0xff));
474 fprintf (OutFptr
, "\n");
480 FILE_NAME_LIST
*NameList
486 Process the command line arguments
490 NameList - the FILE_NAME_LIST linked list node
494 STATUS_SUCCESS - if successful
495 STATUS_ERROR - otherwise
503 EFI_HII_PACKAGE_HEADER
*PackageHeader
;
504 EFI_IFR_FORM_SET
*FormSet
;
506 Status
= STATUS_SUCCESS
;
507 if (NameList
== NULL
) {
512 // Try to open the package file
514 if ((InFptr
= fopen (NameList
->FileName
, "rb")) == NULL
) {
515 Error (NULL
, 0, 0, NameList
->FileName
, "failed to open input file for read");
520 // Get the file size, then allocate a buffer and read in the file contents.
522 fseek (InFptr
, 0, SEEK_END
);
523 BufferSize
= (UINT32
) ftell (InFptr
);
524 fseek (InFptr
, 0, SEEK_SET
);
525 Buffer
= (UINT8
*) malloc (BufferSize
);
526 if (Buffer
== NULL
) {
527 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
531 if (fread (Buffer
, sizeof (UINT8
), BufferSize
, InFptr
) != BufferSize
) {
532 Error (NULL
, 0, 0, NameList
->FileName
, "error reading file contents");
533 Status
= STATUS_ERROR
;
537 NameList
->Length
= BufferSize
;
538 NameList
->Data
= Buffer
;
540 PackageHeader
= (EFI_HII_PACKAGE_HEADER
*) Buffer
;
541 NameList
->PackageType
= PackageHeader
->Type
;
543 if (!mGlobals
.GuidSpecified
&& NameList
->PackageType
== EFI_HII_PACKAGE_FORMS
) {
544 FormSet
= (EFI_IFR_FORM_SET
*) (Buffer
+ sizeof (EFI_HII_PACKAGE_HEADER
));
545 memcpy (&mGlobals
.Guid
, &FormSet
->Guid
, sizeof (EFI_GUID
));
546 mGlobals
.GuidSpecified
= TRUE
;
566 Process the command line arguments
570 As per standard C main()
574 STATUS_SUCCESS - if successful
575 STATUS_ERROR - otherwise
579 FILE_NAME_LIST
*NewList
;
582 Status
= STATUS_SUCCESS
;
583 memset ((void *) &mGlobals
, 0, sizeof (mGlobals
));
596 if (_stricmp (Argv
[0], "-h") == 0 || _stricmp (Argv
[0], "-?") == 0) {
602 // Process until no more args.
605 if (_stricmp (Argv
[0], "-rc") == 0) {
610 Error (UTILITY_NAME
, 0, 0, "mising HII resource file name", NULL
);
611 Status
= STATUS_ERROR
;
615 strcpy (mGlobals
.ResourceFileName
, Argv
[0]);
616 mGlobals
.Mode
|= MODE_CREATE_HII_RESOURCE_FILE
;
618 } else if (_stricmp (Argv
[0], "-hii") == 0) {
623 Error (UTILITY_NAME
, 0, 0, "mising HII package list file name", NULL
);
624 Status
= STATUS_ERROR
;
628 strcpy (mGlobals
.PackageListFileName
, Argv
[0]);
629 mGlobals
.Mode
|= MODE_CREATE_HII_PACKAGE_LIST
;
631 } else if (_stricmp (Argv
[0], "-g") == 0) {
636 Error (UTILITY_NAME
, 0, 0, "mising package list GUID", NULL
);
637 Status
= STATUS_ERROR
;
641 Status
= StringToGuid (Argv
[0], &mGlobals
.Guid
);
642 if (Status
!= STATUS_SUCCESS
) {
645 mGlobals
.GuidSpecified
= TRUE
;
649 // This is a package file
651 NewList
= malloc (sizeof (FILE_NAME_LIST
));
652 if (NewList
== NULL
) {
653 Error (UTILITY_NAME
, 0, 0, "memory allocation failure", NULL
);
654 Status
= STATUS_ERROR
;
658 memset (NewList
, 0, sizeof (FILE_NAME_LIST
));
659 strcpy (NewList
->FileName
, Argv
[0]);
661 if (mGlobals
.PackageFile
== NULL
) {
662 mGlobals
.PackageFile
= NewList
;
664 mGlobals
.LastPackageFile
->Next
= NewList
;
666 mGlobals
.LastPackageFile
= NewList
;
668 Status
= LoadPackage (NewList
);
669 if (Status
!= STATUS_SUCCESS
) {
678 if (!mGlobals
.GuidSpecified
) {
679 Error (UTILITY_NAME
, 0, 0, "please specify HII pakcage list GUID", NULL
);
680 Status
= STATUS_ERROR
;
684 if (Status
!= STATUS_SUCCESS
) {
700 Print usage information for this utility.
713 const char *Str
[] = {
714 UTILITY_NAME
" "UTILITY_VERSION
" - UEFI HII Package List Utility",
715 " Copyright (C), 2008 Intel Corporation",
717 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
718 " Built from "UTILITY_BUILD
", project of "UTILITY_VENDOR
,
722 " "UTILITY_NAME
" [OPTION] PACKAGE [PACKAGE [...]]",
724 " Merge HII package files into a single HII Package List.",
726 " -rc FileName write output to PE/COFF Resource Script file",
727 " -hii FileName write output to binary Package List file",
728 " -g GUID use GUID for the HII Package List Guid",
730 "PACKAGE is the raw binary HII package file generated by StrGather or",
731 "VfrCompiler which named as *.hpk. For example, merge a Form package and",
732 "a String package into one HII package list:",
733 " \""UTILITY_NAME
" -rc Sample.rc -hii Sample.hii \\",
734 " -g 12345678-1234-1234-1234-123456789abc Vfr.hpk Strings.hpk\"",
737 for (i
= 0; Str
[i
] != NULL
; i
++) {
738 fprintf (stdout
, "%s\n", Str
[i
]);