3 The main entry of BFM tool.
5 Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "BinFileManager.h"
12 BOOLEAN mFvGuidIsSet
= FALSE
;
13 EFI_GUID mFvNameGuid
= {0};
14 CHAR8
* mFvNameGuidString
= NULL
;
15 CHAR8
* mGuidToolDefinition
= "GuidToolDefinitionConf.ini";
18 // Store GUIDed Section guid->tool mapping
20 EFI_HANDLE mParsedGuidedSectionTools
= NULL
;
24 Search the config file from the path list.
26 Split the path from env PATH, and then search the cofig
27 file from these paths. The priority is from left to
28 right of PATH string. When met the first Config file, it
29 will break and return the pointer to the full file name.
31 @param PathList the pointer to the path list.
32 @param FileName the pointer to the file name.
34 @retval The pointer to the file name.
35 @return NULL An error occurred.
38 SearchConfigFromPathList (
49 CurDir
= strtok (PathList
,";");
51 CurDir
= strtok (PathList
,":");
53 while (CurDir
!= NULL
) {
54 FileNamePath
= (char *)calloc(
55 strlen (CurDir
) + strlen (OS_SEP_STR
) +strlen (FileName
) + 1,
58 if (FileNamePath
== NULL
) {
61 sprintf(FileNamePath
, "%s%c%s", CurDir
, OS_SEP
, FileName
);
62 if (access (FileNamePath
, 0) != -1) {
66 CurDir
= strtok(NULL
, ";");
68 CurDir
= strtok(NULL
, ":");
78 Show the FD image layout information. Only display the modules with UI name.
80 @param[in] FdInName Input FD binary/image file name;
81 @param[in] FvName The FV ID in the FD file;
82 @param[in] ViewFlag Is this call for view or other operate(add/del/replace)
83 @param[in] FdData The Fd data structure store the FD information.
86 @retval EFI_INVALID_PARAMETER
95 IN FIRMWARE_DEVICE
**FdData
99 FIRMWARE_DEVICE
*LocalFdData
;
100 FV_INFORMATION
*CurrentFv
;
104 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
;
119 // Check the FD file name/path.
121 if (FdInName
== NULL
) {
122 return EFI_INVALID_PARAMETER
;
126 // Open the file containing the FV
128 InputFile
= fopen (FdInName
, "rb");
129 if (InputFile
== NULL
) {
130 return EFI_INVALID_PARAMETER
;
133 Status
= LibFindFvInFd (InputFile
, &LocalFdData
);
135 if (EFI_ERROR(Status
)) {
140 CurrentFv
= LocalFdData
->Fv
;
144 memset (CurrentFv
->FvName
, '\0', _MAX_PATH
);
146 if (LastFvNumber
== 0) {
147 sprintf (CurrentFv
->FvName
, "FV%d", LastFvNumber
);
149 sprintf (CurrentFv
->FvName
, "FV%d", LastFvNumber
);
153 // Determine size of FV
155 if (fseek (InputFile
, CurrentFv
->ImageAddress
, SEEK_SET
) != 0) {
157 LibBfmFreeFd( LocalFdData
);
161 Status
= LibGetFvSize(InputFile
, &FvSize
);
162 if (EFI_ERROR (Status
)) {
168 // Seek to the start of the image, then read the entire FV to the buffer
170 fseek (InputFile
, CurrentFv
->ImageAddress
, SEEK_SET
);
172 FvImage
= (EFI_FIRMWARE_VOLUME_HEADER
*) malloc (FvSize
);
174 if (FvImage
== NULL
) {
176 LibBfmFreeFd( LocalFdData
);
180 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
181 if ((unsigned int) BytesRead
!= FvSize
) {
184 LibBfmFreeFd( LocalFdData
);
189 // Collect FV information each by each.
191 Status
= LibGetFvInfo (FvImage
, CurrentFv
, FvName
, 0, &FfsCount
, ViewFlag
, FALSE
);
194 if (EFI_ERROR (Status
)) {
196 LibBfmFreeFd( LocalFdData
);
199 FvCount
= CurrentFv
->FvLevel
;
200 LastFvNumber
= LastFvNumber
+FvCount
;
204 CurrentFv
= CurrentFv
->FvNext
;
206 } while (CurrentFv
!= NULL
);
209 *FdData
= LocalFdData
;
211 LibBfmFreeFd( LocalFdData
);
220 Add an FFS file into a specify FV.
222 @param[in] FdInName Input FD binary/image file name;
223 @param[in] NewFile The name of the file add in;
224 @param[in] FdOutName Name of output fd file.
227 @retval EFI_INVALID_PARAMETER
239 FIRMWARE_DEVICE
*FdData
;
240 FV_INFORMATION
*FvInFd
;
241 ENCAP_INFO_DATA
*LocalEncapData
;
242 ENCAP_INFO_DATA
*LocalEncapDataTemp
;
250 UINT8 NewAddedFfsLevel
;
251 BOOLEAN FfsLevelFoundFlag
;
252 CHAR8
*OutputFileName
;
255 BOOLEAN FvGuidExisted
;
259 NewAddedFfsLevel
= 0;
261 FfsLevelFoundFlag
= FALSE
;
265 LocalEncapData
= NULL
;
270 LocalEncapDataTemp
= NULL
;
271 OutputFileName
= NULL
;
273 FvGuidExisted
= FALSE
;
276 // Get the size of ffs file to be inserted.
278 NewFfsLength
= GetFileSize(NewFile
);
280 Status
= BfmImageView (FdInName
, NULL
, FALSE
, &FdData
);
282 if (EFI_ERROR (Status
)) {
283 printf ("Error while parse %s FD image.\n", FdInName
);
287 // Check the FvGuid whether exists or not when the BIOS hasn't default setting.
288 // If the FV image with -g GUID can't be found, the storage is still saved into the BFV and report warning message.
292 if (mFvGuidIsSet
&& FvInFd
->IsInputFvFlag
) {
293 FvGuidExisted
= TRUE
;
296 FvInFd
= FvInFd
->FvNext
;
297 } while (FvInFd
!= NULL
);
299 if (mFvGuidIsSet
&& !FvGuidExisted
) {
300 printf ("Fv image with the specified FV Name Guid %s can't be found in current FD.\n", mFvNameGuidString
);
301 LibBfmFreeFd(FdData
);
305 // Iterate to write FFS to each BFV.
309 if ((FvGuidExisted
&& mFvGuidIsSet
&& FvInFd
->IsInputFvFlag
) || ((!FvGuidExisted
|| (!mFvGuidIsSet
)) && FvInFd
->IsBfvFlag
)) {
311 Status
= LibLocateBfv (FdData
, &FvId
, &FvInFd
);
313 if (EFI_ERROR (Status
)) {
314 printf("Error while locate BFV from FD.\n");
315 LibBfmFreeFd(FdData
);
320 // Determine the new added ffs file level in the FV.
322 LocalEncapData
= FvInFd
->EncapData
;
324 while (LocalEncapData
!= NULL
&& !FfsLevelFoundFlag
) {
325 if (LocalEncapData
->Type
== BFM_ENCAP_TREE_FV
) {
326 if (FvEncapLevel
== ((UINT8
) atoi (FvId
+ 2) - (UINT8
) atoi (FvInFd
->FvName
+ 2))) {
328 // Found the FFS level in this FV.
330 LocalEncapDataTemp
= LocalEncapData
;
331 while (LocalEncapDataTemp
!= NULL
) {
332 if (LocalEncapDataTemp
->Type
== BFM_ENCAP_TREE_FFS
) {
333 NewAddedFfsLevel
= LocalEncapDataTemp
->Level
;
334 FfsLevelFoundFlag
= TRUE
;
337 if (LocalEncapDataTemp
->NextNode
!= NULL
) {
338 LocalEncapDataTemp
= LocalEncapDataTemp
->NextNode
;
347 if (LocalEncapData
->NextNode
== NULL
) {
350 LocalEncapData
= LocalEncapData
->NextNode
;
355 // Add the new file into FV.
357 FvInFd
->FfsNumbers
+= 1;
358 if (strlen (NewFile
) > _MAX_PATH
- 1) {
359 printf ("The NewFile name is too long \n");
360 LibBfmFreeFd(FdData
);
363 strncpy (FvInFd
->FfsAttuibutes
[FvInFd
->FfsNumbers
].FfsName
, NewFile
, _MAX_PATH
- 1);
364 FvInFd
->FfsAttuibutes
[FvInFd
->FfsNumbers
].FfsName
[_MAX_PATH
- 1] = 0;
365 FvInFd
->FfsAttuibutes
[FvInFd
->FfsNumbers
].Level
= NewAddedFfsLevel
;
367 TemDir
= getcwd (NULL
, _MAX_PATH
);
368 if (strlen (TemDir
) + strlen (OS_SEP_STR
) + strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
369 printf ("The directory is too long \n");
370 LibBfmFreeFd(FdData
);
373 strncat (TemDir
, OS_SEP_STR
, _MAX_PATH
- strlen (TemDir
) - 1);
374 strncat (TemDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen (TemDir
) - 1);
375 mkdir(TemDir
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
376 Status
= LibEncapNewFvFile (FvInFd
, TemDir
, &OutputFileName
);
378 if (EFI_ERROR (Status
)) {
379 printf("Error. The boot firmware volume (BFV) has only the spare space 0x%lx bytes. But the default setting data takes 0x%llx bytes, which can't be inserted into BFV. \n",(unsigned long) GetBfvPadSize (), (unsigned long long)NewFfsLength
);
380 LibBfmFreeFd(FdData
);
386 // Write New Fv file into the NewFd file.
388 Status
= LibCreateNewFdCopy (FdInName
, FdOutName
);
389 if (EFI_ERROR (Status
)) {
390 printf("Error while copy from %s to %s file. \n", FdInName
, FdOutName
);
391 LibBfmFreeFd(FdData
);
397 NewFdFile
= fopen (FdOutName
, "rb+");
398 if (NewFdFile
== NULL
) {
399 printf("Error while create FD file %s. \n", FdOutName
);
400 LibBfmFreeFd(FdData
);
404 NewFvFile
= fopen (OutputFileName
, "rb+");
406 if (NewFvFile
== NULL
) {
407 printf("Error while create Fv file %s. \n", OutputFileName
);
409 LibBfmFreeFd(FdData
);
413 fseek(NewFvFile
,0,SEEK_SET
);
414 fseek(NewFvFile
,0,SEEK_END
);
416 NewFvLength
= ftell(NewFvFile
);
418 fseek(NewFvFile
,0,SEEK_SET
);
420 Buffer
= malloc ((size_t)NewFvLength
);
422 if (Buffer
== NULL
) {
423 printf ("Error while allocate resource! \n");
426 LibBfmFreeFd(FdData
);
430 if (fread (Buffer
, 1, (size_t) NewFvLength
, NewFvFile
) != (size_t) NewFvLength
) {
431 printf("Error while reading Fv file %s. \n", OutputFileName
);
435 LibBfmFreeFd(FdData
);
439 fseek(NewFdFile
, FvInFd
->ImageAddress
, SEEK_SET
);
440 fseek(NewFdFile
, FvInFd
->ImageAddress
, SEEK_SET
);
442 if (NewFvLength
<= FvInFd
->FvHeader
->FvLength
) {
443 if (fwrite (Buffer
, 1, (size_t) NewFvLength
, NewFdFile
) != (size_t) NewFvLength
) {
444 printf("Error while writing FD file %s. \n", FdOutName
);
448 LibBfmFreeFd(FdData
);
452 printf("Error. The new size of BFV is 0x%llx bytes, which is larger than the previous size of BFV 0x%llx bytes. \n", (unsigned long long) NewFvLength
, (unsigned long long) FvInFd
->FvHeader
->FvLength
);
456 LibBfmFreeFd(FdData
);
466 FvInFd
= FvInFd
->FvNext
;
467 } while (FvInFd
!= NULL
);
470 LibBfmFreeFd(FdData
);
472 if (TemDir
== NULL
) {
474 printf ("Fv image with the specified FV Name Guid %s can't be found.\n", mFvNameGuidString
);
476 printf ("BFV image can't be found.\n");
478 return EFI_NOT_FOUND
;
481 Status
= LibRmDir (TemDir
);
483 if (EFI_ERROR (Status
)) {
484 printf("Error while remove temporary directory. \n");
493 Replace an FFS file into a specify FV.
495 @param[in] FdInName Input FD binary/image file name;
496 @param[in] NewFile The name of the file add in;
497 @param[in] FdOutName Name of output fd file.
500 @retval EFI_INVALID_PARAMETER
512 FIRMWARE_DEVICE
*FdData
;
513 FV_INFORMATION
*FvInFd
;
520 CHAR8
*OutputFileName
;
524 BOOLEAN FvToBeUpdate
;
526 ENCAP_INFO_DATA
*LocalEncapData
;
527 ENCAP_INFO_DATA
*LocalEncapDataTemp
;
529 UINT8 NewAddedFfsLevel
;
530 BOOLEAN FfsLevelFoundFlag
;
531 EFI_GUID EfiNewAddToBfvGuid
;
534 BOOLEAN ReplaceSameFv
;
535 BOOLEAN FvGuidExisted
;
546 OutputFileName
= NULL
;
550 ReplaceSameFv
= FALSE
;
551 FvGuidExisted
= FALSE
;
554 // Get the size of ffs file to be inserted.
556 NewFfsLength
= GetFileSize(NewFile
);
560 FfsFile
= fopen (NewFile
, "rb");
561 if (FfsFile
== NULL
) {
562 printf ("Error while read %s.\n", NewFile
);
565 fseek (FfsFile
, 0, SEEK_SET
);
566 BytesRead
= fread (&EfiNewAddToBfvGuid
, 1, sizeof(EFI_GUID
), FfsFile
);
568 if (BytesRead
!= sizeof(EFI_GUID
)) {
569 printf ("Error while read the GUID from %s.\n", NewFile
);
572 Status
= BfmImageView (FdInName
, NULL
, FALSE
, &FdData
);
574 if (EFI_ERROR (Status
)) {
575 printf ("Error while parse %s FD image.\n", FdInName
);
580 // Check the FvGuid whether exists or not when the BIOS has default setting.
581 // 1. No option means the storage is saved into the same FV image.
582 // 2. The FV image with -g GUID can't be found. The storage is still saved into the same FV image and report warning message.
585 ReplaceSameFv
= TRUE
;
589 if (mFvGuidIsSet
&& FvInFd
->IsInputFvFlag
) {
590 FvGuidExisted
= TRUE
;
593 FvInFd
= FvInFd
->FvNext
;
594 } while (FvInFd
!= NULL
);
596 if (mFvGuidIsSet
&& !FvGuidExisted
) {
597 printf ("Fv image with the specified FV Name Guid %s can't be found in current FD.\n", mFvNameGuidString
);
598 ReplaceSameFv
= TRUE
;
599 LibBfmFreeFd(FdData
);
603 // Interate to insert or replace default setting to Fv
607 FvToBeUpdate
= FALSE
;
608 if (mFvGuidIsSet
&& FvInFd
->IsInputFvFlag
) {
612 Status
= LibLocateBfv (FdData
, &FvId
, &FvInFd
);
614 if (EFI_ERROR (Status
)) {
615 printf("Error while locate BFV from FD.\n");
616 LibBfmFreeFd(FdData
);
621 while (Index
<= FvInFd
->FfsNumbers
) {
623 // Locate the multi-platform ffs in Fv and then replace or delete it.
625 if (!CompareGuid(&FvInFd
->FfsHeader
[Index
].Name
, &EfiNewAddToBfvGuid
)) {
634 if (FvToBeUpdate
|| (Index
<= FvInFd
->FfsNumbers
)) {
637 if (Index
<= FvInFd
->FfsNumbers
) {
639 // Override original default data by New File
641 if (strlen (NewFile
) > _MAX_PATH
- 1) {
642 printf ("The NewFile name is too long \n");
643 LibBfmFreeFd(FdData
);
646 strncpy (FvInFd
->FfsAttuibutes
[Index
].FfsName
, NewFile
, _MAX_PATH
- 1);
647 FvInFd
->FfsAttuibutes
[Index
].FfsName
[_MAX_PATH
- 1] = 0;
649 FfsLevelFoundFlag
= FALSE
;
651 NewAddedFfsLevel
= 0;
653 // Determine the new added ffs file level in the FV.
655 LocalEncapData
= FvInFd
->EncapData
;
657 while (LocalEncapData
!= NULL
&& !FfsLevelFoundFlag
) {
658 if (LocalEncapData
->Type
== BFM_ENCAP_TREE_FV
) {
659 if (FvEncapLevel
== ((UINT8
) atoi (FvId
+ 2) - (UINT8
) atoi (FvInFd
->FvName
+ 2))) {
661 // Found the FFS level in this FV.
663 LocalEncapDataTemp
= LocalEncapData
;
664 while (LocalEncapDataTemp
!= NULL
) {
665 if (LocalEncapDataTemp
->Type
== BFM_ENCAP_TREE_FFS
) {
666 NewAddedFfsLevel
= LocalEncapDataTemp
->Level
;
667 FfsLevelFoundFlag
= TRUE
;
670 if (LocalEncapDataTemp
->NextNode
!= NULL
) {
671 LocalEncapDataTemp
= LocalEncapDataTemp
->NextNode
;
680 if (LocalEncapData
->NextNode
== NULL
) {
683 LocalEncapData
= LocalEncapData
->NextNode
;
688 // Add the new file into FV.
690 FvInFd
->FfsNumbers
+= 1;
691 memcpy (FvInFd
->FfsAttuibutes
[FvInFd
->FfsNumbers
].FfsName
, NewFile
, _MAX_PATH
);
692 FvInFd
->FfsAttuibutes
[FvInFd
->FfsNumbers
].Level
= NewAddedFfsLevel
;
696 // Remove original default data from FV.
698 FvInFd
->FfsAttuibutes
[Index
].FfsName
[0] = '\0';
701 if (TemDir
== NULL
) {
702 TemDir
= getcwd (NULL
, _MAX_PATH
);
703 if (strlen (TemDir
) + strlen (OS_SEP_STR
)+ strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
704 printf ("The directory is too long \n");
705 LibBfmFreeFd(FdData
);
708 strncat (TemDir
, OS_SEP_STR
, _MAX_PATH
- strlen (TemDir
) - 1);
709 strncat (TemDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen (TemDir
) - 1);
710 mkdir(TemDir
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
713 Status
= LibEncapNewFvFile (FvInFd
, TemDir
, &OutputFileName
);
715 if (EFI_ERROR (Status
)) {
716 printf("Error. The boot firmware volume (BFV) has only the spare space 0x%lx bytes. But the default setting data takes 0x%llx bytes, which can't be inserted into BFV. \n", (unsigned long) GetBfvPadSize (), (unsigned long long) NewFfsLength
);
717 LibBfmFreeFd(FdData
);
723 // Write New Fv file into the NewFd file.
725 Status
= LibCreateNewFdCopy (FdInName
, FdOutName
);
726 if (EFI_ERROR (Status
)) {
727 printf("Error while copy from %s to %s file. \n", FdInName
, FdOutName
);
728 LibBfmFreeFd(FdData
);
734 NewFdFile
= fopen (FdOutName
, "rb+");
735 if (NewFdFile
== NULL
) {
736 printf("Error while create FD file %s. \n", FdOutName
);
737 LibBfmFreeFd(FdData
);
741 NewFvFile
= fopen (OutputFileName
, "rb+");
743 if (NewFvFile
== NULL
) {
744 printf("Error while create Fv file %s. \n", OutputFileName
);
745 LibBfmFreeFd(FdData
);
750 fseek(NewFvFile
,0,SEEK_SET
);
751 fseek(NewFvFile
,0,SEEK_END
);
753 NewFvLength
= ftell(NewFvFile
);
755 fseek(NewFvFile
,0,SEEK_SET
);
757 Buffer
= malloc ((size_t)NewFvLength
);
759 if (Buffer
== NULL
) {
760 LibBfmFreeFd(FdData
);
766 if (fread (Buffer
, 1, (size_t) NewFvLength
, NewFvFile
) != (size_t) NewFvLength
) {
767 printf("Error while read Fv file %s. \n", OutputFileName
);
768 LibBfmFreeFd(FdData
);
775 fseek(NewFdFile
, FvInFd
->ImageAddress
, SEEK_SET
);
776 fseek(NewFdFile
, FvInFd
->ImageAddress
, SEEK_SET
);
778 if (NewFvLength
<= FvInFd
->FvHeader
->FvLength
) {
779 if (fwrite (Buffer
, 1, (size_t) NewFvLength
, NewFdFile
) != (size_t) NewFvLength
) {
780 printf("Error while write FD file %s. \n", FdOutName
);
783 LibBfmFreeFd(FdData
);
788 printf("Error. The new size of BFV is 0x%llx bytes, which is larger than the previous size of BFV 0x%llx bytes. \n", (unsigned long long) NewFvLength
, (unsigned long long) FvInFd
->FvHeader
->FvLength
);
790 LibBfmFreeFd(FdData
);
802 FvInFd
= FvInFd
->FvNext
;
803 } while (FvInFd
!= NULL
);
805 LibBfmFreeFd(FdData
);
807 if (TemDir
== NULL
|| !FdIsUpdate
) {
809 printf ("Fv image with the specified FV Name Guid %s can't be found.\n", mFvNameGuidString
);
811 printf ("BFV image can't be found.\n");
813 return EFI_NOT_FOUND
;
816 Status
= LibRmDir (TemDir
);
818 if (EFI_ERROR (Status
)) {
819 printf("Error while remove temporary directory. \n");
828 The main entry of BFM tool.
837 FIRMWARE_DEVICE
*FdData
;
839 CHAR8 FullGuidToolDefinition
[_MAX_PATH
];
856 // Save, skip filename arg
861 if ((stricmp(Argv
[0], "-v") == 0)) {
863 // Check the revison of BfmLib
866 printf("%s\n", __BUILD_VERSION
);
871 // Workaroud: the first call to this function
872 // returns a file name ends with dot
877 CHAR8 tmp
[] = "/tmp/fileXXXXXX";
879 Fdtmp
= mkstemp(tmp
);
883 // Get the same path with the application itself
885 if (strlen (FileName
) > _MAX_PATH
- 1) {
886 Error (NULL
, 0, 2000, "Parameter: Input file name is too long", NULL
);
889 strncpy (FullGuidToolDefinition
, FileName
, _MAX_PATH
- 1);
890 FullGuidToolDefinition
[_MAX_PATH
- 1] = 0;
891 FileNameIndex
= strlen (FullGuidToolDefinition
);
892 while (FileNameIndex
!= 0) {
894 if (FullGuidToolDefinition
[FileNameIndex
] == OS_SEP
) {
895 FullGuidToolDefinition
[FileNameIndex
] = 0;
900 // Build the path list for Config file scan. The priority is below.
901 // 1. Scan the current path
902 // 2. Scan the same path with the application itself
903 // 3. Scan the current %PATH% of OS environment
904 // 4. Use the build-in default configuration
906 PathList
= getenv("PATH");
907 if (PathList
== NULL
) {
908 Error (NULL
, 0, 1001, "Option: Environment variable 'PATH' does not exist", NULL
);
911 EnvLen
= strlen(PathList
);
912 NewPathList
= (char *)calloc(
915 + strlen (FullGuidToolDefinition
)
921 if (NewPathList
== NULL
) {
922 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
928 sprintf (NewPathList
, "%s;%s;%s", ".", FullGuidToolDefinition
, PathList
);
930 sprintf (NewPathList
, "%s:%s:%s", ".", FullGuidToolDefinition
, PathList
);
936 // Load Guid Tools definition
938 InFilePath
= SearchConfigFromPathList(NewPathList
, mGuidToolDefinition
);
940 if (InFilePath
!= NULL
) {
941 printf ("\nThe Guid Tool Definition of BfmLib comes from the '%s'. \n", InFilePath
);
942 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (InFilePath
);
946 // Use the pre-defined standard guided tools.
948 printf ("\nThe Guid Tool Definition of BfmLib comes from the build-in default configuration. \n");
949 mParsedGuidedSectionTools
= LibPreDefinedGuidedTools ();
953 // BfmLib -e FdName.Fd
955 if ((stricmp(Argv
[0], "-e") == 0)) {
961 // Extract FFS files.
963 Status
= BfmImageView (Argv
[1], NULL
, FALSE
, &FdData
);
965 if (EFI_ERROR (Status
)) {
969 if (FdData
== NULL
) {
973 LibBfmFreeFd(FdData
);
975 } else if ((stricmp(Argv
[0], "-i") == 0)) {
977 // Insert FFS files to BFV
978 // BfmLib -i InFdName.Fd FfsName.ffs OutFdName.Fd -g FvNameGuid
982 mFvNameGuidString
= Argv
[5];
983 StringToGuid (Argv
[5], &mFvNameGuid
);
989 Status
= BfmImageAdd(Argv
[1], Argv
[2], Argv
[3]);
991 if (EFI_ERROR (Status
)) {
995 } else if ((stricmp(Argv
[0], "-r") == 0)) {
997 // Replace FFS files in BFV
998 // BfmLib -r InFdName.Fd FfsName.ffs OutFdName.Fd -g FvNameGuid
1001 mFvGuidIsSet
= TRUE
;
1002 mFvNameGuidString
= Argv
[5];
1003 StringToGuid (Argv
[5], &mFvNameGuid
);
1009 Status
= BfmImageReplace (Argv
[1], Argv
[2], Argv
[3]);
1011 if (EFI_ERROR (Status
)) {
1017 // Invalid parameter.