1 /** @file
2   This contains all code necessary to build the GenFvImage.exe utility.
3   This utility relies heavily on the GenFvImage Lib.  Definitions for both
4   can be found in the Tiano Firmware Volume Generation Utility
5   Specification, review draft.
6 
7 Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution.  The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12 
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 
16 **/
17 
18 //
19 // File included in build
20 //
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include "GenFvInternalLib.h"
25 
26 //
27 // Utility Name
28 //
29 #define UTILITY_NAME  "GenFv"
30 
31 //
32 // Utility version information
33 //
34 #define UTILITY_MAJOR_VERSION 0
35 #define UTILITY_MINOR_VERSION 1
36 
37 EFI_GUID  mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;
38 EFI_GUID  mEfiFirmwareFileSystem3Guid = EFI_FIRMWARE_FILE_SYSTEM3_GUID;
39 
40 STATIC
41 VOID
Version(VOID)42 Version (
43   VOID
44 )
45 /*++
46 
47 Routine Description:
48 
49   Displays the standard utility information to SDTOUT
50 
51 Arguments:
52 
53   None
54 
55 Returns:
56 
57   None
58 
59 --*/
60 {
61   fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
62 }
63 
64 STATIC
65 VOID
Usage(VOID)66 Usage (
67   VOID
68   )
69 /*++
70 
71 Routine Description:
72 
73   Displays the utility usage syntax to STDOUT
74 
75 Arguments:
76 
77   None
78 
79 Returns:
80 
81   None
82 
83 --*/
84 {
85   //
86   // Summary usage
87   //
88   fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);
89 
90   //
91   // Copyright declaration
92   //
93   fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
94 
95   //
96   // Details Option
97   //
98   fprintf (stdout, "Options:\n");
99   fprintf (stdout, "  -o FileName, --outputfile FileName\n\
100                         File is the FvImage or CapImage to be created.\n");
101   fprintf (stdout, "  -i FileName, --inputfile FileName\n\
102                         File is the input FV.inf or Cap.inf to specify\n\
103                         how to construct FvImage or CapImage.\n");
104   fprintf (stdout, "  -b BlockSize, --blocksize BlockSize\n\
105                         BlockSize is one HEX or DEC format value\n\
106                         BlockSize is required by Fv Image.\n");
107   fprintf (stdout, "  -n NumberBlock, --numberblock NumberBlock\n\
108                         NumberBlock is one HEX or DEC format value\n\
109                         NumberBlock is one optional parameter.\n");
110   fprintf (stdout, "  -f FfsFile, --ffsfile FfsFile\n\
111                         FfsFile is placed into Fv Image\n\
112                         multi files can input one by one\n");
113   fprintf (stdout, "  -s FileTakenSize, --filetakensize FileTakenSize\n\
114                         FileTakenSize specifies the size of the required\n\
115                         space that the input file is placed in Fvimage.\n\
116                         It is specified together with the input file.\n");
117   fprintf (stdout, "  -r Address, --baseaddr Address\n\
118                         Address is the rebase start address for drivers that\n\
119                         run in Flash. It supports DEC or HEX digital format.\n\
120                         If it is set to zero, no rebase action will be taken\n");
121   fprintf (stdout, "  -F ForceRebase, --force-rebase ForceRebase\n\
122                         If value is TRUE, will always take rebase action\n\
123                         If value is FALSE, will always not take reabse action\n\
124                         If not specified, will take rebase action if rebase address greater than zero, \n\
125                         will not take rebase action if rebase address is zero.\n");
126   fprintf (stdout, "  -a AddressFile, --addrfile AddressFile\n\
127                         AddressFile is one file used to record the child\n\
128                         FV base address when current FV base address is set.\n");
129   fprintf (stdout, "  -m logfile, --map logfile\n\
130                         Logfile is the output fv map file name. if it is not\n\
131                         given, the FvName.map will be the default map file name\n");
132   fprintf (stdout, "  -g Guid, --guid Guid\n\
133                         GuidValue is one specific capsule guid value\n\
134                         or fv file system guid value.\n\
135                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
136   fprintf (stdout, "  --FvNameGuid Guid     Guid is used to specify Fv Name.\n\
137                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
138   fprintf (stdout, "  --capflag CapFlag     Capsule Reset Flag can be PersistAcrossReset,\n\
139                         or PopulateSystemTable or InitiateReset or not set\n");
140   fprintf (stdout, "  --capoemflag CapOEMFlag\n\
141                         Capsule OEM Flag is an integer between 0x0000 and 0xffff\n");
142   fprintf (stdout, "  --capheadsize HeadSize\n\
143                         HeadSize is one HEX or DEC format value\n\
144                         HeadSize is required by Capsule Image.\n");
145   fprintf (stdout, "  -c, --capsule         Create Capsule Image.\n");
146   fprintf (stdout, "  -p, --dump            Dump Capsule Image header.\n");
147   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");
148   fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");
149   fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");
150   fprintf (stdout, "  --version             Show program's version number and exit.\n");
151   fprintf (stdout, "  -h, --help            Show this help message and exit.\n");
152 }
153 
154 UINT32 mFvTotalSize;
155 UINT32 mFvTakenSize;
156 
157 int
main(IN int argc,IN char ** argv)158 main (
159   IN int   argc,
160   IN char  **argv
161   )
162 /*++
163 
164 Routine Description:
165 
166   This utility uses GenFvImage.Lib to build a firmware volume image.
167 
168 Arguments:
169 
170   FvInfFileName      The name of an FV image description file or Capsule Image.
171 
172   Arguments come in pair in any order.
173     -I FvInfFileName
174 
175 Returns:
176 
177   EFI_SUCCESS            No error conditions detected.
178   EFI_INVALID_PARAMETER  One or more of the input parameters is invalid.
179   EFI_OUT_OF_RESOURCES   A resource required by the utility was unavailable.
180                          Most commonly this will be memory allocation
181                          or file creation.
182   EFI_LOAD_ERROR         GenFvImage.lib could not be loaded.
183   EFI_ABORTED            Error executing the GenFvImage lib.
184 
185 --*/
186 {
187   EFI_STATUS            Status;
188   CHAR8                 *InfFileName;
189   CHAR8                 *AddrFileName;
190   CHAR8                 *MapFileName;
191   CHAR8                 *InfFileImage;
192   UINT32                InfFileSize;
193   CHAR8                 *OutFileName;
194   BOOLEAN               CapsuleFlag;
195   BOOLEAN               DumpCapsule;
196   FILE                  *FpFile;
197   EFI_CAPSULE_HEADER    *CapsuleHeader;
198   UINT64                LogLevel, TempNumber;
199   UINT32                Index;
200 
201   InfFileName   = NULL;
202   AddrFileName  = NULL;
203   InfFileImage  = NULL;
204   OutFileName   = NULL;
205   MapFileName   = NULL;
206   InfFileSize   = 0;
207   CapsuleFlag   = FALSE;
208   DumpCapsule   = FALSE;
209   FpFile        = NULL;
210   CapsuleHeader = NULL;
211   LogLevel      = 0;
212   TempNumber    = 0;
213   Index         = 0;
214   mFvTotalSize  = 0;
215   mFvTakenSize  = 0;
216   Status        = EFI_SUCCESS;
217 
218   SetUtilityName (UTILITY_NAME);
219 
220   if (argc == 1) {
221     Error (NULL, 0, 1001, "Missing options", "No input options specified.");
222     Usage ();
223     return STATUS_ERROR;
224   }
225 
226   //
227   // Init global data to Zero
228   //
229   memset (&mFvDataInfo, 0, sizeof (FV_INFO));
230   memset (&mCapDataInfo, 0, sizeof (CAP_INFO));
231   //
232   // Set the default FvGuid
233   //
234   memcpy (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid, sizeof (EFI_GUID));
235   mFvDataInfo.ForceRebase = -1;
236 
237   //
238   // Parse command line
239   //
240   argc --;
241   argv ++;
242 
243   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
244     Version ();
245     Usage ();
246     return STATUS_SUCCESS;
247   }
248 
249   if (stricmp (argv[0], "--version") == 0) {
250     Version ();
251     return STATUS_SUCCESS;
252   }
253 
254   while (argc > 0) {
255     if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {
256       InfFileName = argv[1];
257       if (InfFileName == NULL) {
258         Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");
259         return STATUS_ERROR;
260       }
261       argc -= 2;
262       argv += 2;
263       continue;
264     }
265 
266     if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {
267       AddrFileName = argv[1];
268       if (AddrFileName == NULL) {
269         Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");
270         return STATUS_ERROR;
271       }
272       argc -= 2;
273       argv += 2;
274       continue;
275     }
276 
277     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
278       OutFileName = argv[1];
279       if (OutFileName == NULL) {
280         Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");
281         return STATUS_ERROR;
282       }
283       argc -= 2;
284       argv += 2;
285       continue;
286     }
287 
288     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {
289       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
290       if (EFI_ERROR (Status)) {
291         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
292         return STATUS_ERROR;
293       }
294       mFvDataInfo.BaseAddress    = TempNumber;
295       mFvDataInfo.BaseAddressSet = TRUE;
296       argc -= 2;
297       argv += 2;
298       continue;
299     }
300 
301     if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {
302       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
303       if (EFI_ERROR (Status)) {
304         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
305         return STATUS_ERROR;
306       }
307       if (TempNumber == 0) {
308         Error (NULL, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");
309         return STATUS_ERROR;
310       }
311       mFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;
312       DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%llx", EFI_BLOCK_SIZE_STRING, (unsigned long long) TempNumber);
313       argc -= 2;
314       argv += 2;
315       continue;
316     }
317 
318     if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {
319       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
320       if (EFI_ERROR (Status)) {
321         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
322         return STATUS_ERROR;
323       }
324       if (TempNumber == 0) {
325         Error (NULL, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");
326         return STATUS_ERROR;
327       }
328       mFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;
329       DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%llx", EFI_NUM_BLOCKS_STRING, (unsigned long long) TempNumber);
330       argc -= 2;
331       argv += 2;
332       continue;
333     }
334 
335     if ((strcmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {
336       if (argv[1] == NULL) {
337         Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");
338         return STATUS_ERROR;
339       }
340       strcpy (mFvDataInfo.FvFiles[Index], argv[1]);
341       DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index + 1, argv[1]);
342       argc -= 2;
343       argv += 2;
344 
345       if (argc > 0) {
346 		    if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
347 		      if (argv[1] == NULL) {
348 		        Error (NULL, 0, 1003, "Invalid option value", "Ffsfile Size can't be null");
349 		        return STATUS_ERROR;
350 		      }
351 		      Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
352 		      if (EFI_ERROR (Status)) {
353 		        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
354 		        return STATUS_ERROR;
355 		      }
356 		      mFvDataInfo.SizeofFvFiles[Index] = (UINT32) TempNumber;
357 	      	DebugMsg (NULL, 0, 9, "FV component file size", "the %uth size is %s", (unsigned) Index + 1, argv[1]);
358 	      	argc -= 2;
359 	      	argv += 2;
360         }
361       }
362       Index ++;
363       continue;
364     }
365 
366     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
367       Error (NULL, 0, 1003, "Invalid option", "It must be specified together with -f option to specify the file size.");
368       return STATUS_ERROR;
369     }
370 
371     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {
372       CapsuleFlag = TRUE;
373       argc --;
374       argv ++;
375       continue;
376     }
377 
378     if ((strcmp (argv[0], "-F") == 0) || (stricmp (argv[0], "--force-rebase") == 0)) {
379       if (argv[1] == NULL) {
380         Error (NULL, 0, 1003, "Invalid option value", "Froce rebase flag can't be null");
381         return STATUS_ERROR;
382       }
383 
384       if (stricmp (argv[1], "TRUE") == 0) {
385         mFvDataInfo.ForceRebase = 1;
386       } else if (stricmp (argv[1], "FALSE") == 0) {
387         mFvDataInfo.ForceRebase = 0;
388       } else {
389         Error (NULL, 0, 1003, "Invalid option value", "froce rebase flag value must be \"TRUE\" or \"FALSE\"");
390         return STATUS_ERROR;
391       }
392 
393       argc -= 2;
394       argv += 2;
395       continue;
396     }
397 
398     if (stricmp (argv[0], "--capheadsize") == 0) {
399       //
400       // Get Capsule Image Header Size
401       //
402       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
403       if (EFI_ERROR (Status)) {
404         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
405         return STATUS_ERROR;
406       }
407       mCapDataInfo.HeaderSize = (UINT32) TempNumber;
408       DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%llx", EFI_CAPSULE_HEADER_SIZE_STRING, (unsigned long long) TempNumber);
409       argc -= 2;
410       argv += 2;
411       continue;
412     }
413 
414     if (stricmp (argv[0], "--capflag") == 0) {
415       //
416       // Get Capsule Header
417       //
418       if (argv[1] == NULL) {
419         Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);
420         return STATUS_ERROR;
421       }
422       if (strcmp (argv[1], "PopulateSystemTable") == 0) {
423         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;
424       } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {
425         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
426       } else if (strcmp (argv[1], "InitiateReset") == 0) {
427         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET;
428       } else {
429         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
430         return STATUS_ERROR;
431       }
432       DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);
433       argc -= 2;
434       argv += 2;
435       continue;
436     }
437 
438     if (stricmp (argv[0], "--capoemflag") == 0) {
439       if (argv[1] == NULL) {
440         Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag can't be null");
441       }
442       Status = AsciiStringToUint64(argv[1], FALSE, &TempNumber);
443       if (EFI_ERROR (Status) || TempNumber > 0xffff) {
444         Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag value must be integer value between 0x0000 and 0xffff");
445         return STATUS_ERROR;
446       }
447       mCapDataInfo.Flags |= TempNumber;
448       DebugMsg( NULL, 0, 9, "Capsule OEM Flags", argv[1]);
449       argc -= 2;
450       argv += 2;
451       continue;
452     }
453 
454     if (stricmp (argv[0], "--capguid") == 0) {
455       //
456       // Get the Capsule Guid
457       //
458       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
459       if (EFI_ERROR (Status)) {
460         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
461         return STATUS_ERROR;
462       }
463       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
464       argc -= 2;
465       argv += 2;
466       continue;
467     }
468 
469     if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {
470       //
471       // Get the Capsule or Fv Guid
472       //
473       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
474       if (EFI_ERROR (Status)) {
475         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
476         return STATUS_ERROR;
477       }
478       memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));
479       mFvDataInfo.FvFileSystemGuidSet = TRUE;
480       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
481       DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);
482       argc -= 2;
483       argv += 2;
484       continue;
485     }
486 
487     if (stricmp (argv[0], "--FvNameGuid") == 0) {
488       //
489       // Get Fv Name Guid
490       //
491       Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);
492       if (EFI_ERROR (Status)) {
493         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
494         return STATUS_ERROR;
495       }
496       mFvDataInfo.FvNameGuidSet = TRUE;
497       DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);
498       argc -= 2;
499       argv += 2;
500       continue;
501     }
502 
503     if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {
504       DumpCapsule = TRUE;
505       argc --;
506       argv ++;
507       continue;
508     }
509 
510     if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {
511       MapFileName = argv[1];
512       if (MapFileName == NULL) {
513         Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");
514         return STATUS_ERROR;
515       }
516       argc -= 2;
517       argv += 2;
518       continue;
519     }
520 
521     if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
522       SetPrintLevel (VERBOSE_LOG_LEVEL);
523       VerboseMsg ("Verbose output Mode Set!");
524       argc --;
525       argv ++;
526       continue;
527     }
528 
529     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
530       SetPrintLevel (KEY_LOG_LEVEL);
531       KeyMsg ("Quiet output Mode Set!");
532       argc --;
533       argv ++;
534       continue;
535     }
536 
537     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
538       Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
539       if (EFI_ERROR (Status)) {
540         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
541         return STATUS_ERROR;
542       }
543       if (LogLevel > 9) {
544         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
545         return STATUS_ERROR;
546       }
547       SetPrintLevel (LogLevel);
548       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
549       argc -= 2;
550       argv += 2;
551       continue;
552     }
553 
554     //
555     // Don't recognize the parameter.
556     //
557     Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);
558     return STATUS_ERROR;
559   }
560 
561   VerboseMsg ("%s tool start.", UTILITY_NAME);
562 
563   //
564   // check input parameter, InfFileName can be NULL
565   //
566   if (InfFileName == NULL && DumpCapsule) {
567     Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");
568     return STATUS_ERROR;
569   }
570   VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);
571 
572   if (!DumpCapsule && OutFileName == NULL) {
573     Error (NULL, 0, 1001, "Missing option", "Output File");
574     return STATUS_ERROR;
575   }
576   if (OutFileName != NULL) {
577     VerboseMsg ("the output file name is %s", OutFileName);
578   }
579 
580   //
581   // Read the INF file image
582   //
583   if (InfFileName != NULL) {
584     Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);
585     if (EFI_ERROR (Status)) {
586       return STATUS_ERROR;
587     }
588   }
589 
590   if (DumpCapsule) {
591     VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);
592     //
593     // Dump Capsule Image Header Information
594     //
595     CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;
596     if (OutFileName == NULL) {
597       FpFile = stdout;
598     } else {
599       FpFile = fopen (LongFilePath (OutFileName), "w");
600       if (FpFile == NULL) {
601         Error (NULL, 0, 0001, "Error opening file", OutFileName);
602         return STATUS_ERROR;
603       }
604     }
605     fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);
606     fprintf (FpFile, "  GUID                  %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
607                     (unsigned) CapsuleHeader->CapsuleGuid.Data1,
608                     (unsigned) CapsuleHeader->CapsuleGuid.Data2,
609                     (unsigned) CapsuleHeader->CapsuleGuid.Data3,
610                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[0],
611                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[1],
612                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[2],
613                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[3],
614                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[4],
615                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[5],
616                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[6],
617                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[7]);
618     fprintf (FpFile, "  Header size           0x%08X\n", (unsigned) CapsuleHeader->HeaderSize);
619     fprintf (FpFile, "  Flags                 0x%08X\n", (unsigned) CapsuleHeader->Flags);
620     fprintf (FpFile, "  Capsule image size    0x%08X\n", (unsigned) CapsuleHeader->CapsuleImageSize);
621     fclose (FpFile);
622   } else if (CapsuleFlag) {
623     VerboseMsg ("Create capsule image");
624     //
625     // Call the GenerateCapImage to generate Capsule Image
626     //
627     for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {
628       strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);
629     }
630 
631     Status = GenerateCapImage (
632               InfFileImage,
633               InfFileSize,
634               OutFileName
635               );
636   } else {
637     VerboseMsg ("Create Fv image and its map file");
638     //
639     // Will take rebase action at below situation:
640     // 1. ForceRebase Flag specified to TRUE;
641     // 2. ForceRebase Flag not specified, BaseAddress greater than zero.
642     //
643     if (((mFvDataInfo.BaseAddress > 0) && (mFvDataInfo.ForceRebase == -1)) || (mFvDataInfo.ForceRebase == 1)) {
644       VerboseMsg ("FvImage Rebase Address is 0x%llX", (unsigned long long) mFvDataInfo.BaseAddress);
645     }
646     //
647     // Call the GenerateFvImage to generate Fv Image
648     //
649     Status = GenerateFvImage (
650               InfFileImage,
651               InfFileSize,
652               OutFileName,
653               MapFileName
654               );
655   }
656 
657   //
658   // free InfFileImage memory
659   //
660   if (InfFileImage != NULL) {
661     free (InfFileImage);
662   }
663 
664   //
665   //  update boot driver address and runtime driver address in address file
666   //
667   if (Status == EFI_SUCCESS && AddrFileName != NULL && mFvBaseAddressNumber > 0) {
668     FpFile = fopen (LongFilePath (AddrFileName), "w");
669     if (FpFile == NULL) {
670       Error (NULL, 0, 0001, "Error opening file", AddrFileName);
671       return STATUS_ERROR;
672     }
673     fprintf (FpFile, FV_BASE_ADDRESS_STRING);
674     fprintf (FpFile, "\n");
675     for (Index = 0; Index < mFvBaseAddressNumber; Index ++) {
676       fprintf (
677         FpFile,
678         "0x%llx\n",
679         (unsigned long long)mFvBaseAddress[Index]
680         );
681     }
682     fflush (FpFile);
683     fclose (FpFile);
684   }
685 
686   if (Status == EFI_SUCCESS) {
687     DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);
688     DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);
689     DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, (unsigned) (mFvTotalSize - mFvTakenSize));
690   }
691 
692   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
693 
694   return GetUtilityStatus ();
695 }
696