3 Copyright (c) 2004 - 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 export and pack files and create HII export files,
19 dumps, or variable defaults packs.
29 #include "EfiUtilityMsgs.h"
31 #include "EfiInternalFormRepresentation.h"
35 #include "StringParse.h"
37 #define UTILITY_VERSION "v1.0"
38 #define UTILITY_NAME "HiiPack"
42 // We may have to create an empty IFR formset to provide a GUID for an HII
43 // export pack. Create a structure definition to make it easier.
48 EFI_HII_IFR_PACK PackHeader
;
49 EFI_IFR_FORM_SET Formset
;
50 EFI_IFR_END_FORM_SET EndFormset
;
55 // We'll store lists of file names from the command line in
56 // a linked list of these
58 typedef struct _FILE_NAME_LIST
{
59 struct _FILE_NAME_LIST
*Next
;
60 UINT8 FileName
[MAX_PATH
];
61 int Tag
; // used for whatever
65 // When merging HII export packs, we save HII data table headers in a linked
68 typedef struct _DATA_TABLE_HEADER_LIST
{
69 struct _DATA_TABLE_HEADER_LIST
*Next
;
70 EFI_HII_DATA_TABLE DataTableHeader
;
71 } DATA_TABLE_HEADER_LIST
;
73 // Create some defines for the different operation modes supported by this utility
75 #define MODE_CREATE_HII_EXPORT 1
76 #define MODE_MERGE_HII_EXPORTS 2
77 #define MODE_EMIT_DEFAULTS 3
78 #define MODE_DUMP_HII_EXPORT 4
80 // Here's all our globals.
83 FILE_NAME_LIST
*PackFileNames
; // Input HII pack file names
84 FILE_NAME_LIST
*HiiExportFileNames
; // Input files when merging
85 CHAR8 OutputFileName
[MAX_PATH
]; // Output dump file
86 BOOLEAN MfgFlag
; // From -mfg command line arg
87 BOOLEAN NoEmptyVarPacks
; // From -noemptyvarpacks command line arg
88 BOOLEAN NoVarPacks
; // From -novarpacks command line arg
89 EFI_GUID Guid
; // Guid specified on command line
90 BOOLEAN GuidSpecified
;
91 BOOLEAN DumpStrings
; // In dump mode, dump string data
93 int Mode
; // Mode this utility is operating in
112 char *HiiExportFileName
,
129 EFI_HII_STRING_PACK
*Pack
,
138 EFI_HII_VARIABLE_PACK
*Pack
,
166 EFI_HII_IFR_PACK
*Pack
,
180 EFI_HII_STRING_PACK
*PackHeader
185 ProcessHiiExportFile (
193 FILE_NAME_LIST
*FileName
199 FILE_NAME_LIST
*HiiExportFiles
,
207 FILE_NAME_LIST
*HiiExportFiles
,
208 char *OutputFileName
,
228 char *OutputFileName
,
229 EFI_GUID
*DummyFormsetGuid
,
230 FILE_NAME_LIST
*PackFiles
,
243 Call the routine to parse the command-line options, then process the file.
247 Standard C main() argc and argv.
255 // GC_TODO: Argc - add argument and description to function comment
256 // GC_TODO: ] - add argument and description to function comment
260 // Set the utility name for error reporting purposes
262 SetUtilityName (UTILITY_NAME
);
264 // Process the command-line arguments
266 Status
= ProcessArgs (Argc
, Argv
);
267 if (Status
!= STATUS_SUCCESS
) {
271 // Switch based on whether we're dumping, merging, etc.
273 if (mGlobals
.Mode
== MODE_DUMP_HII_EXPORT
) {
274 if (mGlobals
.Verbose
) {
275 fprintf (stdout
, "Dumping HII export file %s => %s\n", mGlobals
.HiiExportFileNames
, mGlobals
.OutputFileName
);
278 DumpHiiExportFile (mGlobals
.HiiExportFileNames
->FileName
, mGlobals
.OutputFileName
);
279 } else if (mGlobals
.Mode
== MODE_CREATE_HII_EXPORT
) {
280 CreateHiiExport (mGlobals
.OutputFileName
, &mGlobals
.Guid
, mGlobals
.PackFileNames
, mGlobals
.MfgFlag
);
281 } else if (mGlobals
.Mode
== MODE_MERGE_HII_EXPORTS
) {
282 MergeHiiExports (mGlobals
.HiiExportFileNames
, mGlobals
.OutputFileName
, mGlobals
.MfgFlag
, mGlobals
.NoEmptyVarPacks
);
283 } else if (mGlobals
.Mode
== MODE_EMIT_DEFAULTS
) {
284 EmitDefaults (mGlobals
.HiiExportFileNames
, mGlobals
.MfgFlag
, mGlobals
.NoEmptyVarPacks
);
291 return GetUtilityStatus ();
294 /******************************************************************************/
298 FILE_NAME_LIST
*HiiExportFiles
,
299 char *OutputFileName
,
307 Given a linked list of input HII export pack files, read in the contents
308 of each and create a single HII export pack that contains the contents
309 of all the input files.
313 HiiExportFiles - pointer to linked list of input HII export pack file names
314 OutputFileName - name of output (merged) HII export file
315 MfgDefaults - non-zero to emit manufacturing defaults in output file
316 NoEmptyVarPacks - non-zero to not emit 0-length variable packs to the output file
320 STATUS_SUCCESS - if successful
321 STATUS_ERROR - otherwise
325 EFI_HII_HANDLE HiiHandle
;
334 EFI_HII_EXPORT_TABLE
*HiiExportTableHeader
;
335 EFI_HII_EXPORT_TABLE TempHiiExportTableHeader
;
336 EFI_HII_DATA_TABLE
*DataTableHeader
;
337 EFI_HII_STRING_PACK
*StringPack
;
338 EFI_HII_VARIABLE_PACK
*VarPack
;
339 EFI_HII_IFR_PACK
*IfrPack
;
340 EFI_GUID HiiExportRevisionGuid
= EFI_HII_PROTOCOL_GUID
;
341 EFI_GUID PackageGuid
;
342 EFI_GUID FormsetGuid
;
343 long DataTableHeaderOffset
;
344 DATA_TABLE_HEADER_LIST
*DataTableList
;
345 DATA_TABLE_HEADER_LIST
*LastDataTable
;
346 DATA_TABLE_HEADER_LIST
*TempDataTable
;
350 HiiHandle
= FIRST_HII_PACK_HANDLE
;
354 Status
= STATUS_ERROR
;
355 DataTableList
= NULL
;
356 LastDataTable
= NULL
;
358 // Initialize our IFR parser and string routines
363 // Process each input HII export file
366 while (HiiExportFiles
!= NULL
) {
367 if (mGlobals
.Verbose
) {
368 fprintf (stdout
, "Processing file %s\n", HiiExportFiles
->FileName
);
371 // Read in the entire file contents
373 if ((InFptr
= fopen (HiiExportFiles
->FileName
, "rb")) == NULL
) {
374 Error (NULL
, 0, 0, HiiExportFiles
->FileName
, "failed to open HII export file for reading");
378 fseek (InFptr
, 0, SEEK_END
);
379 FileSize
= (int) ftell (InFptr
);
380 fseek (InFptr
, 0, SEEK_SET
);
381 Buffer
= (CHAR8
*) malloc (FileSize
);
382 if (Buffer
== NULL
) {
383 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
387 if (fread (Buffer
, FileSize
, 1, InFptr
) != 1) {
388 Error (NULL
, 0, 0, HiiExportFiles
->FileName
, "failed to read file contents");
394 HiiExportTableHeader
= (EFI_HII_EXPORT_TABLE
*) Buffer
;
396 // Walk all the data tables
398 DataTableHeader
= (EFI_HII_DATA_TABLE
*) (HiiExportTableHeader
+ 1);
399 for (DataTableIndex
= 0; DataTableIndex
< (int) HiiExportTableHeader
->NumberOfHiiDataTables
; DataTableIndex
++) {
402 // Make sure we're still pointing into our buffer
404 if (((char *) DataTableHeader
< Buffer
) || ((char *) DataTableHeader
> Buffer
+ FileSize
)) {
405 Error (NULL
, 0, 0, "bad data table size in input file", NULL
);
409 // Save a copy of the data table header
411 TempDataTable
= (DATA_TABLE_HEADER_LIST
*) malloc (sizeof (DATA_TABLE_HEADER_LIST
));
412 if (TempDataTable
== NULL
) {
413 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
417 memset ((void *) TempDataTable
, 0, sizeof (DATA_TABLE_HEADER_LIST
));
418 memcpy (&TempDataTable
->DataTableHeader
, DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
));
419 if (DataTableList
== NULL
) {
420 DataTableList
= TempDataTable
;
422 LastDataTable
->Next
= TempDataTable
;
425 LastDataTable
= TempDataTable
;
427 // If there is an IFR pack, parse it
429 if (DataTableHeader
->IfrDataOffset
!= 0) {
432 (EFI_HII_IFR_PACK
*) ((char *) DataTableHeader
+ DataTableHeader
->IfrDataOffset
),
433 &DataTableHeader
->PackageGuid
440 // If there is string data, save it
442 if (DataTableHeader
->StringDataOffset
!= 0) {
443 Status
= StringParsePack (
445 (EFI_HII_STRING_PACK
*) ((char *) DataTableHeader
+ DataTableHeader
->StringDataOffset
),
447 &DataTableHeader
->PackageGuid
449 if (Status
!= STATUS_SUCCESS
) {
454 // If there is device path data, process it
456 if (DataTableHeader
->DevicePathOffset
!= 0) {
457 Error (NULL
, 0, 0, "application error", "%s contains unsupported device path data", HiiExportFiles
->FileName
);
463 DataTableHeader
= (EFI_HII_DATA_TABLE
*) ((char *) DataTableHeader
+ DataTableHeader
->DataTableSize
);
472 HiiExportFiles
= HiiExportFiles
->Next
;
475 // Now create defaults
477 if (IfrSetDefaults (MfgDefaults
) != STATUS_SUCCESS
) {
481 // Create and write the output HII export header
483 if ((OutFptr
= fopen (OutputFileName
, "wb")) == NULL
) {
484 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
488 memset ((void *) &TempHiiExportTableHeader
, 0, sizeof (EFI_HII_EXPORT_TABLE
));
489 TempHiiExportTableHeader
.NumberOfHiiDataTables
= HiiHandle
- FIRST_HII_PACK_HANDLE
;
490 memcpy (&TempHiiExportTableHeader
.Revision
, &HiiExportRevisionGuid
, sizeof (EFI_GUID
));
491 if (fwrite ((void *) &TempHiiExportTableHeader
, sizeof (EFI_HII_EXPORT_TABLE
), 1, OutFptr
) != 1) {
492 Error (NULL
, 0, 0, OutputFileName
, "failed to write HII export table header to output file");
496 // Now go back through all the handles and create new data packs for each, writing out
497 // the contents as we go.
499 HiiHandle
= FIRST_HII_PACK_HANDLE
;
500 for (TempDataTable
= DataTableList
; TempDataTable
!= NULL
; TempDataTable
= TempDataTable
->Next
) {
502 // Write a data table header to the output file. We'll rewind the file and
503 // write an updated one when we're done with this data set
505 DataTableHeaderOffset
= ftell (OutFptr
);
506 TempDataTable
->DataTableHeader
.HiiHandle
= HiiHandle
;
507 TempDataTable
->DataTableHeader
.DataTableSize
= sizeof (EFI_HII_DATA_TABLE
);
509 // We may change the number of variable data when merging export files, so init to 0
511 TempDataTable
->DataTableHeader
.NumberOfVariableData
= 0;
512 if (fwrite ((void *) &TempDataTable
->DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
513 Error (NULL
, 0, 0, OutputFileName
, "failed to write HII data table header to output file");
517 // Get the string pack if any
519 Status
= StringGetPack (HiiHandle
, &StringPack
, &FileSize
, &Count
, &FormsetGuid
, &PackageGuid
);
520 if (Status
== STATUS_SUCCESS
) {
521 TempDataTable
->DataTableHeader
.StringDataOffset
= TempDataTable
->DataTableHeader
.DataTableSize
;
522 TempDataTable
->DataTableHeader
.DataTableSize
+= FileSize
;
524 // TempDataTable->DataTableHeader.NumberOfLanguages should be unchanged
526 if (fwrite ((void *) StringPack
, FileSize
, 1, OutFptr
) != 1) {
527 Error (NULL
, 0, 0, "failed to write string pack to output file", NULL
);
534 Status
= IfrGetIfrPack (HiiHandle
, &IfrPack
, &FormsetGuid
);
535 if (Status
== STATUS_SUCCESS
) {
537 // Write the IFR pack, followed by the variable packs
539 TempDataTable
->DataTableHeader
.IfrDataOffset
= TempDataTable
->DataTableHeader
.DataTableSize
;
540 TempDataTable
->DataTableHeader
.DataTableSize
+= IfrPack
->Header
.Length
;
541 if (fwrite ((void *) IfrPack
, IfrPack
->Header
.Length
, 1, OutFptr
) != 1) {
542 Error (NULL
, 0, 0, "failed to write IFR pack to output file", NULL
);
546 // If this is just a formset stub, then don't write the variable packs
548 if (IfrPack
->Header
.Length
!= sizeof (EMPTY_FORMSET_PACK
)) {
550 // Go through all the variable packs and see if they're referenced by this IFR
554 Status
= IfrGetVarPack (Count
, &VarPack
);
555 if (Status
== STATUS_SUCCESS
) {
557 // Check for variable data length of 0
559 if ((NoEmptyVarPacks
== 0) ||
560 ((VarPack
->Header
.Length
- sizeof (EFI_HII_VARIABLE_PACK
) - VarPack
->VariableNameLength
) != 0)
563 // See if it's referenced by this IFR
565 if (IfrReferencesVarPack (HiiHandle
, VarPack
) == STATUS_SUCCESS
) {
566 if (TempDataTable
->DataTableHeader
.VariableDataOffset
== 0) {
567 TempDataTable
->DataTableHeader
.VariableDataOffset
= TempDataTable
->DataTableHeader
.DataTableSize
;
570 TempDataTable
->DataTableHeader
.DataTableSize
+= VarPack
->Header
.Length
;
571 TempDataTable
->DataTableHeader
.NumberOfVariableData
++;
572 if (fwrite ((void *) VarPack
, VarPack
->Header
.Length
, 1, OutFptr
) != 1) {
573 Error (NULL
, 0, 0, "failed to write variable pack to output file", NULL
);
582 } while (Status
== STATUS_SUCCESS
);
585 Status
= STATUS_SUCCESS
;
588 // Get the device path pack
591 // Rewind the file and write the updated data table header.
593 fseek (OutFptr
, DataTableHeaderOffset
, SEEK_SET
);
594 if (fwrite ((void *) &TempDataTable
->DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
595 Error (NULL
, 0, 0, OutputFileName
, "failed to write HII data table header to output file");
599 fseek (OutFptr
, 0, SEEK_END
);
603 Status
= STATUS_SUCCESS
;
607 if (Buffer
!= NULL
) {
611 if (InFptr
!= NULL
) {
615 if (OutFptr
!= NULL
) {
619 while (DataTableList
!= NULL
) {
620 TempDataTable
= DataTableList
->Next
;
621 free (DataTableList
);
622 DataTableList
= TempDataTable
;
628 /******************************************************************************/
632 char *OutputFileName
,
633 EFI_GUID
*DummyFormsetGuid
,
634 FILE_NAME_LIST
*PackFiles
,
641 Given a linked list of HII pack file names, walk the list to
642 process them and create a single HII export file.
646 OutputFileName - name of output HII export file to create
647 DummyFormsetGuid - IFR formsets contain a GUID which is used in many
648 places while processing data tables. If we were not
649 given an IFR pack, then we'll create a stub IFR
650 pack using this GUID as the formset GUID.
651 PackFiles - linked list of HII pack files to process
652 MfgDefaults - when creating variable packs (via IFR pack processing),
653 use manufacturing defaults rather than standard defaults
657 STATUS_SUCCESS - if successful
658 STATUS_ERROR - otherwise
663 EMPTY_FORMSET_PACK EmptyFormset
;
664 EFI_HII_DATA_TABLE DataTableHeader
;
665 EFI_HII_EXPORT_TABLE ExportTableHeader
;
666 long DataTableHeaderOffset
;
670 FILE_NAME_LIST
*TempFile
;
671 EFI_GUID HiiExportRevisionGuid
= EFI_HII_PROTOCOL_GUID
;
673 EFI_GUID PackageGuid
;
675 EFI_HII_VARIABLE_PACK
*VarPack
;
676 EFI_HII_IFR_PACK
*IfrPack
;
677 EFI_HII_STRING_PACK_HEADER
*StringPack
;
678 EFI_HII_STRING_PACK_HEADER TerminatorStringPack
;
684 // If no input HII pack files, then why are we here? Should have been caught when
685 // args were processed though.
687 if (PackFiles
== NULL
) {
688 Error (NULL
, 0, 0, "no input pack files specified", NULL
);
693 Status
= STATUS_ERROR
;
696 // Open the output file for writing
698 if ((OutFptr
= fopen (OutputFileName
, "wb")) == NULL
) {
699 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
703 // Figure out how many data tables we are going to need. We'll create one
704 // data table if no more than one IFR, or we'll create one data table per IFR,
705 // and then one for strings if multiple IFR
709 for (TempFile
= PackFiles
; TempFile
!= NULL
; TempFile
= TempFile
->Next
) {
710 if (TempFile
->Tag
== EFI_HII_IFR
) {
712 } else if (TempFile
->Tag
== EFI_HII_STRING
) {
717 // Three possibilities:
718 // 1) No IFR, so create one data table that contains only strings and an empty formset
719 // 2) Only 1 IFR, so create an export table with one data table that contains the IFR
720 // and all the strings
721 // 3) Multiple IFR, so create a data table for each IFR and another data table with
724 // Initialize the export table header and write it out
726 memset ((void *) &ExportTableHeader
, 0, sizeof (EFI_HII_EXPORT_TABLE
));
728 ExportTableHeader
.NumberOfHiiDataTables
= 1;
731 // One data table per IFR, plus one for strings (if any).
733 ExportTableHeader
.NumberOfHiiDataTables
= (UINT16
) NumIfr
;
734 if (NumStrings
!= 0) {
735 ExportTableHeader
.NumberOfHiiDataTables
++;
739 // Init the GUID in the HII export table header
741 memcpy (&ExportTableHeader
.Revision
, &HiiExportRevisionGuid
, sizeof (EFI_GUID
));
742 if (fwrite ((void *) &ExportTableHeader
, sizeof (EFI_HII_EXPORT_TABLE
), 1, OutFptr
) != 1) {
743 Error (NULL
, 0, 0, OutputFileName
, "failed to write HII export table header to output file");
747 // *****************************************************************************************
749 // CASE 1 - No IFR => one data table that contains only strings and an empty formset.
752 // CASE 2 - Only 1 IFR => create an export table with one data table that contains the IFR
753 // and all the strings plus variable data
755 // CASE 3 - Multiple IFR => create a data table for each IFR and another data table with
756 // all the strings. Each IFR data table has variable data if applicable.
758 // *****************************************************************************************
760 // If the user did not give us an IFR file, then we'll have to create an empty formset
761 // and emit it to the output file. In this case, we need a formset GUID on the command
764 if ((NumIfr
== 0) && (mGlobals
.GuidSpecified
== 0)) {
766 // Warning (NULL, 0, 0, "using NULL GUID for empty formset", "specify -g GUID on the command line if desired");
768 memset ((void *) &PackageGuid
, 0, sizeof (EFI_GUID
));
769 } else if (mGlobals
.GuidSpecified
) {
771 // Use it for the package GUID
773 memcpy (&PackageGuid
, &mGlobals
.Guid
, sizeof (EFI_GUID
));
776 // Init the data table header.
777 // Write out the blank data table header. Save the offset so we can
778 // write an updated version at the end of processing.
780 memset ((void *) &DataTableHeader
, 0, sizeof (EFI_HII_DATA_TABLE
));
781 DataTableHeaderOffset
= ftell (OutFptr
);
782 DataTableHeader
.HiiHandle
= FIRST_HII_PACK_HANDLE
;
783 if (mGlobals
.Verbose
) {
784 fprintf (stdout
, "writing data table (first time) to offset 0x%X\n", ftell (OutFptr
));
787 if (fwrite ((void *) &DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
788 Error (NULL
, 0, 0, "failed to write Data Table Header to output file", NULL
);
792 // Set the data table size, then write out all the string packs
794 DataTableHeader
.DataTableSize
= sizeof (EFI_HII_DATA_TABLE
);
796 // Write out the string files to a single data record
798 for (TempFile
= PackFiles
; TempFile
!= NULL
; TempFile
= TempFile
->Next
) {
800 // Continue to next file if it's not a string pack file
802 if (TempFile
->Tag
!= EFI_HII_STRING
) {
806 // Set the offset in the header if this is the first string pack
808 if (DataTableHeader
.StringDataOffset
== 0) {
809 DataTableHeader
.StringDataOffset
= DataTableHeader
.DataTableSize
;
812 if ((InFptr
= fopen (TempFile
->FileName
, "rb")) == NULL
) {
813 Error (NULL
, 0, 0, TempFile
->FileName
, "failed to open input string pack file for reading");
817 // Get the file size, then read it into a buffer
819 fseek (InFptr
, 0, SEEK_END
);
820 FileSize
= ftell (InFptr
);
821 fseek (InFptr
, 0, SEEK_SET
);
822 Buffer
= (char *) malloc (FileSize
);
823 if (Buffer
== NULL
) {
824 Error (NULL
, 0, 0, TempFile
->FileName
, "memory allocation failure reading in file contents");
828 if (fread (Buffer
, FileSize
, 1, InFptr
) != 1) {
829 Error (NULL
, 0, 0, TempFile
->FileName
, "failed to read file contents");
836 // Verify that it's actually a string pack
838 StringPack
= (EFI_HII_STRING_PACK_HEADER
*) Buffer
;
839 while ((char *) StringPack
< Buffer
+ FileSize
) {
840 if (StringPack
->Header
.Type
!= EFI_HII_STRING
) {
841 Error (NULL
, 0, 0, TempFile
->FileName
, "file does not consist entirely of string packs");
845 if (StringPack
->Header
.Length
== 0) {
849 DataTableHeader
.NumberOfLanguages
++;
850 DataTableHeader
.DataTableSize
+= StringPack
->Header
.Length
;
852 // Write the string pack to the output file
854 if (mGlobals
.Verbose
) {
855 fprintf (stdout
, "writing string pack to offset 0x%X\n", ftell (OutFptr
));
858 if (fwrite (StringPack
, StringPack
->Header
.Length
, 1, OutFptr
) != 1) {
859 Error (NULL
, 0, 0, TempFile
->FileName
, "failed to write string pack to output file");
863 // Sanity check that adding the length advances us (no wrap)
865 if ((char *) StringPack
+ StringPack
->Header
.Length
<= (char *) StringPack
) {
866 Error (NULL
, 0, 0, TempFile
->FileName
, "invalid pack size in file");
870 StringPack
= (EFI_HII_STRING_PACK_HEADER
*) ((char *) StringPack
+ StringPack
->Header
.Length
);
873 // Free up buffer, go to next input string pack file
879 // Write a null-terminator string pack if we had any string packs at all
881 if (DataTableHeader
.StringDataOffset
!= 0) {
882 memset (&TerminatorStringPack
, 0, sizeof (EFI_HII_STRING_PACK_HEADER
));
883 TerminatorStringPack
.Header
.Length
= 0;
884 TerminatorStringPack
.Header
.Type
= EFI_HII_STRING
;
885 if (mGlobals
.Verbose
) {
886 fprintf (stdout
, "writing terminator string pack to offset 0x%X\n", ftell (OutFptr
));
889 if (fwrite (&TerminatorStringPack
, sizeof (EFI_HII_STRING_PACK_HEADER
), 1, OutFptr
) != 1) {
890 Error (NULL
, 0, 0, "failed to write string pack terminator to output file", NULL
);
894 DataTableHeader
.DataTableSize
+= sizeof (EFI_HII_STRING_PACK_HEADER
);
897 // Parse all the IFR packs, then get the GUID from the first
898 // one so we can use it for the package GUID if necessary.
900 memcpy (&PackageGuid
, &mGlobals
.Guid
, sizeof (EFI_GUID
));
903 if (ProcessIfrFiles (PackFiles
) != STATUS_SUCCESS
) {
907 // Set variable defaults in all variable packs
909 IfrSetDefaults (MfgDefaults
);
911 // Get the GUID from the first IFR pack if the user did not specify a GUID on
914 if (mGlobals
.GuidSpecified
== 0) {
915 if (IfrGetIfrPack (FIRST_HII_PACK_HANDLE
, &IfrPack
, &PackageGuid
) != STATUS_SUCCESS
) {
916 Error (NULL
, 0, 0, "internal application error", "failed to retrieve IFR pack after parsing");
922 // Set the package GUID in the data table header.
924 memcpy (&DataTableHeader
.PackageGuid
, &PackageGuid
, sizeof (EFI_GUID
));
926 // If no IFR, then create and write the empty formset. Otherwise
927 // parse the IFR and emit it and the variable data for it.
930 memset ((void *) &EmptyFormset
, 0, sizeof (EMPTY_FORMSET_PACK
));
931 EmptyFormset
.PackHeader
.Header
.Type
= EFI_HII_IFR
;
932 EmptyFormset
.PackHeader
.Header
.Length
= sizeof (EMPTY_FORMSET_PACK
);
936 EmptyFormset
.Formset
.Header
.OpCode
= EFI_IFR_FORM_SET_OP
;
937 EmptyFormset
.Formset
.Header
.Length
= (UINT8
) sizeof (EFI_IFR_FORM_SET
);
938 memcpy (&EmptyFormset
.Formset
.Guid
, &PackageGuid
, sizeof (EFI_GUID
));
942 EmptyFormset
.EndFormset
.Header
.OpCode
= EFI_IFR_END_FORM_SET_OP
;
943 EmptyFormset
.EndFormset
.Header
.Length
= (UINT8
) sizeof (EFI_IFR_END_FORM_SET
);
944 DataTableHeader
.IfrDataOffset
= DataTableHeader
.DataTableSize
;
945 if (mGlobals
.Verbose
) {
946 fprintf (stdout
, "writing stub IFR formset to to offset 0x%X\n", ftell (OutFptr
));
949 if (fwrite (&EmptyFormset
, sizeof (EMPTY_FORMSET_PACK
), 1, OutFptr
) != 1) {
950 Error (NULL
, 0, 0, OutputFileName
, "failed to write formset stub to output file");
954 DataTableHeader
.DataTableSize
+= sizeof (EMPTY_FORMSET_PACK
);
956 // Go back and re-write the data table header, reposition to the end, then return.
958 fseek (OutFptr
, DataTableHeaderOffset
, SEEK_SET
);
959 if (mGlobals
.Verbose
) {
960 fprintf (stdout
, "writing data table (second time) to offset 0x%X\n", ftell (OutFptr
));
963 if (fwrite ((void *) &DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
964 Error (NULL
, 0, 0, "failed to write Data Table Header to output file", NULL
);
968 fseek (OutFptr
, 0, SEEK_END
);
969 if (mGlobals
.Verbose
) {
972 "final file offset=0x%X DataTableHeader.DataTableSize=0x%X\n",
974 DataTableHeader
.DataTableSize
977 } else if (NumIfr
== 1) {
979 // They gave us one input IFR file. We parsed it above, so get each one
980 // and emit the IFR and each variable pack it references.
981 // Update the data pack header for the IFR pack, then write the IFR pack data
983 DataTableHeader
.IfrDataOffset
= DataTableHeader
.DataTableSize
;
984 if (IfrGetIfrPack (FIRST_HII_PACK_HANDLE
, &IfrPack
, &TempGuid
) != STATUS_SUCCESS
) {
985 Error (NULL
, 0, 0, "internal application error", "failed to retrieve IFR pack after parsing");
989 if (mGlobals
.Verbose
) {
990 fprintf (stdout
, "writing IFR pack to 0x%X\n", ftell (OutFptr
));
993 if (fwrite (IfrPack
, IfrPack
->Header
.Length
, 1, OutFptr
) != 1) {
994 Error (NULL
, 0, 0, OutputFileName
, "failed to write IFR pack to output file");
998 DataTableHeader
.DataTableSize
+= IfrPack
->Header
.Length
;
1000 // Now go through all the variable packs discovered during IFR processing
1001 // and write them to the output file
1003 if (mGlobals
.NoVarPacks
== 0) {
1006 Status
= IfrGetVarPack (Index
, &VarPack
);
1007 if (Status
== STATUS_SUCCESS
) {
1009 // If this is the first variable pack, then update the "offset
1010 // to variable data" in the data table header
1013 DataTableHeader
.VariableDataOffset
= DataTableHeader
.DataTableSize
;
1016 DataTableHeader
.DataTableSize
+= VarPack
->Header
.Length
;
1017 DataTableHeader
.NumberOfVariableData
++;
1018 if (fwrite ((void *) VarPack
, VarPack
->Header
.Length
, 1, OutFptr
) != 1) {
1019 Error (NULL
, 0, 0, OutputFileName
, "failed to write variable pack to output file");
1025 } while (Status
== STATUS_SUCCESS
);
1028 // Reposition in the output file and write the updated data table header
1030 fseek (OutFptr
, DataTableHeaderOffset
, SEEK_SET
);
1031 if (fwrite ((void *) &DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
1032 Error (NULL
, 0, 0, "failed to write Data Table Header to output file", NULL
);
1036 fseek (OutFptr
, 0, SEEK_END
);
1039 // Multiple IFR input files. Close out the current data table (strings)
1040 // if applicable. Then retrieve each parsed IFR pack and create a data pack
1041 // that contains the IFR (one per data set) and the variable packs that
1042 // the given IFR form references.
1044 if (NumStrings
!= 0) {
1045 fseek (OutFptr
, DataTableHeaderOffset
, SEEK_SET
);
1046 if (fwrite ((void *) &DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
1047 Error (NULL
, 0, 0, "failed to write Data Table Header to output file", NULL
);
1051 fseek (OutFptr
, 0, SEEK_END
);
1054 // No strings, so back up over the data table header we wrote because we assumed
1055 // at least one string pack.
1057 fseek (OutFptr
, DataTableHeaderOffset
, SEEK_SET
);
1060 // Now go through all the IFR packs and write them out, along with variable
1061 // data referenced by each. Note that multiple IFR forms can refer to the
1062 // same variables, so the same variable data could be duplicated in multiple
1065 Index
= FIRST_HII_PACK_HANDLE
;
1066 while (IfrGetIfrPack (Index
, &IfrPack
, &TempGuid
) == STATUS_SUCCESS
) {
1068 // Initialize the data table header
1070 memset (&DataTableHeader
, 0, sizeof (EFI_HII_DATA_TABLE
));
1071 memcpy (&DataTableHeader
.PackageGuid
, &PackageGuid
, sizeof (EFI_GUID
));
1073 // If we didn't have strings, then the HiiHandle should be just Index,
1074 // rather than Index+1. But since the HiiHandle is not required to start
1075 // with 1, we'll let it be Index+1.
1077 DataTableHeader
.HiiHandle
= (EFI_HII_HANDLE
) (Index
+ 1);
1078 DataTableHeader
.DataTableSize
= sizeof (EFI_HII_DATA_TABLE
);
1080 // Save the file offset of the data table header so we can write an updated
1083 DataTableHeaderOffset
= ftell (OutFptr
);
1084 if (mGlobals
.Verbose
) {
1085 fprintf (stdout
, "writing data table header to 0x%X\n", ftell (OutFptr
));
1088 if (fwrite ((void *) &DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
1089 Error (NULL
, 0, 0, "failed to write Data Table Header to output file", NULL
);
1093 DataTableHeader
.IfrDataOffset
= DataTableHeader
.DataTableSize
;
1094 if (fwrite (IfrPack
, IfrPack
->Header
.Length
, 1, OutFptr
) != 1) {
1095 Error (NULL
, 0, 0, OutputFileName
, "failed to write IFR pack to output file");
1099 DataTableHeader
.DataTableSize
+= IfrPack
->Header
.Length
;
1101 // Go through all the variable packs and see if this IFR references each. If the
1102 // IFR does reference it, then add the variable pack to the output.
1104 if (mGlobals
.NoVarPacks
== 0) {
1106 while (IfrGetVarPack (VarPackIndex
, &VarPack
) == STATUS_SUCCESS
) {
1108 // See if the IFR references this variable pack
1110 if (IfrReferencesVarPack (Index
, VarPack
) == STATUS_SUCCESS
) {
1112 // If this is the first variable pack, then set the offset in
1113 // the data table header.
1115 if (DataTableHeader
.VariableDataOffset
== 0) {
1116 DataTableHeader
.VariableDataOffset
= DataTableHeader
.DataTableSize
;
1119 // Write the variable pack
1121 if (fwrite (VarPack
, VarPack
->Header
.Length
, 1, OutFptr
) != 1) {
1122 Error (NULL
, 0, 0, OutputFileName
, "failed to write variable pack to output file");
1126 DataTableHeader
.NumberOfVariableData
++;
1127 DataTableHeader
.DataTableSize
+= VarPack
->Header
.Length
;
1134 // Write the updated data table header
1136 fseek (OutFptr
, DataTableHeaderOffset
, SEEK_SET
);
1137 if (fwrite ((void *) &DataTableHeader
, sizeof (EFI_HII_DATA_TABLE
), 1, OutFptr
) != 1) {
1138 Error (NULL
, 0, 0, "failed to write Data Table Header to output file", NULL
);
1142 fseek (OutFptr
, 0, SEEK_END
);
1150 Status
= STATUS_SUCCESS
;
1154 if (Buffer
!= NULL
) {
1158 if (InFptr
!= NULL
) {
1162 if (OutFptr
!= NULL
) {
1169 /******************************************************************************/
1173 FILE_NAME_LIST
*FileName
1177 Routine Description:
1179 Given a linked list of pack file names, read in each IFR pack file
1180 and process the contents.
1184 FileName - pointer to linked list of input pack file names
1188 STATUS_SUCCESS - if successful
1189 STATUS_ERROR - otherwise
1199 EFI_GUID FormsetGuid
;
1200 EFI_HII_PACK_HEADER
*PackHeader
;
1202 // Process each input IFR file
1204 Status
= STATUS_ERROR
;
1208 while (FileName
!= NULL
) {
1210 // Only process IFR pack files
1212 if (FileName
->Tag
!= EFI_HII_IFR
) {
1213 FileName
= FileName
->Next
;
1217 // Open the input file, then read the contents
1219 if ((InFptr
= fopen (FileName
->FileName
, "rb")) == NULL
) {
1220 Error (NULL
, 0, 0, FileName
->FileName
, "failed to open input IFR file");
1224 fseek (InFptr
, 0, SEEK_END
);
1225 BufferSize
= ftell (InFptr
);
1226 fseek (InFptr
, 0, SEEK_SET
);
1227 Buffer
= (char *) malloc (BufferSize
);
1228 if (Buffer
== NULL
) {
1229 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1233 if (fread (Buffer
, BufferSize
, 1, InFptr
) != 1) {
1234 Error (NULL
, 0, 0, FileName
->FileName
, "failed to read file contents");
1241 // Check the buffer contents -- better be an IFR pack
1243 if (BufferSize
< sizeof (EFI_HII_PACK_HEADER
)) {
1244 Error (NULL
, 0, 0, FileName
->FileName
, "file is not large enough to contain an IFR pack");
1248 PackHeader
= (EFI_HII_PACK_HEADER
*) Buffer
;
1249 if (PackHeader
->Type
!= EFI_HII_IFR
) {
1250 Error (NULL
, 0, 0, FileName
->FileName
, "file does not appear to be an IFR pack");
1254 // Process the contents
1256 memset ((void *) &FormsetGuid
, 0, sizeof (EFI_GUID
));
1257 IfrStatus
= IfrParsePack (Handle
, (EFI_HII_IFR_PACK
*) PackHeader
, &FormsetGuid
);
1258 if (IfrStatus
!= STATUS_SUCCESS
) {
1265 FileName
= FileName
->Next
;
1268 Status
= STATUS_SUCCESS
;
1270 if (InFptr
!= NULL
) {
1274 if (Buffer
!= NULL
) {
1284 FILE_NAME_LIST
*HiiExportFiles
,
1290 Routine Description:
1292 Given a linked list of HII export files, read in each file,
1293 process the contents, and then emit variable packs.
1297 HiiExportFiles - linked list of HII export files to process
1298 MfgDefaults - emit manufacturing defaults
1299 NoEmptyVarPacks - don't emit variable packs if they are 0-length
1303 STATUS_SUCCESS - if successful
1304 STATUS_ERROR - otherwise
1311 EFI_HII_VARIABLE_PACK
*VarPack
;
1312 CHAR8 OutFileName
[MAX_PATH
];
1313 CHAR8 GuidString
[100];
1318 EFI_HII_EXPORT_TABLE
*HiiExportTableHeader
;
1319 EFI_HII_DATA_TABLE
*DataTableHeader
;
1323 HiiHandle
= FIRST_HII_PACK_HANDLE
;
1327 Status
= STATUS_ERROR
;
1329 // Initialize our IFR parser
1333 // Process each input HII export file
1335 while (HiiExportFiles
!= NULL
) {
1336 if (mGlobals
.Verbose
) {
1337 fprintf (stdout
, "Processing file %s\n", HiiExportFiles
->FileName
);
1340 // Read in the entire file contents
1342 if ((InFptr
= fopen (HiiExportFiles
->FileName
, "rb")) == NULL
) {
1343 Error (NULL
, 0, 0, HiiExportFiles
->FileName
, "failed to open HII export file for reading");
1347 fseek (InFptr
, 0, SEEK_END
);
1348 FileSize
= (int) ftell (InFptr
);
1349 fseek (InFptr
, 0, SEEK_SET
);
1350 Buffer
= (CHAR8
*) malloc (FileSize
);
1351 if (Buffer
== NULL
) {
1352 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1356 if (fread (Buffer
, FileSize
, 1, InFptr
) != 1) {
1357 Error (NULL
, 0, 0, HiiExportFiles
->FileName
, "failed to read file contents");
1363 HiiExportTableHeader
= (EFI_HII_EXPORT_TABLE
*) Buffer
;
1365 // Walk all the data tables
1367 DataTableHeader
= (EFI_HII_DATA_TABLE
*) (HiiExportTableHeader
+ 1);
1368 for (DataTableIndex
= 0; DataTableIndex
< (int) HiiExportTableHeader
->NumberOfHiiDataTables
; DataTableIndex
++) {
1370 // Make sure we're still pointing into our buffer
1372 if (((char *) DataTableHeader
< Buffer
) || ((char *) DataTableHeader
> Buffer
+ FileSize
)) {
1373 Error (NULL
, 0, 0, "bad data table size in input file", NULL
);
1377 // If there is an IFR pack, parse it
1380 if (DataTableHeader
->IfrDataOffset
!= 0) {
1383 (EFI_HII_IFR_PACK
*) ((char *) DataTableHeader
+ DataTableHeader
->IfrDataOffset
),
1384 &DataTableHeader
->PackageGuid
1393 DataTableHeader
= (EFI_HII_DATA_TABLE
*) ((char *) DataTableHeader
+ DataTableHeader
->DataTableSize
);
1401 HiiExportFiles
= HiiExportFiles
->Next
;
1404 // Now create defaults
1406 if (IfrSetDefaults (MfgDefaults
) != STATUS_SUCCESS
) {
1410 // Now retrieve each variable pack and write it out to a GUID-VarName.hpk file
1414 Status
= IfrGetVarPack (HiiHandle
, &VarPack
);
1415 if (Status
== STATUS_SUCCESS
) {
1417 // Check for variable data length of 0
1419 if ((NoEmptyVarPacks
== 0) ||
1420 ((VarPack
->Header
.Length
- sizeof (EFI_HII_VARIABLE_PACK
) - VarPack
->VariableNameLength
) != 0)
1423 // Open the output file and write the variable pack
1425 GuidToString (&VarPack
->VariableGuid
, GuidString
);
1429 "%s-%S-MfgDefaults%s",
1431 (CHAR16
*) (VarPack
+ 1),
1432 DEFAULT_HII_PACK_FILENAME_EXTENSION
1439 (CHAR16
*) (VarPack
+ 1),
1440 DEFAULT_HII_PACK_FILENAME_EXTENSION
1444 if (mGlobals
.Verbose
) {
1447 "Creating %svariable defaults pack file %s\n",
1448 MfgDefaults
? "manufacturing " : "",
1453 if ((OutFptr
= fopen (OutFileName
, "wb")) == NULL
) {
1454 Error (NULL
, 0, 0, OutFileName
, "failed to open output file for writing", NULL
);
1458 if (fwrite ((void *) VarPack
, VarPack
->Header
.Length
, 1, OutFptr
) != 1) {
1459 Error (NULL
, 0, 0, OutFileName
, "failed to write defaults to output file");
1467 // Print a message that we skipped one if in verbose mode
1469 if (mGlobals
.Verbose
) {
1470 GuidToString (&VarPack
->VariableGuid
, GuidString
);
1474 "%s-%S-MfgDefaults%s",
1476 (CHAR16
*) (VarPack
+ 1),
1477 DEFAULT_HII_PACK_FILENAME_EXTENSION
1484 (CHAR16
*) (VarPack
+ 1),
1485 DEFAULT_HII_PACK_FILENAME_EXTENSION
1491 "Skipping 0-length %svariable defaults pack file %s\n",
1492 MfgDefaults
? "manufacturing " : "",
1500 } while (Status
== STATUS_SUCCESS
);
1501 Status
= STATUS_SUCCESS
;
1504 if (Buffer
!= NULL
) {
1508 if (InFptr
!= NULL
) {
1512 if (OutFptr
!= NULL
) {
1526 Routine Description:
1528 Free up an memory we allocated so we can exit cleanly
1536 FILE_NAME_LIST
*Next
;
1538 // Free up input pack file names
1540 while (mGlobals
.PackFileNames
!= NULL
) {
1541 Next
= mGlobals
.PackFileNames
->Next
;
1542 free (mGlobals
.PackFileNames
);
1543 mGlobals
.PackFileNames
= Next
;
1546 // Free up input HII export file names
1548 while (mGlobals
.HiiExportFileNames
!= NULL
) {
1549 Next
= mGlobals
.HiiExportFileNames
->Next
;
1550 free (mGlobals
.HiiExportFileNames
);
1551 mGlobals
.HiiExportFileNames
= Next
;
1558 char *HiiExportFileName
,
1559 char *OutputFileName
1563 Routine Description:
1565 Dump the contents of an HII export file for debug purposes
1569 HiiExportFileName - name of input HII export file
1570 OutputFileName - name of output file to dump contents
1573 STATUS_SUCCESS - no problems
1574 STATUS_ERROR - problems encountered processing the file
1586 char GuidString
[100];
1589 EFI_HII_DATA_TABLE
*DataTableHeader
;
1590 EFI_GUID HiiExportRevisionGuid
= EFI_HII_PROTOCOL_GUID
;
1597 Status
= STATUS_ERROR
;
1599 // Open the input file
1601 if ((InFptr
= fopen (HiiExportFileName
, "rb")) == NULL
) {
1602 Error (NULL
, 0, 0, HiiExportFileName
, "failed to open input HII export file for reading");
1606 // Open the output file
1608 if ((OutFptr
= fopen (OutputFileName
, "w")) == NULL
) {
1609 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file for writing");
1613 // Get the file size, then allocate a buffer and read in the file contents.
1615 fseek (InFptr
, 0, SEEK_END
);
1616 BufferSize
= (int) ftell (InFptr
);
1617 fseek (InFptr
, 0, SEEK_SET
);
1618 BufferStart
= (char *) malloc (BufferSize
);
1619 if (BufferStart
== NULL
) {
1620 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1624 if (fread (BufferStart
, BufferSize
, 1, InFptr
) != 1) {
1625 Error (NULL
, 0, 0, HiiExportFileName
, "error reading file contents");
1632 // Crude check of the input data -- check the size and GUID
1634 if (BufferSize
< sizeof (EFI_HII_EXPORT_TABLE
)) {
1635 Error (NULL
, 0, 0, HiiExportFileName
, "files not large enough to contain an HII export table header");
1639 if (memcmp (&((EFI_HII_EXPORT_TABLE
*) BufferStart
)->Revision
, &HiiExportRevisionGuid
, sizeof (EFI_GUID
)) != 0) {
1640 Error (NULL
, 0, 0, HiiExportFileName
, "invalid HII export revision GUID -- is this an HII export file?");
1642 // See if it's a HII pack file
1644 TestDumpHiiPack (OutFptr
, BufferStart
, BufferSize
);
1648 // Now walk the export data
1650 Buffer
= BufferStart
;
1651 BufferEnd
= BufferStart
+ BufferSize
;
1655 fprintf (OutFptr
, "HII dump of file %s\n\n", HiiExportFileName
);
1656 NumberOfTables
= ((EFI_HII_EXPORT_TABLE
*) Buffer
)->NumberOfHiiDataTables
;
1657 fprintf (OutFptr
, "Number of data tables: %d\n", NumberOfTables
);
1658 GuidToString (&((EFI_HII_EXPORT_TABLE
*) Buffer
)->Revision
, GuidString
);
1659 fprintf (OutFptr
, "HII export revision: %s\n", GuidString
);
1661 // Now walk the data tables
1663 Buffer
+= sizeof (EFI_HII_EXPORT_TABLE
);
1664 for (Counter
= 0; Counter
< NumberOfTables
; Counter
++) {
1665 DataTableHeader
= (EFI_HII_DATA_TABLE
*) Buffer
;
1666 fprintf (OutFptr
, "----------------------------------------------------------\n");
1667 fprintf (OutFptr
, " DataTable at offset 0x%08X\n", (int) Buffer
- (int) BufferStart
);
1668 fprintf (OutFptr
, " HII Handle: 0x%08X\n", DataTableHeader
->HiiHandle
);
1669 GuidToString (&DataTableHeader
->PackageGuid
, GuidString
);
1670 fprintf (OutFptr
, " Package GUID: %s\n", GuidString
);
1671 fprintf (OutFptr
, " Data table size: 0x%08X\n", DataTableHeader
->DataTableSize
);
1672 fprintf (OutFptr
, " IFR data offset: 0x%08X\n", DataTableHeader
->IfrDataOffset
);
1673 fprintf (OutFptr
, " String data offset: 0x%08X\n", DataTableHeader
->StringDataOffset
);
1674 fprintf (OutFptr
, " Variable data offset: 0x%08X\n", DataTableHeader
->VariableDataOffset
);
1675 fprintf (OutFptr
, " Device path offset: 0x%08X\n", DataTableHeader
->DevicePathOffset
);
1676 fprintf (OutFptr
, " Number of variable data: 0x%08X\n", DataTableHeader
->NumberOfVariableData
);
1677 fprintf (OutFptr
, " Number of languages: 0x%08X\n", DataTableHeader
->NumberOfLanguages
);
1681 if (DataTableHeader
->StringDataOffset
!= 0) {
1684 (EFI_HII_STRING_PACK
*) ((char *) DataTableHeader
+ DataTableHeader
->StringDataOffset
),
1685 DataTableHeader
->StringDataOffset
,
1692 if (DataTableHeader
->IfrDataOffset
!= 0) {
1695 (EFI_HII_IFR_PACK
*) ((char *) DataTableHeader
+ DataTableHeader
->IfrDataOffset
),
1696 DataTableHeader
->IfrDataOffset
,
1703 if (DataTableHeader
->VariableDataOffset
!= 0) {
1706 (EFI_HII_VARIABLE_PACK
*) ((char *) DataTableHeader
+ DataTableHeader
->VariableDataOffset
),
1707 DataTableHeader
->NumberOfVariableData
,
1708 DataTableHeader
->VariableDataOffset
,
1716 // Check position before advancing
1718 if ((Buffer
+ DataTableHeader
->DataTableSize
< Buffer
) || (Buffer
+ DataTableHeader
->DataTableSize
> BufferEnd
)) {
1719 Error (NULL
, 0, 0, HiiExportFileName
, "bad data table size at offset 0x%X", (int) Buffer
- (int) BufferStart
);
1723 Buffer
+= DataTableHeader
->DataTableSize
;
1726 Status
= STATUS_SUCCESS
;
1728 if (OutFptr
!= NULL
) {
1732 if (InFptr
!= NULL
) {
1736 if (BufferStart
!= NULL
) {
1747 EFI_HII_IFR_PACK
*Pack
,
1753 Routine Description:
1755 Dump the contents of an IFR pack for debug purposes
1759 OutFptr - file pointer to which to dump the output
1760 Pack - pointer to IFR pack to dump
1761 BaseOffset - offset from which Pack starts in its parent data table
1762 Indent - indent this many spaces when printing text to OutFptr
1769 EFI_IFR_FORM_SET
*IfrFormSet
;
1770 char GuidString
[100];
1771 if (Pack
->Header
.Type
!= EFI_HII_IFR
) {
1772 Error (NULL
, 0, 0, "found non-IFR pack type at IFR data offset", NULL
);
1776 fprintf (OutFptr
, "%*cIFR pack at offset 0x%08X\n", Indent
, ' ', BaseOffset
);
1777 fprintf (OutFptr
, "%*c Length 0x%08X\n", Indent
, ' ', Pack
->Header
.Length
);
1779 // Get the GUID from the formset
1781 IfrFormSet
= (EFI_IFR_FORM_SET
*) (Pack
+ 1);
1782 GuidToString (&IfrFormSet
->Guid
, GuidString
);
1783 fprintf (OutFptr
, "%*c Variable GUID %s\n", Indent
, ' ', GuidString
);
1785 // Print the IFR formset size, with a note indicating if it's a min (likely stub)
1788 if (Pack
->Header
.Length
== sizeof (EMPTY_FORMSET_PACK
)) {
1791 "%*c IFR formset size 0x%08X (empty formset)\n",
1794 Pack
->Header
.Length
- sizeof (EFI_HII_IFR_PACK
)
1799 "%*c IFR formset size 0x%08X\n",
1802 Pack
->Header
.Length
- sizeof (EFI_HII_IFR_PACK
)
1806 // Dump raw bytes -- not much use
1814 EFI_HII_VARIABLE_PACK
*Pack
,
1821 Routine Description:
1823 Dump the contents of an IFR pack for debug purposes
1827 OutFptr - file pointer to which to dump the output
1828 Pack - pointer to variable pack to dump
1829 NumPacks - number of packs in Pack[] array
1830 BaseOffset - offset from which Pack starts in its parent data table
1831 Indent - indent this many spaces when printing text to OutFptr
1841 char GuidString
[100];
1843 for (Count
= 0; Count
< NumPacks
; Count
++) {
1844 if (Pack
->Header
.Type
!= EFI_HII_VARIABLE
) {
1845 Error (NULL
, 0, 0, "found non-variable pack type in variable pack array", NULL
);
1849 fprintf (OutFptr
, "%*cVariable pack at offset 0x%08X\n", Indent
, ' ', BaseOffset
);
1850 fprintf (OutFptr
, "%*c Length 0x%08X\n", Indent
, ' ', Pack
->Header
.Length
);
1851 GuidToString (&Pack
->VariableGuid
, GuidString
);
1852 fprintf (OutFptr
, "%*c Variable GUID %s\n", Indent
, ' ', GuidString
);
1853 fprintf (OutFptr
, "%*c Variable Name %S\n", Indent
, ' ', (CHAR16
*) (Pack
+ 1));
1854 Len
= sizeof (EFI_HII_VARIABLE_PACK
) + Pack
->VariableNameLength
;
1855 fprintf (OutFptr
, "%*c Variable Size 0x%08X\n", Indent
, ' ', Pack
->Header
.Length
- Len
);
1859 DumpRawBytes (OutFptr
, (char *) Pack
+ Len
, Pack
->Header
.Length
- Len
, Len
, Indent
+ 2);
1860 BaseOffset
+= Pack
->Header
.Length
;
1861 Pack
= (EFI_HII_VARIABLE_PACK
*) ((char *) Pack
+ Pack
->Header
.Length
);
1869 EFI_HII_STRING_PACK
*Pack
,
1875 Routine Description:
1877 Dump the contents of a string pack array for debug purposes
1881 OutFptr - file pointer to which to dump the output
1882 Pack - pointer to string pack array to dump
1883 BaseOffset - offset from which Pack starts in its parent data table
1884 Indent - indent this many spaces when printing text to OutFptr
1895 // String pack array is terminated with a zero-length string pack
1897 while (Pack
->Header
.Length
> 0) {
1898 if (Pack
->Header
.Type
!= EFI_HII_STRING
) {
1899 Error (NULL
, 0, 0, "found non-string pack type in string pack array", NULL
);
1903 fprintf (OutFptr
, "%*cString pack at offset 0x%08X\n", Indent
, ' ', BaseOffset
);
1904 fprintf (OutFptr
, "%*c Length 0x%08X\n", Indent
, ' ', Pack
->Header
.Length
);
1907 "%*c Language %S\n",
1910 (CHAR16
*) ((char *) Pack
+ Pack
->LanguageNameString
)
1914 "%*c Printable Language %S\n",
1917 (CHAR16
*) ((char *) Pack
+ Pack
->PrintableLanguageName
)
1919 fprintf (OutFptr
, "%*c Number of strings 0x%08X\n", Indent
, ' ', Pack
->NumStringPointers
);
1920 fprintf (OutFptr
, "%*c Attributes 0x%08X\n", Indent
, ' ', Pack
->Attributes
);
1921 IndexPtr
= (int *) (Pack
+ 1);
1925 if (mGlobals
.DumpStrings
) {
1926 for (Count
= 0; Count
< (int) Pack
->NumStringPointers
; Count
++) {
1927 fprintf (OutFptr
, "%*c String 0x%04X: ", Indent
, ' ', Count
);
1929 // Print raw hex bytes
1931 for (WCPtr
= (CHAR16
*) ((char *) Pack
+*IndexPtr
); *WCPtr
!= 0; WCPtr
++) {
1932 fprintf (OutFptr
, "%02X ", (unsigned int) *WCPtr
);
1935 fprintf (OutFptr
, "00\n");
1940 BaseOffset
+= Pack
->Header
.Length
;
1941 Pack
= (EFI_HII_STRING_PACK
*) ((char *) Pack
+ Pack
->Header
.Length
);
1954 Routine Description:
1956 GC_TODO: Add function description
1960 OutFptr - GC_TODO: add argument description
1961 Buffer - GC_TODO: add argument description
1962 BufferSize - GC_TODO: add argument description
1966 GC_TODO: add return values
1970 EFI_HII_PACK_HEADER
*PackHeader
;
1972 PackHeader
= (EFI_HII_PACK_HEADER
*) Buffer
;
1976 if (PackHeader
->Length
!= (unsigned int) BufferSize
) {
1982 switch (PackHeader
->Type
) {
1983 case EFI_HII_STRING
:
1984 fprintf (stdout
, "Dumping as string pack\n");
1985 DumpStringPack (OutFptr
, (EFI_HII_STRING_PACK
*) Buffer
, 0, 2);
1989 fprintf (stdout
, "Dumping as IFR pack\n");
1990 DumpIfrPack (OutFptr
, (EFI_HII_IFR_PACK
*) Buffer
, 0, 2);
1993 case EFI_HII_VARIABLE
:
1994 fprintf (stdout
, "Dumping as IFR pack\n");
1995 DumpVariablePacks (OutFptr
, (EFI_HII_VARIABLE_PACK
*) Buffer
, 1, 0, 2);
2011 Routine Description:
2013 GC_TODO: Add function description
2017 OutFptr - GC_TODO: add argument description
2018 Buffer - GC_TODO: add argument description
2019 Count - GC_TODO: add argument description
2020 BaseOffset - GC_TODO: add argument description
2021 Indent - GC_TODO: add argument description
2025 GC_TODO: add return values
2031 for (Counter
= 0; Counter
< Count
; Counter
++) {
2032 if ((Counter
& 0xF) == 0) {
2034 fprintf (OutFptr
, "\n%*c%08X ", Indent
, ' ', Counter
);
2036 fprintf (OutFptr
, "\n%*c%08X ", Indent
, ' ', Counter
);
2040 fprintf (OutFptr
, "%02X ", (unsigned int) (unsigned char) *Buffer
);
2044 fprintf (OutFptr
, "\n");
2054 Routine Description:
2056 Given a pointer to a GUID, sprint the value into a string
2060 Guid - pointer to input GUID
2061 Str - pointer to outgoing printed GUID value
2070 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
2091 Routine Description:
2093 Callback function used to get files matching a file mask. This
2094 function is called when the command-line arguments to this utility
2095 are parsed and the user specified "-s Path FileMask" to process
2096 all HII export files in Path and its subdirectories that match
2101 FoundFileName - name of file found.
2104 non-zero - caller should halt processing
2105 zero - no problems while processing FoundFileName
2109 FILE_NAME_LIST
*FileName
;
2111 FILE_NAME_LIST
*TempFileName
;
2113 FileName
= (FILE_NAME_LIST
*) malloc (sizeof (FILE_NAME_LIST
));
2114 if (FileName
== NULL
) {
2115 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
2116 return STATUS_ERROR
;
2119 memset ((void *) FileName
, 0, sizeof (FILE_NAME_LIST
));
2120 strcpy (FileName
->FileName
, FoundFileName
);
2121 if (mGlobals
.HiiExportFileNames
== NULL
) {
2122 mGlobals
.HiiExportFileNames
= FileName
;
2125 // Add to the end of the list
2127 for (TempFileName
= mGlobals
.HiiExportFileNames
; TempFileName
->Next
!= NULL
; TempFileName
= TempFileName
->Next
)
2129 TempFileName
->Next
= FileName
;
2143 Routine Description:
2145 Process the command line arguments
2149 As per standard C main()
2153 STATUS_SUCCESS - if successful
2154 STATUS_ERROR - otherwise
2157 // GC_TODO: Argc - add argument and description to function comment
2158 // GC_TODO: ] - add argument and description to function comment
2160 FILE_NAME_LIST
*FileName
;
2162 FILE_NAME_LIST
*TempFileName
;
2164 EFI_HII_PACK_HEADER PackHeader
;
2166 memset ((void *) &mGlobals
, 0, sizeof (mGlobals
));
2168 // Skip program name
2175 return STATUS_ERROR
;
2178 // First arg must be one of create, merge, defaults, or dump
2180 if (_stricmp (Argv
[0], "create") == 0) {
2181 mGlobals
.Mode
= MODE_CREATE_HII_EXPORT
;
2182 } else if (_stricmp (Argv
[0], "merge") == 0) {
2183 mGlobals
.Mode
= MODE_MERGE_HII_EXPORTS
;
2184 } else if (_stricmp (Argv
[0], "defaults") == 0) {
2185 mGlobals
.Mode
= MODE_EMIT_DEFAULTS
;
2186 } else if (_stricmp (Argv
[0], "dump") == 0) {
2187 mGlobals
.Mode
= MODE_DUMP_HII_EXPORT
;
2188 } else if (strcmp (Argv
[0], "-?") == 0) {
2190 return STATUS_ERROR
;
2192 Error (NULL
, 0, 0, Argv
[0], "unrecognized mode");
2193 return STATUS_ERROR
;
2199 // Process until no more args.
2202 if (_stricmp (Argv
[0], "-o") == 0) {
2204 // -o option to specify the output file
2206 if ((Argc
<= 1) || (Argv
[1][0] == '-')) {
2207 Error (UTILITY_NAME
, 0, 0, Argv
[0], "missing output file name");
2208 return STATUS_ERROR
;
2211 if (mGlobals
.OutputFileName
[0] == 0) {
2212 mGlobals
.OutputFileName
[MAX_PATH
- 1] = 0;
2213 strncpy (mGlobals
.OutputFileName
, Argv
[1], MAX_PATH
- 1);
2215 Error (UTILITY_NAME
, 0, 0, Argv
[1], "-o option already specified with '%s'", mGlobals
.OutputFileName
);
2216 return STATUS_ERROR
;
2221 } else if (_stricmp (Argv
[0], "-mfg") == 0) {
2222 mGlobals
.MfgFlag
= 1;
2223 } else if (_stricmp (Argv
[0], "-g") == 0) {
2225 // -g option to specify the guid
2227 if ((Argc
<= 1) || (Argv
[1][0] == '-')) {
2228 Error (UTILITY_NAME
, 0, 0, Argv
[0], "missing GUID");
2229 return STATUS_ERROR
;
2232 StringToGuid (Argv
[1], &mGlobals
.Guid
);
2233 mGlobals
.GuidSpecified
= 1;
2236 } else if (_stricmp (Argv
[0], "-v") == 0) {
2237 mGlobals
.Verbose
= 1;
2238 } else if (_stricmp (Argv
[0], "-p") == 0) {
2240 // -p option to specify an input pack file. Only valid for 'create' mode
2242 if (mGlobals
.Mode
!= MODE_CREATE_HII_EXPORT
) {
2243 Error (NULL
, 0, 0, Argv
[0], "option only valid in 'create' mode");
2244 return STATUS_ERROR
;
2247 if ((Argc
<= 1) || (Argv
[1][0] == '-')) {
2248 Error (UTILITY_NAME
, 0, 0, Argv
[0], "missing pack file name");
2249 return STATUS_ERROR
;
2252 // Consume arguments until next -arg or end
2258 // Open the file, read the pack header, and figure out what type of
2261 if ((InFptr
= fopen (Argv
[0], "rb")) == NULL
) {
2262 Error (NULL
, 0, 0, Argv
[0], "failed to open input HII pack file for reading");
2263 return STATUS_ERROR
;
2266 if (fread (&PackHeader
, sizeof (EFI_HII_PACK_HEADER
), 1, InFptr
) != 1) {
2267 Error (NULL
, 0, 0, Argv
[0], "failed to read pack header from input HII pack file");
2269 return STATUS_ERROR
;
2273 if ((PackHeader
.Type
!= EFI_HII_STRING
) &&
2274 (PackHeader
.Type
!= EFI_HII_IFR
) &&
2275 (PackHeader
.Type
!= EFI_HII_VARIABLE
)
2277 Error (NULL
, 0, 0, Argv
[0], "unsupported HII pack type 0x%X", (unsigned int) PackHeader
.Type
);
2278 return STATUS_ERROR
;
2281 // Add this file name to our list of pack files
2283 FileName
= (FILE_NAME_LIST
*) malloc (sizeof (FILE_NAME_LIST
));
2284 if (FileName
== NULL
) {
2285 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
2286 return STATUS_ERROR
;
2289 memset ((void *) FileName
, 0, sizeof (FILE_NAME_LIST
));
2290 FileName
->Tag
= (int) PackHeader
.Type
;
2291 strcpy (FileName
->FileName
, Argv
[0]);
2292 if (mGlobals
.PackFileNames
== NULL
) {
2293 mGlobals
.PackFileNames
= FileName
;
2296 // Add to the end of the list
2298 for (TempFileName
= mGlobals
.PackFileNames
; TempFileName
->Next
!= NULL
; TempFileName
= TempFileName
->Next
)
2300 TempFileName
->Next
= FileName
;
2302 } while ((Argc
> 1) && (Argv
[1][0] != '-'));
2303 } else if (_stricmp (Argv
[0], "-noemptyvarpacks") == 0) {
2304 mGlobals
.NoEmptyVarPacks
= 1;
2305 } else if (_stricmp (Argv
[0], "-novarpacks") == 0) {
2306 mGlobals
.NoVarPacks
= 1;
2307 } else if (_stricmp (Argv
[0], "-x") == 0) {
2309 // -x option to specify an input HII export file name. Not valid for 'create' mode
2311 if (mGlobals
.Mode
== MODE_CREATE_HII_EXPORT
) {
2312 Error (NULL
, 0, 0, Argv
[0], "option is not valid in 'create' mode");
2313 return STATUS_ERROR
;
2316 if ((Argc
<= 1) || (Argv
[1][0] == '-')) {
2317 Error (UTILITY_NAME
, 0, 0, Argv
[0], "missing HII export input file name");
2318 return STATUS_ERROR
;
2321 // Consume arguments until next -arg or end
2327 // Add this file name to our list of export files
2329 FileName
= (FILE_NAME_LIST
*) malloc (sizeof (FILE_NAME_LIST
));
2330 if (FileName
== NULL
) {
2331 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
2332 return STATUS_ERROR
;
2335 memset ((void *) FileName
, 0, sizeof (FILE_NAME_LIST
));
2336 strcpy (FileName
->FileName
, Argv
[0]);
2337 if (mGlobals
.HiiExportFileNames
== NULL
) {
2338 mGlobals
.HiiExportFileNames
= FileName
;
2341 // Add to the end of the list
2343 for (TempFileName
= mGlobals
.HiiExportFileNames
;
2344 TempFileName
->Next
!= NULL
;
2345 TempFileName
= TempFileName
->Next
2348 TempFileName
->Next
= FileName
;
2350 } while ((Argc
> 1) && (Argv
[1][0] != '-'));
2351 } else if (_stricmp (Argv
[0], "-dumpstrings") == 0) {
2352 mGlobals
.DumpStrings
= 1;
2353 } else if (_stricmp (Argv
[0], "-s") == 0) {
2355 // -s option to specify input HII export files using a path and file mask.
2356 // Only valid in merge mode
2358 if (mGlobals
.Mode
!= MODE_MERGE_HII_EXPORTS
) {
2359 Error (NULL
, 0, 0, Argv
[0], "option only valid in 'merge' mode");
2360 return STATUS_ERROR
;
2363 if ((Argc
<= 1) || (Argv
[1][0] == '-')) {
2364 Error (UTILITY_NAME
, 0, 0, Argv
[0], "missing root directory name");
2365 return STATUS_ERROR
;
2368 if ((Argc
<= 2) || (Argv
[2][0] == '-')) {
2369 Error (UTILITY_NAME
, 0, 0, Argv
[0], "missing file mask");
2370 return STATUS_ERROR
;
2373 // Call our function to process the directory and file mask. If
2374 // the directory does not start with c:\, then prepend cwd to it.
2376 if (FindFiles (Argv
[1], Argv
[2], FindFilesCallback
)) {
2377 Error (NULL
, 0, 0, "failed to process matching files", "%s\\%s", Argv
[1], Argv
[2]);
2378 return STATUS_ERROR
;
2383 } else if (_stricmp (Argv
[0], "-p") == 0) {
2385 // -p option to specify an input pack file. Only valid for 'create' mode
2387 if (mGlobals
.Mode
!= MODE_CREATE_HII_EXPORT
) {
2388 Error (NULL
, 0, 0, Argv
[0], "option only valid in 'create' mode");
2389 return STATUS_ERROR
;
2392 if ((Argc
<= 1) || (Argv
[1][0] == '-')) {
2393 Error (UTILITY_NAME
, 0, 0, Argv
[0], "missing pack file name");
2394 return STATUS_ERROR
;
2397 // Consume arguments until next -arg or end
2403 // Open the file, read the pack header, and figure out what type of
2406 if ((InFptr
= fopen (Argv
[0], "rb")) == NULL
) {
2407 Error (NULL
, 0, 0, Argv
[0], "failed to open input HII pack file for reading");
2408 return STATUS_ERROR
;
2411 if (fread (&PackHeader
, sizeof (EFI_HII_PACK_HEADER
), 1, InFptr
) != 1) {
2412 Error (NULL
, 0, 0, Argv
[0], "failed to read pack header from input HII pack file");
2414 return STATUS_ERROR
;
2418 if ((PackHeader
.Type
!= EFI_HII_STRING
) &&
2419 (PackHeader
.Type
!= EFI_HII_IFR
) &&
2420 (PackHeader
.Type
!= EFI_HII_VARIABLE
)
2422 Error (NULL
, 0, 0, Argv
[0], "unsupported HII pack type 0x%X", (unsigned int) PackHeader
.Type
);
2423 return STATUS_ERROR
;
2426 // Add this file name to our list of pack files
2428 FileName
= (FILE_NAME_LIST
*) malloc (sizeof (FILE_NAME_LIST
));
2429 if (FileName
== NULL
) {
2430 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
2431 return STATUS_ERROR
;
2434 memset ((void *) FileName
, 0, sizeof (FILE_NAME_LIST
));
2435 FileName
->Tag
= (int) PackHeader
.Type
;
2436 strcpy (FileName
->FileName
, Argv
[0]);
2437 if (mGlobals
.PackFileNames
== NULL
) {
2438 mGlobals
.PackFileNames
= FileName
;
2441 // Add to the end of the list
2443 for (TempFileName
= mGlobals
.PackFileNames
; TempFileName
->Next
!= NULL
; TempFileName
= TempFileName
->Next
)
2445 TempFileName
->Next
= FileName
;
2447 } while ((Argc
> 1) && (Argv
[1][0] != '-'));
2449 Error (NULL
, 0, 0, Argv
[0], "unrecognized option");
2450 return STATUS_ERROR
;
2457 // All modes except 'defaults' requires an output file name
2459 if (mGlobals
.Mode
!= MODE_EMIT_DEFAULTS
) {
2460 if (mGlobals
.OutputFileName
[0] == 0) {
2461 Error (NULL
, 0, 0, "must specify '-o OutputFileName'", NULL
);
2462 return STATUS_ERROR
;
2465 // If merging, then you have to specify at least one HII export files.
2466 // We support specifying only one file in case you want to take an export file
2467 // and emit a copy with different (for example, manufacturing) defaults.
2469 if (mGlobals
.Mode
== MODE_MERGE_HII_EXPORTS
) {
2470 if (mGlobals
.HiiExportFileNames
== NULL
) {
2471 Error (NULL
, 0, 0, "must specify at least one HII export file in 'merge' mode", NULL
);
2472 return STATUS_ERROR
;
2474 } else if (mGlobals
.Mode
== MODE_CREATE_HII_EXPORT
) {
2476 // Must have specified at least one HII pack file
2478 if (mGlobals
.PackFileNames
== NULL
) {
2479 Error (NULL
, 0, 0, "must specify at least one input HII pack file in 'create' mode", NULL
);
2480 return STATUS_ERROR
;
2485 // Must have specified an input HII export file name
2487 if (mGlobals
.HiiExportFileNames
== NULL
) {
2488 Error (NULL
, 0, 0, "must specify at least one '-x HiiExportFileName'", NULL
);
2489 return STATUS_ERROR
;
2493 return STATUS_SUCCESS
;
2503 Routine Description:
2505 Print usage information for this utility.
2518 const char *Str
[] = {
2519 UTILITY_NAME
" "UTILITY_VERSION
" - Create/Dump HII Database Files Utility",
2520 " Copyright (C), 2004 - 2008 Intel Corporation",
2521 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
2522 " Built from "UTILITY_BUILD
", project of "UTILITY_VENDOR
,
2526 " "UTILITY_NAME
" [MODE] [OPTION]",
2528 " create create an HII export file from one or more HII pack files",
2529 " merge merge two or more HII export files into one HII export file",
2530 " defaults emit variable defaults from an input HII export file",
2531 " dump ASCII dump the contents of an HII export file",
2532 "Options for all modes:",
2533 " -o FileName write output to FileName",
2534 " -mfg use manufacturing defaults from IFR rather than standard defaults",
2535 " -g GUID use GUID for a package GUID in the data tables where applicable",
2536 " -v verbose operation",
2537 "Options for 'create' mode:",
2538 " -p PackFileName(s) include contents of HII pack file PackFileName",
2539 " in the output file",
2540 " -novarpacks don't emit variable packs to the output file",
2541 "Options for 'merge' mode:",
2542 " -x HiiExportFileName(s) include contents of HII export file",
2543 " HiiExportFileName in the output file",
2544 " -s Path FileMask include all matching HII export files in Path",
2545 " and its subdirectories in the output file.",
2546 " If Path does not begin with the form C:\\, then",
2547 " it is assumed to be relative to the current working",
2548 " directory. FileMask may contain wildcard characters.",
2549 "Options for 'defaults' mode:",
2550 " -x HiiExportFileName emit defaults from all variables referenced",
2551 " in input file HiiExportFileName",
2552 " -noemptyvarpacks don't emit variable packs for 0-length variables",
2553 "Options for 'dump' mode:",
2554 " -x HiiExportFileName dump contents of input file HiiExportFileName",
2555 " -dumpstrings dump string data",
2558 for (Index
= 0; Str
[Index
] != NULL
; Index
++) {
2559 fprintf (stdout
, "%s\n", Str
[Index
]);