3 Library to parse and generate FV image.
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "FirmwareModuleManagement.h"
12 #define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \
15 (FvbAttributes & EFI_FVB2_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \
19 CHAR8 mFirmwareFileSystem2Guid
[16] = {0x78, 0xE5, 0x8C, 0x8C, 0x3D, 0x8A, 0x1C, 0x4F, 0x99, 0x35, 0x89, 0x61, 0x85, 0xC3, 0x2D, 0xD3};
21 CHAR8 mFirmwareFileSystem3Guid
[16] = {0x7A, 0xC0, 0x73, 0x54, 0xCB, 0x3D, 0xCA, 0x4D, 0xBD, 0x6F, 0x1E, 0x96, 0x89, 0xE7, 0x34, 0x9A };
23 EFI_GUID mEfiCrc32GuidedSectionExtractionProtocolGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
24 extern CHAR8
* mGuidToolDefinition
;
26 static CHAR8
*mSectionTypeName
[] = {
27 NULL
, // 0x00 - reserved
28 "EFI_SECTION_COMPRESSION", // 0x01
29 "EFI_SECTION_GUID_DEFINED", // 0x02
30 NULL
, // 0x03 - reserved
31 NULL
, // 0x04 - reserved
32 NULL
, // 0x05 - reserved
33 NULL
, // 0x06 - reserved
34 NULL
, // 0x07 - reserved
35 NULL
, // 0x08 - reserved
36 NULL
, // 0x09 - reserved
37 NULL
, // 0x0A - reserved
38 NULL
, // 0x0B - reserved
39 NULL
, // 0x0C - reserved
40 NULL
, // 0x0D - reserved
41 NULL
, // 0x0E - reserved
42 NULL
, // 0x0F - reserved
43 "EFI_SECTION_PE32", // 0x10
44 "EFI_SECTION_PIC", // 0x11
45 "EFI_SECTION_TE", // 0x12
46 "EFI_SECTION_DXE_DEPEX", // 0x13
47 "EFI_SECTION_VERSION", // 0x14
48 "EFI_SECTION_USER_INTERFACE", // 0x15
49 "EFI_SECTION_COMPATIBILITY16", // 0x16
50 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17
51 "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18
52 "EFI_SECTION_RAW", // 0x19
54 "EFI_SECTION_PEI_DEPEX", // 0x1B
55 "EFI_SECTION_SMM_DEPEX" // 0x1C
59 static CHAR8
*mFfsFileType
[] = {
61 "EFI_FV_FILETYPE_RAW", // 0x01
62 "EFI_FV_FILETYPE_FREEFORM", // 0x02
63 "EFI_FV_FILETYPE_SECURITY_CORE", // 0x03
64 "EFI_FV_FILETYPE_PEI_CORE", // 0x04
65 "EFI_FV_FILETYPE_DXE_CORE", // 0x05
66 "EFI_FV_FILETYPE_PEIM", // 0x06
67 "EFI_FV_FILETYPE_DRIVER", // 0x07
68 "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER", // 0x08
69 "EFI_FV_FILETYPE_APPLICATION", // 0x09
70 "EFI_FV_FILETYPE_SMM", // 0x0A
71 "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE",// 0x0B
72 "EFI_FV_FILETYPE_COMBINED_SMM_DXE", // 0x0C
73 "EFI_FV_FILETYPE_SMM_CORE" // 0x0D
76 static CHAR8
*mGuidSectionAttr
[] = {
78 "PROCESSING_REQUIRED", // 0x01
79 "AUTH_STATUS_VALID" // 0x02
82 static EFI_GUID mFvUiGuid
= {
83 0xA67DF1FA, 0x8DE8, 0x4E98, {
84 0xAF, 0x09, 0x4B, 0xDF, 0x2E, 0xFF, 0xBC, 0x7C
90 Generate the unique template filename.
100 TemString
= CloneString (tmpnam (NULL
));
102 CHAR8 tmp
[] = "/tmp/fileXXXXXX";
104 Fdtmp
= mkstemp(tmp
);
105 TemString
= CloneString(tmp
);
113 LibExtractFvUiName(CONST EFI_FIRMWARE_VOLUME_EXT_HEADER
*FvExtHeader
, CHAR8
**FvUiName
)
117 EFI_FIRMWARE_VOLUME_EXT_ENTRY
*ExtEntry
;
118 EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE
*GuidEntry
;
121 ExtEnd
= (UINT8
*)FvExtHeader
+ FvExtHeader
->ExtHeaderSize
;
122 ExtEntry
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*)(FvExtHeader
+ 1);
123 while ((UINT8
*)ExtEntry
< ExtEnd
) {
127 if (ExtEntry
->ExtEntryType
== 0x0002) {
128 GuidEntry
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE
*)ExtEntry
;
129 if (memcmp(&GuidEntry
->FormatType
, &mFvUiGuid
, sizeof(EFI_GUID
)) == 0) {
130 ExtDataSize
= ExtEntry
->ExtEntrySize
- (sizeof(EFI_GUID
)+sizeof(*ExtEntry
));
131 *FvUiName
= malloc(ExtDataSize
+ 1);
132 if (*FvUiName
!= NULL
) {
133 memcpy(*FvUiName
, (UINT8
*)GuidEntry
+ sizeof(EFI_GUID
)+sizeof(*ExtEntry
), ExtDataSize
);
134 (*FvUiName
)[ExtDataSize
] = '\0';
140 ExtEntry
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*)((UINT8
*)ExtEntry
+ ExtEntry
->ExtEntrySize
);
142 return EFI_NOT_FOUND
;
146 LibInitializeFvStruct (
156 for (Index
= 0; Index
< MAX_NUMBER_OF_FILES_IN_FV
; Index
++) {
157 memset (Fv
->FfsAttuibutes
[Index
].FfsName
, '\0', _MAX_PATH
);
158 memset (Fv
->FfsAttuibutes
[Index
].UiName
, '\0', _MAX_PATH
);
159 memset (&Fv
->FfsAttuibutes
[Index
].GuidName
, '\0', sizeof(EFI_GUID
));
160 Fv
->FfsAttuibutes
[Index
].UiNameSize
= 0;
161 Fv
->FfsAttuibutes
[Index
].IsLeaf
= TRUE
;
162 Fv
->FfsAttuibutes
[Index
].Level
= 0xFF;
163 Fv
->FfsAttuibutes
[Index
].TotalSectionNum
= 0;
164 Fv
->FfsAttuibutes
[Index
].Depex
= NULL
;
165 Fv
->FfsAttuibutes
[Index
].DepexLen
= 0;
166 Fv
->FfsAttuibutes
[Index
].IsHandle
= FALSE
;
167 Fv
->FfsAttuibutes
[Index
].IsFvStart
= FALSE
;
168 Fv
->FfsAttuibutes
[Index
].IsFvEnd
= FALSE
;
171 Fv
->EncapData
= NULL
;
173 Fv
->ChildFvFFS
= NULL
;
176 strcpy(Fv
->AlignmentStr
,"8");
184 IN OUT FIRMWARE_DEVICE
**FdData
187 FIRMWARE_DEVICE
*LocalFdData
;
190 CHAR8 SignatureCheck
[5] = "";
191 CHAR8 Signature
[5] = "_FVH";
192 FV_INFORMATION
*CurrentFv
;
193 FV_INFORMATION
*NewFoundFv
;
200 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
212 if (InputFile
== NULL
) {
213 Error ("FMMT", 0, 0001, "Error opening the input file", "");
218 // Find each FVs in the FD
221 fseek(InputFile
,0,SEEK_SET
);
222 fseek(InputFile
,0,SEEK_END
);
224 FdSize
= ftell(InputFile
);
226 fseek(InputFile
,0,SEEK_SET
);
228 // Create an FD structure to store useful information.
230 LocalFdData
= (FIRMWARE_DEVICE
*) malloc (sizeof (FIRMWARE_DEVICE
));
231 if (LocalFdData
== NULL
) {
232 Error ("FMMT", 0, 0002, "Error searching FVs in the input fd", "Allocate memory error");
233 return EFI_OUT_OF_RESOURCES
;
235 LocalFdData
->Fv
= (FV_INFORMATION
*) malloc (sizeof (FV_INFORMATION
));
236 if (LocalFdData
->Fv
== NULL
) {
237 Error ("FMMT", 0, 0002, "Error searching FVs in the input fd", "Allocate memory error");
239 return EFI_OUT_OF_RESOURCES
;
242 LibInitializeFvStruct (LocalFdData
->Fv
);
245 // Readout the FD file data to buffer.
247 FdBuffer
= malloc (FdSize
);
249 if (FdBuffer
== NULL
) {
250 Error ("FMMT", 0, 0002, "Error searching FVs in the input fd", "Allocate memory error");
251 free (LocalFdData
->Fv
);
253 return EFI_OUT_OF_RESOURCES
;
256 if (fread (FdBuffer
, 1, FdSize
, InputFile
) != FdSize
) {
257 Error ("FMMT", 0, 0002, "Error searching FVs in the input fd", "Read FD file error!");
258 free (LocalFdData
->Fv
);
264 FdBufferOri
= FdBuffer
;
265 FdBufferEnd
= FdBuffer
+ FdSize
;
267 while (FdBuffer
<= FdBufferEnd
- sizeof (EFI_FIRMWARE_VOLUME_HEADER
)) {
268 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FdBuffer
;
270 // Copy 4 bytes of fd data to check the _FVH signature
272 memcpy (SignatureCheck
, &FvHeader
->Signature
, 4);
274 if (strncmp(SignatureCheck
, Signature
, 4) == 0){
276 // Still need to determine the FileSystemGuid in EFI_FIRMWARE_VOLUME_HEADER equal to
277 // EFI_FIRMWARE_FILE_SYSTEM2_GUID or EFI_FIRMWARE_FILE_SYSTEM3_GUID.
278 // Turn back 28 bytes to find the GUID.
280 memcpy (Ffs2Guid
, &FvHeader
->FileSystemGuid
, 16);
285 for (Index
= 0; Index
< 16; Index
++) {
286 if (Ffs2Guid
[Index
] != mFirmwareFileSystem2Guid
[Index
]) {
291 for (Index
= 0; Index
< 16; Index
++) {
292 if (Ffs2Guid
[Index
] != mFirmwareFileSystem3Guid
[Index
]) {
299 // Here we found an FV.
301 if ((Index
== 16) && ((FdBuffer
+ FvHeader
->FvLength
) <= FdBufferEnd
)) {
303 LocalFdData
->Fv
->ImageAddress
= (UINTN
)((UINT8
*)FdBuffer
- (UINT8
*)FdBufferOri
);
304 CurrentFv
= LocalFdData
->Fv
;
305 CurrentFv
->FvNext
= NULL
;
307 // Store the FV name by found sequence
309 sprintf(CurrentFv
->FvName
, "FV%d", FvCount
);
313 NewFoundFv
= (FV_INFORMATION
*) malloc (sizeof (FV_INFORMATION
));
314 if (NewFoundFv
== NULL
) {
315 Error ("FMMT", 0, 0002, "Error searching FVs in the input fd", "Allocate memory error");
316 free (LocalFdData
->Fv
);
319 return EFI_OUT_OF_RESOURCES
;
322 LibInitializeFvStruct (NewFoundFv
);
325 // Need to turn back 0x2c bytes
327 NewFoundFv
->ImageAddress
= (UINTN
)((UINT8
*)FdBuffer
- (UINT8
*)FdBufferOri
);
330 // Store the FV name by found sequence
332 sprintf(NewFoundFv
->FvName
, "FV%d", FvCount
);
335 // Value it to NULL for found FV usage.
337 NewFoundFv
->FvNext
= NULL
;
338 CurrentFv
->FvNext
= NewFoundFv
;
341 // Make the CurrentFv point to next FV.
343 CurrentFv
= CurrentFv
->FvNext
;
347 FdBuffer
= FdBuffer
+ FvHeader
->FvLength
;
357 LocalFdData
->Size
= FdSize
;
359 *FdData
= LocalFdData
;
374 EFI_FFS_FILE_HEADER2
*CurrentFile
;
380 FreeOffset
= (UINTN
)ALIGN_POINTER(Offset
, 8);
381 Status
= FvBufFindNextFile(InputFv
, &Offset
, (VOID
**)&CurrentFile
);
382 if (Status
== EFI_NOT_FOUND
) {
386 else if (EFI_ERROR(Status
)) {
389 } while (CurrentFile
!= NULL
);
395 Construct a set of blank chars based on the number.
397 @param[in] Count The number of blank chars.
399 @return A string contained the blank chars.
403 LibConstructBlankChar (
413 RetStr
= (CHAR8
*) malloc (Count
+1);
415 if (RetStr
== NULL
) {
416 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
420 memset (RetStr
, '\0', Count
+ 1);
422 for (Index
=0; Index
<= Count
-1; Index
++) {
432 This function determines the size of the FV and the erase polarity. The
433 erase polarity is the FALSE value for file state.
436 @param[in ] InputFile The file that contains the FV image.
437 @param[out] FvSize The size of the FV.
438 @param[out] ErasePolarity The FV erase polarity.
440 @return EFI_SUCCESS Function completed successfully.
441 @return EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
442 @return EFI_ABORTED The function encountered an error.
454 EFI_FIRMWARE_VOLUME_HEADER
*VolumeHeader
;
457 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FvExtHeader
;
463 // Check input parameters
465 if (InputFv
== NULL
) {
466 Error (__FILE__
, __LINE__
, 0, "FMMT application error", "invalid parameter to function");
467 return EFI_INVALID_PARAMETER
;
473 VolumeHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) InputFv
;
476 BlankSpace
= LibConstructBlankChar((FvLevel
)*2);
478 if (BlankSpace
== NULL
) {
479 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
480 return EFI_OUT_OF_RESOURCES
;
485 if ((FvLevel
-1) == 0) {
486 printf ("\n%s :\n", FvName
);
488 printf ("%sChild FV named FV%d of %s\n", BlankSpace
, FvCount
, FvName
);
493 // Print FV header information
496 printf ("\n%sAttributes: %X\n", BlankSpace
, (unsigned) VolumeHeader
->Attributes
);
497 printf ("%sTotal Volume Size: 0x%08X\n", BlankSpace
, (unsigned) VolumeHeader
->FvLength
);
498 printf ("%sFree Volume Size: 0x%08X\n", BlankSpace
, (unsigned) (VolumeHeader
->FvLength
- GetFreeOffset(InputFv
)));
501 if (ViewFlag
&& VolumeHeader
->ExtHeaderOffset
!= 0) {
502 FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)((UINT8
*)VolumeHeader
+ VolumeHeader
->ExtHeaderOffset
);
503 printf("%sFvNameGuid: %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
505 FvExtHeader
->FvName
.Data1
,
506 FvExtHeader
->FvName
.Data2
,
507 FvExtHeader
->FvName
.Data3
,
508 FvExtHeader
->FvName
.Data4
[0],
509 FvExtHeader
->FvName
.Data4
[1],
510 FvExtHeader
->FvName
.Data4
[2],
511 FvExtHeader
->FvName
.Data4
[3],
512 FvExtHeader
->FvName
.Data4
[4],
513 FvExtHeader
->FvName
.Data4
[5],
514 FvExtHeader
->FvName
.Data4
[6],
515 FvExtHeader
->FvName
.Data4
[7]);
516 LibExtractFvUiName(FvExtHeader
, &FvUiName
);
517 if (FvUiName
!= NULL
&& FvLevel
== 1) {
518 printf("%sFV UI Name: %s\n\n", BlankSpace
, FvUiName
);
527 Get size info from FV file.
544 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
549 if (InputFile
== NULL
|| FvSize
== NULL
) {
550 Error (__FILE__
, __LINE__
, 0, "FMMT application error", "invalid parameter to function");
551 return EFI_INVALID_PARAMETER
;
554 fseek (InputFile
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), SEEK_CUR
);
556 fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
557 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
559 if (BlockMap
.NumBlocks
!= 0) {
560 Size
+= BlockMap
.NumBlocks
* BlockMap
.Length
;
562 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.Length
== 0));
572 Clears out all files from the Fv buffer in memory
574 @param[in] Fv - Address of the Fv in memory
585 EFI_FIRMWARE_VOLUME_HEADER
*hdr
;
586 EFI_FV_BLOCK_MAP_ENTRY
*blk
;
589 hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
592 while (blk
->Length
!= 0 || blk
->NumBlocks
!= 0) {
593 *Size
= *Size
+ (blk
->Length
* blk
->NumBlocks
);
594 if (*Size
>= 0x40000000) {
596 // If size is greater than 1GB, then assume it is corrupted
598 return EFI_VOLUME_CORRUPTED
;
605 // If size is 0, then assume the volume is corrupted
607 return EFI_VOLUME_CORRUPTED
;
614 Generate the leaf FFS files.
619 EFI_FFS_FILE_HEADER2
*CurrentFile
,
620 FV_INFORMATION
*CurrentFv
,
624 BOOLEAN ErasePolarity
638 TempDir
= getcwd (NULL
, _MAX_PATH
);
639 if (strlen (TempDir
) + strlen(OS_SEP_STR
) + strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
640 Error("FMMT", 0, 1001, "The directory is too long.", "");
643 strncat (TempDir
, OS_SEP_STR
, _MAX_PATH
- strlen(TempDir
) - 1);
644 strncat (TempDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen(TempDir
) - 1);
646 mkdir(TempDir
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
648 FfsFileName
= (CHAR8
*) malloc (_MAX_PATH
);
649 if (FfsFileName
== NULL
) {
650 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
653 memset (FfsFileName
, '\0', _MAX_PATH
);
654 FfsFileSize
= GetFfsFileLength ((EFI_FFS_FILE_HEADER
*) CurrentFile
);
656 (CHAR8
*)FfsFileName
,
657 "%s%cNum%d-%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X-Level%d",
661 (unsigned) CurrentFile
->Name
.Data1
,
662 CurrentFile
->Name
.Data2
,
663 CurrentFile
->Name
.Data3
,
664 CurrentFile
->Name
.Data4
[0],
665 CurrentFile
->Name
.Data4
[1],
666 CurrentFile
->Name
.Data4
[2],
667 CurrentFile
->Name
.Data4
[3],
668 CurrentFile
->Name
.Data4
[4],
669 CurrentFile
->Name
.Data4
[5],
670 CurrentFile
->Name
.Data4
[6],
671 CurrentFile
->Name
.Data4
[7],
675 memcpy (CurrentFv
->FfsAttuibutes
[*FfsCount
].FfsName
, FfsFileName
, strlen(FfsFileName
));
676 memcpy (&CurrentFv
->FfsAttuibutes
[*FfsCount
].GuidName
, &CurrentFile
->Name
, sizeof(EFI_GUID
));
678 // Update current FFS files file state.
681 CurrentFile
->State
= (UINT8
)~(CurrentFile
->State
);
684 FfsFile
= fopen (FfsFileName
, "wb+");
685 if (FfsFile
== NULL
) {
686 Error ("FMMT", 0, 0003, "error writing FFS file", "cannot Create a new ffs file.");
691 if (fwrite (CurrentFile
, 1, FfsFileSize
, FfsFile
) != FfsFileSize
) {
692 Error ("FMMT", 0, 0004, "error writing FFS file", "cannot Create a new ffs file.");
702 CurrentFv
->FfsNumbers
= *FfsCount
;
707 CurrentFile
->State
= (UINT8
)~(CurrentFile
->State
);
714 Unicode2AsciiString (
716 OUT CHAR8
*Destination
722 Convert a null-terminated unicode string to a null-terminated ascii string.
726 Source - The pointer to the null-terminated input unicode string.
727 Destination - The pointer to the null-terminated output ascii string.
735 while (*Source
!= '\0') {
736 *(Destination
++) = (CHAR8
) *(Source
++);
739 // End the ascii with a NULL.
747 Parses EFI Sections, if the view flag turn on, then will collect FFS section information
748 and extract FFS files.
750 @param[in] SectionBuffer - Buffer containing the section to parse.
751 @param[in] BufferLength - Length of SectionBuffer
752 @param[in, out] CurrentFv
754 @param[in] CurrentFile
756 @param[in, out] FfsCount
758 @param[in] ErasePolarity
760 @retval EFI_SECTION_ERROR - Problem with section parsing.
761 (a) compression errors
762 (b) unrecognized section
763 @retval EFI_UNSUPPORTED - Do not know how to parse the section.
764 @retval EFI_SUCCESS - Section successfully parsed.
765 @retval EFI_OUT_OF_RESOURCES - Memory allocation failed.
770 UINT8
*SectionBuffer
,
772 FV_INFORMATION
*CurrentFv
,
774 EFI_FFS_FILE_HEADER2
*CurrentFile
,
776 ENCAP_INFO_DATA
**CurrentFvEncapData
,
781 BOOLEAN ErasePolarity
,
782 BOOLEAN
*IsFfsGenerated
787 UINT32 SectionLength
;
788 UINT32 UiSectionLength
;
789 EFI_SECTION_TYPE Type
;
791 CHAR8
*ExtractionTool
;
792 CHAR8
*ToolInputFile
;
793 CHAR8
*ToolOutputFile
;
794 CHAR8
*SystemCommandFormatString
;
795 CHAR8
*SystemCommand
;
796 UINT8
*ToolOutputBuffer
;
797 UINT32 ToolOutputLength
;
800 BOOLEAN HasDepexSection
;
801 UINT32 NumberOfSections
;
802 ENCAP_INFO_DATA
*LocalEncapData
;
803 ENCAP_INFO_DATA
*LocalEncapDataTemp
;
805 UINT8
*UncompressedBuffer
;
806 UINT32 UncompressedLength
;
807 UINT8
*CompressedBuffer
;
808 UINT32 CompressedLength
;
809 UINT8 CompressionType
;
810 DECOMPRESS_FUNCTION DecompressFunction
;
811 GETINFO_FUNCTION GetInfoFunction
;
814 UINT8
*ScratchBuffer
;
815 BOOLEAN EncapDataNeedUpdata
;
817 CHAR8
*ToolInputFileFullName
;
818 CHAR8
*ToolOutputFileFullName
;
819 UINT8 LargeHeaderOffset
;
823 CHAR8
*ToolInputFileName
;
824 CHAR8
*ToolOutputFileName
;
829 ToolOutputLength
= 0;
831 NumberOfSections
= 0;
832 UncompressedLength
= 0;
833 CompressedLength
= 0;
838 ExtractionTool
= NULL
;
839 ToolInputFile
= NULL
;
840 ToolOutputFile
= NULL
;
841 SystemCommand
= NULL
;
842 SystemCommandFormatString
= NULL
;
843 ToolOutputBuffer
= NULL
;
845 LocalEncapData
= NULL
;
846 LocalEncapDataTemp
= NULL
;
848 UncompressedBuffer
= NULL
;
849 CompressedBuffer
= NULL
;
850 ScratchBuffer
= NULL
;
852 ToolInputFileFullName
= NULL
;
853 ToolOutputFileFullName
= NULL
;
854 ToolInputFileName
= NULL
;
855 ToolOutputFileFullName
= NULL
;
856 HasDepexSection
= FALSE
;
857 EncapDataNeedUpdata
= TRUE
;
858 LargeHeaderOffset
= 0;
861 while (ParsedLength
< BufferLength
) {
862 Ptr
= SectionBuffer
+ ParsedLength
;
864 SectionLength
= GetLength (((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Size
);
865 Type
= ((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Type
;
868 // This is sort of an odd check, but is necessary because FFS files are
869 // padded to a QWORD boundary, meaning there is potentially a whole section
870 // header worth of 0xFF bytes.
872 if (SectionLength
== 0xffffff && Type
== 0xff) {
877 //If Size is 0xFFFFFF then ExtendedSize contains the size of the section.
879 if (SectionLength
== 0xffffff) {
880 SectionLength
= ((EFI_COMMON_SECTION_HEADER2
*) Ptr
)->ExtendedSize
;
881 LargeHeaderOffset
= sizeof (EFI_COMMON_SECTION_HEADER2
) - sizeof (EFI_COMMON_SECTION_HEADER
);
886 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
888 EncapDataNeedUpdata
= TRUE
;
893 CurrentFv
->FfsAttuibutes
[*FfsCount
].IsLeaf
= FALSE
;
894 CurrentFv
->FfsAttuibutes
[*FfsCount
].IsFvStart
= TRUE
;
896 // Put in encapsulate data information.
898 LocalEncapData
= *CurrentFvEncapData
;
899 if (LocalEncapData
->NextNode
!= NULL
) {
900 LocalEncapData
= LocalEncapData
->NextNode
;
901 while (LocalEncapData
->RightNode
!= NULL
) {
902 LocalEncapData
= LocalEncapData
->RightNode
;
906 if (EncapDataNeedUpdata
) {
908 // Put in this is an FFS with FV section
912 // Construct the new ENCAP_DATA
914 LocalEncapData
->NextNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
916 if (LocalEncapData
->NextNode
== NULL
) {
917 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
921 LocalEncapData
= LocalEncapData
->NextNode
;
923 LocalEncapData
->Level
= Level
;
924 LocalEncapData
->Type
= FMMT_ENCAP_TREE_FV_SECTION
;
927 // We don't need additional data for encapsulate this FFS but type.
929 LocalEncapData
->Data
= NULL
;
930 LocalEncapData
->FvExtHeader
= NULL
;
931 LocalEncapData
->NextNode
= NULL
;
932 LocalEncapData
->RightNode
= NULL
;
933 LocalEncapData
->Depex
= NULL
;
934 LocalEncapData
->DepexLen
= 0;
935 LocalEncapData
->UiNameSize
= 0;
936 LocalEncapData
->FvId
= *FvCount
;
940 //save parent level FFS file's GUID name
942 LocalEncapDataTemp
= CurrentFv
->EncapData
;
943 while (LocalEncapDataTemp
->NextNode
!= NULL
) {
944 if (LocalEncapDataTemp
->Level
== FfsLevel
) {
945 while (LocalEncapDataTemp
->RightNode
!= NULL
) {
946 LocalEncapDataTemp
= LocalEncapDataTemp
->RightNode
;
948 if (LocalEncapDataTemp
!= NULL
&& LocalEncapDataTemp
->FvExtHeader
== NULL
) {
949 LocalEncapDataTemp
->FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)malloc(sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER
));
950 if (LocalEncapDataTemp
->FvExtHeader
== NULL
) {
951 Error(NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
955 if (*FfsCount
>= 1) {
956 if ((memcmp(&CurrentFv
->FfsAttuibutes
[*FfsCount
- 1].GuidName
, &(LocalEncapDataTemp
->FvExtHeader
->FvName
), sizeof(EFI_GUID
)) == 0)) {
957 memcpy(LocalEncapDataTemp
->UiName
, CurrentFv
->FfsAttuibutes
[*FfsCount
- 1].UiName
, _MAX_PATH
);
958 LocalEncapDataTemp
->UiNameSize
= CurrentFv
->FfsAttuibutes
[*FfsCount
- 1].UiNameSize
;
959 LocalEncapDataTemp
->DepexLen
= CurrentFv
->FfsAttuibutes
[*FfsCount
- 1].DepexLen
;
960 LocalEncapDataTemp
->Depex
= malloc (LocalEncapDataTemp
->DepexLen
);
961 if (LocalEncapDataTemp
->Depex
== NULL
) {
962 Error(NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
965 memcpy(LocalEncapDataTemp
->Depex
, CurrentFv
->FfsAttuibutes
[*FfsCount
- 1].Depex
, LocalEncapDataTemp
->DepexLen
);
971 LocalEncapDataTemp
= LocalEncapDataTemp
->NextNode
;
974 Status
= LibGetFvInfo ((UINT8
*)((EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*)Ptr
+ 1) + LargeHeaderOffset
, CurrentFv
, FvName
, Level
, &LocalEncapData
, FfsCount
, FvCount
, ViewFlag
, TRUE
);
975 if (EFI_ERROR (Status
)) {
976 Error ("FMMT", 0, 0003, "printing of FV section contents failed", NULL
);
977 return EFI_SECTION_ERROR
;
979 if (*FfsCount
>= 1) {
980 CurrentFv
->FfsAttuibutes
[*FfsCount
-1].IsFvEnd
= TRUE
;
984 case EFI_SECTION_COMPRESSION
:
988 EncapDataNeedUpdata
= TRUE
;
990 // Put in encapsulate data information.
992 LocalEncapData
= *CurrentFvEncapData
;
993 if (LocalEncapData
->NextNode
!= NULL
) {
994 EncapDataNeedUpdata
= FALSE
;
995 while (LocalEncapData
->RightNode
!= NULL
) {
996 LocalEncapData
= LocalEncapData
->RightNode
;
1000 if (EncapDataNeedUpdata
) {
1002 // Put in this is an FFS with FV section
1006 // Construct the new ENCAP_DATA
1008 LocalEncapData
->NextNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
1010 if (LocalEncapData
->NextNode
== NULL
) {
1011 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1015 LocalEncapData
= LocalEncapData
->NextNode
;
1017 LocalEncapData
->Level
= Level
;
1018 LocalEncapData
->Type
= FMMT_ENCAP_TREE_COMPRESS_SECTION
;
1021 // Store the compress type
1023 LocalEncapData
->Data
= malloc (sizeof (UINT8
));
1025 if (LocalEncapData
->Data
== NULL
) {
1026 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL
);
1027 return EFI_OUT_OF_RESOURCES
;
1030 *(UINT8
*)LocalEncapData
->Data
= ((EFI_COMPRESSION_SECTION
*) (Ptr
+ LargeHeaderOffset
))->CompressionType
;
1031 LocalEncapData
->FvExtHeader
= NULL
;
1032 LocalEncapData
->NextNode
= NULL
;
1033 LocalEncapData
->RightNode
= NULL
;
1035 LocalEncapData
->RightNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
1036 if (LocalEncapData
->RightNode
== NULL
) {
1037 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1040 LocalEncapData
= LocalEncapData
->RightNode
;
1042 LocalEncapData
->Level
= Level
;
1043 LocalEncapData
->Type
= FMMT_ENCAP_TREE_COMPRESS_SECTION
;
1046 // Store the compress type
1048 LocalEncapData
->Data
= malloc (sizeof (UINT8
));
1050 if (LocalEncapData
->Data
== NULL
) {
1051 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL
);
1052 return EFI_OUT_OF_RESOURCES
;
1055 *(UINT8
*)LocalEncapData
->Data
= ((EFI_COMPRESSION_SECTION
*) (Ptr
+ LargeHeaderOffset
))->CompressionType
;
1056 LocalEncapData
->FvExtHeader
= NULL
;
1057 LocalEncapData
->NextNode
= NULL
;
1058 LocalEncapData
->RightNode
= NULL
;
1063 // Process compressed section
1065 CurrentFv
->FfsAttuibutes
[*FfsCount
].IsLeaf
= FALSE
;
1067 UncompressedBuffer
= NULL
;
1068 CompressedLength
= SectionLength
- sizeof (EFI_COMPRESSION_SECTION
) - LargeHeaderOffset
;
1069 UncompressedLength
= ((EFI_COMPRESSION_SECTION
*) (Ptr
+ LargeHeaderOffset
))->UncompressedLength
;
1070 CompressionType
= ((EFI_COMPRESSION_SECTION
*) (Ptr
+ LargeHeaderOffset
))->CompressionType
;
1072 if (CompressionType
== EFI_NOT_COMPRESSED
) {
1073 //printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1074 if (CompressedLength
!= UncompressedLength
) {
1075 Error ("FMMT", 0, 0, "file is not compressed, but the compressed length does not match the uncompressed length", NULL
);
1076 return EFI_SECTION_ERROR
;
1079 UncompressedBuffer
= Ptr
+ sizeof (EFI_COMPRESSION_SECTION
) + LargeHeaderOffset
;
1080 } else if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1081 GetInfoFunction
= EfiGetInfo
;
1082 DecompressFunction
= EfiDecompress
;
1084 CompressedBuffer
= Ptr
+ sizeof (EFI_COMPRESSION_SECTION
) + LargeHeaderOffset
;
1086 Status
= GetInfoFunction (CompressedBuffer
, CompressedLength
, &DstSize
, &ScratchSize
);
1087 if (EFI_ERROR (Status
)) {
1088 Error ("FMMT", 0, 0003, "error getting compression info from compression section", NULL
);
1089 return EFI_SECTION_ERROR
;
1092 if (DstSize
!= UncompressedLength
) {
1093 Error ("FMMT", 0, 0003, "compression error in the compression section", NULL
);
1094 return EFI_SECTION_ERROR
;
1097 ScratchBuffer
= malloc (ScratchSize
);
1098 if (ScratchBuffer
== NULL
) {
1099 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL
);
1100 return EFI_OUT_OF_RESOURCES
;
1102 UncompressedBuffer
= malloc (UncompressedLength
);
1103 if (UncompressedBuffer
== NULL
) {
1104 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL
);
1105 free (ScratchBuffer
);
1106 return EFI_OUT_OF_RESOURCES
;
1109 // Decompress the section.
1111 Status
= DecompressFunction (
1119 free (ScratchBuffer
);
1120 if (EFI_ERROR (Status
)) {
1121 Error ("FMMT", 0, 0003, "decompress failed", NULL
);
1122 free (UncompressedBuffer
);
1123 return EFI_SECTION_ERROR
;
1126 Error ("FMMT", 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType
);
1127 return EFI_SECTION_ERROR
;
1130 Status
= LibParseSection ( UncompressedBuffer
,
1144 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1146 // We need to deallocate Buffer
1148 free (UncompressedBuffer
);
1151 if (EFI_ERROR (Status
)) {
1152 Error (NULL
, 0, 0003, "failed to parse section", NULL
);
1153 return EFI_SECTION_ERROR
;
1158 case EFI_SECTION_GUID_DEFINED
:
1160 // Process GUID defined
1161 // looks up the appropriate tool to use for extracting
1162 // a GUID defined FV section.
1166 EncapDataNeedUpdata
= TRUE
;
1168 // Put in encapsulate data information.
1170 LocalEncapData
= *CurrentFvEncapData
;
1171 if (LocalEncapData
->NextNode
!= NULL
) {
1172 EncapDataNeedUpdata
= FALSE
;
1173 while (LocalEncapData
->RightNode
!= NULL
) {
1174 LocalEncapData
= LocalEncapData
->RightNode
;
1177 GuidAttr
= ((EFI_GUID_DEFINED_SECTION
*)(Ptr
+ LargeHeaderOffset
))->Attributes
;
1178 DataOffset
= ((EFI_GUID_DEFINED_SECTION
*)(Ptr
+ LargeHeaderOffset
))->DataOffset
;
1180 if ((ViewFlag
) && ((GuidAttr
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0)) {
1181 ToolOutputBuffer
= Ptr
+ DataOffset
;
1182 ToolOutputLength
= SectionLength
- DataOffset
;
1183 Status
= LibParseSection(
1198 if (EFI_ERROR(Status
)) {
1199 Error(NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
1200 return EFI_SECTION_ERROR
;
1205 if (EncapDataNeedUpdata
) {
1208 // Put in this is an FFS with FV section
1212 // Construct the new ENCAP_DATA
1214 LocalEncapData
->NextNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
1216 if (LocalEncapData
->NextNode
== NULL
) {
1217 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1221 LocalEncapData
= LocalEncapData
->NextNode
;
1223 LocalEncapData
->Level
= Level
;
1224 LocalEncapData
->Type
= FMMT_ENCAP_TREE_GUIDED_SECTION
;
1225 LocalEncapData
->Depex
= NULL
;
1226 LocalEncapData
->DepexLen
= 0;
1227 LocalEncapData
->UiNameSize
= 0;
1229 // We don't need additional data for encapsulate this FFS but type.
1230 // include DataOffset + Attributes
1233 LocalEncapData
->Data
= (EFI_GUID
*) malloc (sizeof (EFI_GUID
) + 4);
1235 if (LocalEncapData
->Data
== NULL
) {
1236 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1241 // include guid attribute and dataoffset
1243 memcpy (LocalEncapData
->Data
, Ptr
+ LargeHeaderOffset
+ OFFSET_OF (EFI_GUID_DEFINED_SECTION
, SectionDefinitionGuid
), sizeof (EFI_GUID
) + 4);
1245 LocalEncapData
->FvExtHeader
= NULL
;
1246 LocalEncapData
->NextNode
= NULL
;
1247 LocalEncapData
->RightNode
= NULL
;
1249 LocalEncapData
->RightNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
1250 if (LocalEncapData
->RightNode
== NULL
) {
1251 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1254 LocalEncapData
= LocalEncapData
->RightNode
;
1255 LocalEncapData
->Level
= Level
;
1256 LocalEncapData
->Type
= FMMT_ENCAP_TREE_GUIDED_SECTION
;
1257 LocalEncapData
->Depex
= NULL
;
1258 LocalEncapData
->DepexLen
= 0;
1259 LocalEncapData
->UiNameSize
= 0;
1261 // We don't need additional data for encapsulate this FFS but type.
1262 // include DataOffset + Attributes
1265 LocalEncapData
->Data
= (EFI_GUID
*) malloc (sizeof (EFI_GUID
) + 4);
1267 if (LocalEncapData
->Data
== NULL
) {
1268 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1273 // include guid attribute and dataoffset
1275 memcpy (LocalEncapData
->Data
, Ptr
+ LargeHeaderOffset
+ OFFSET_OF (EFI_GUID_DEFINED_SECTION
, SectionDefinitionGuid
), sizeof (EFI_GUID
) + 4);
1277 LocalEncapData
->FvExtHeader
= NULL
;
1278 LocalEncapData
->NextNode
= NULL
;
1279 LocalEncapData
->RightNode
= NULL
;
1282 CurrentFv
->FfsAttuibutes
[*FfsCount
].IsLeaf
= FALSE
;
1285 LookupGuidedSectionToolPath (
1286 mParsedGuidedSectionTools
,
1287 &((EFI_GUID_DEFINED_SECTION
*) (Ptr
+ LargeHeaderOffset
))->SectionDefinitionGuid
1290 if (ExtractionTool
!= NULL
&& ((GuidAttr
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) != 0)) {
1292 TempDir
= getcwd (NULL
, _MAX_PATH
);
1293 if (strlen (TempDir
) + strlen(OS_SEP_STR
) + strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
1294 Error("FMMT", 0, 1001, "The directory is too long.", "");
1295 free (ExtractionTool
);
1296 return EFI_SECTION_ERROR
;
1298 strncat (TempDir
, OS_SEP_STR
, _MAX_PATH
- strlen(TempDir
) - 1);
1299 strncat (TempDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen(TempDir
) - 1);
1300 mkdir(TempDir
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
1301 ToolInputFile
= GenTempFile ();
1302 if (ToolInputFile
== NULL
) {
1303 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1304 free (ExtractionTool
);
1305 return EFI_OUT_OF_RESOURCES
;
1307 ToolOutputFile
= GenTempFile ();
1308 if (ToolOutputFile
== NULL
) {
1309 free (ToolInputFile
);
1310 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1311 free (ExtractionTool
);
1312 return EFI_OUT_OF_RESOURCES
;
1314 ToolInputFileName
= strrchr(ToolInputFile
, OS_SEP
);
1315 if (ToolInputFileName
== NULL
) {
1316 free (ToolInputFile
);
1317 free (ToolOutputFile
);
1318 free (ExtractionTool
);
1321 ToolOutputFileName
= strrchr(ToolOutputFile
, OS_SEP
);
1322 if (ToolOutputFileName
== NULL
) {
1323 free (ToolInputFile
);
1324 free (ToolOutputFile
);
1325 free (ExtractionTool
);
1329 ToolInputFileFullName
= malloc (strlen("%s%s") + strlen(TempDir
) + strlen(ToolInputFileName
) + 1);
1330 if (ToolInputFileFullName
== NULL
) {
1331 free (ToolInputFile
);
1332 free (ToolOutputFile
);
1333 free (ExtractionTool
);
1334 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL
);
1335 return EFI_OUT_OF_RESOURCES
;
1337 ToolOutputFileFullName
= malloc (strlen("%s%s") + strlen(TempDir
) + strlen(ToolOutputFileName
) + 1);
1339 if (ToolOutputFileFullName
== NULL
) {
1340 free (ToolInputFile
);
1341 free (ToolOutputFile
);
1342 free (ToolInputFileFullName
);
1343 free (ExtractionTool
);
1344 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1345 return EFI_OUT_OF_RESOURCES
;
1348 sprintf (ToolInputFileFullName
, "%s%s", TempDir
, ToolInputFileName
);
1349 sprintf (ToolOutputFileFullName
, "%s%s", TempDir
, ToolOutputFileName
);
1352 // Construction 'system' command string
1354 SystemCommandFormatString
= "%s -d -o \"%s\" \"%s\"";
1355 SystemCommand
= malloc (
1356 strlen (SystemCommandFormatString
) +
1357 strlen (ExtractionTool
) +
1358 strlen (ToolInputFileFullName
) +
1359 strlen (ToolOutputFileFullName
) +
1362 if (SystemCommand
== NULL
) {
1363 free (ToolInputFile
);
1364 free (ToolOutputFile
);
1365 free (ToolInputFileFullName
);
1366 free (ToolOutputFileFullName
);
1367 free (ExtractionTool
);
1372 "%s -d -o \"%s\" \"%s\"",
1374 ToolOutputFileFullName
,
1375 ToolInputFileFullName
1377 free (ExtractionTool
);
1378 ExtractionTool
= NULL
;
1380 Status
= PutFileImage (
1381 ToolInputFileFullName
,
1382 (CHAR8
*) Ptr
+ ((EFI_GUID_DEFINED_SECTION
*) (Ptr
+ LargeHeaderOffset
))->DataOffset
,
1383 SectionLength
- ((EFI_GUID_DEFINED_SECTION
*) (Ptr
+ LargeHeaderOffset
))->DataOffset
1386 if (HasDepexSection
) {
1387 HasDepexSection
= FALSE
;
1390 if (EFI_ERROR (Status
)) {
1391 Error ("FMMT", 0, 0004, "unable to decoded GUIDED section", NULL
);
1392 free (SystemCommand
);
1393 free (ToolInputFile
);
1394 free (ToolOutputFile
);
1395 free (ToolOutputFileFullName
);
1396 remove (ToolInputFileFullName
);
1397 free (ToolInputFileFullName
);
1398 return EFI_SECTION_ERROR
;
1401 if (system (SystemCommand
) != EFI_SUCCESS
) {
1402 printf("Command failed: %s\n", SystemCommand
);
1403 free (SystemCommand
);
1404 free (ToolInputFile
);
1405 free (ToolOutputFile
);
1406 free (ToolOutputFileFullName
);
1407 remove (ToolInputFileFullName
);
1408 free (ToolInputFileFullName
);
1411 free (SystemCommand
);
1412 remove (ToolInputFileFullName
);
1413 free (ToolInputFile
);
1414 free (ToolInputFileFullName
);
1415 ToolInputFile
= NULL
;
1416 ToolInputFileFullName
= NULL
;
1419 Status
= GetFileImage (
1420 ToolOutputFileFullName
,
1421 (CHAR8
**)&ToolOutputBuffer
,
1424 remove (ToolOutputFileFullName
);
1425 free (ToolOutputFile
);
1426 free (ToolOutputFileFullName
);
1427 ToolOutputFile
= NULL
;
1428 ToolOutputFileFullName
= NULL
;
1430 if (EFI_ERROR (Status
)) {
1431 Error ("FMMT", 0, 0004, "unable to read decoded GUIDED section", NULL
);
1432 return EFI_SECTION_ERROR
;
1435 Status
= LibParseSection (
1450 if (EFI_ERROR (Status
)) {
1451 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
1452 return EFI_SECTION_ERROR
;
1454 } else if ((GuidAttr
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0){
1455 Status
= LibParseSection (
1456 Ptr
+ ((EFI_GUID_DEFINED_SECTION
*) (Ptr
+ LargeHeaderOffset
))->DataOffset
,
1457 SectionLength
- ((EFI_GUID_DEFINED_SECTION
*) (Ptr
+ LargeHeaderOffset
))->DataOffset
,
1470 if (ExtractionTool
!= NULL
) {
1471 free (ExtractionTool
);
1472 ExtractionTool
= NULL
;
1474 if (EFI_ERROR (Status
)) {
1475 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
1476 return EFI_SECTION_ERROR
;
1480 // We don't know how to parse it now.
1482 if (ExtractionTool
!= NULL
) {
1483 free (ExtractionTool
);
1484 ExtractionTool
= NULL
;
1486 Error ("FMMT", 0, 0003, "Error parsing section", \
1487 "EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in %s file.", mGuidToolDefinition
);
1488 printf(" Its GUID is: ");
1489 PrintGuid(&(((EFI_GUID_DEFINED_SECTION
*)(Ptr
+ LargeHeaderOffset
))->SectionDefinitionGuid
));
1490 return EFI_UNSUPPORTED
;
1497 case EFI_SECTION_RAW
:
1498 NumberOfSections
++;
1499 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1501 if (!*IsFfsGenerated
) {
1502 LibGenFfsFile(CurrentFile
, CurrentFv
, FvName
, Level
, FfsCount
, ErasePolarity
);
1503 *IsFfsGenerated
= TRUE
;
1508 case EFI_SECTION_PE32
:
1509 NumberOfSections
++;
1510 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1512 if (!*IsFfsGenerated
) {
1513 LibGenFfsFile(CurrentFile
, CurrentFv
, FvName
, Level
, FfsCount
, ErasePolarity
);
1514 *IsFfsGenerated
= TRUE
;
1519 case EFI_SECTION_PIC
:
1520 NumberOfSections
++;
1521 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1523 if (!*IsFfsGenerated
) {
1524 LibGenFfsFile(CurrentFile
, CurrentFv
, FvName
, Level
, FfsCount
, ErasePolarity
);
1525 *IsFfsGenerated
= TRUE
;
1530 case EFI_SECTION_TE
:
1531 NumberOfSections
++;
1532 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1534 if (!*IsFfsGenerated
) {
1535 LibGenFfsFile(CurrentFile
, CurrentFv
, FvName
, Level
, FfsCount
, ErasePolarity
);
1536 *IsFfsGenerated
= TRUE
;
1541 case EFI_SECTION_COMPATIBILITY16
:
1542 NumberOfSections
++;
1543 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1545 if (!*IsFfsGenerated
) {
1546 LibGenFfsFile(CurrentFile
, CurrentFv
, FvName
, Level
, FfsCount
, ErasePolarity
);
1547 *IsFfsGenerated
= TRUE
;
1552 case EFI_SECTION_FREEFORM_SUBTYPE_GUID
:
1553 NumberOfSections
++;
1554 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1556 if (!*IsFfsGenerated
) {
1557 LibGenFfsFile(CurrentFile
, CurrentFv
, FvName
, Level
, FfsCount
, ErasePolarity
);
1558 *IsFfsGenerated
= TRUE
;
1563 case EFI_SECTION_VERSION
:
1564 NumberOfSections
++;
1565 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1567 case EFI_SECTION_PEI_DEPEX
:
1568 NumberOfSections
++;
1569 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1570 HasDepexSection
= TRUE
;
1571 CurrentFv
->FfsAttuibutes
[*FfsCount
].Depex
= malloc (SectionLength
);
1572 memcpy(CurrentFv
->FfsAttuibutes
[*FfsCount
].Depex
, Ptr
, SectionLength
);
1573 CurrentFv
->FfsAttuibutes
[*FfsCount
].DepexLen
= SectionLength
;
1575 case EFI_SECTION_DXE_DEPEX
:
1576 NumberOfSections
++;
1577 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1578 HasDepexSection
= TRUE
;
1579 CurrentFv
->FfsAttuibutes
[*FfsCount
].Depex
= malloc (SectionLength
);
1580 memcpy(CurrentFv
->FfsAttuibutes
[*FfsCount
].Depex
, Ptr
, SectionLength
);
1581 CurrentFv
->FfsAttuibutes
[*FfsCount
].DepexLen
= SectionLength
;
1583 case EFI_SECTION_SMM_DEPEX
:
1584 NumberOfSections
++;
1585 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1586 HasDepexSection
= TRUE
;
1587 CurrentFv
->FfsAttuibutes
[*FfsCount
].Depex
= malloc (SectionLength
);
1588 memcpy(CurrentFv
->FfsAttuibutes
[*FfsCount
].Depex
, Ptr
, SectionLength
);
1589 CurrentFv
->FfsAttuibutes
[*FfsCount
].DepexLen
= SectionLength
;
1592 case EFI_SECTION_USER_INTERFACE
:
1593 NumberOfSections
++;
1594 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1596 UiSectionLength
= GetLength (((EFI_USER_INTERFACE_SECTION
*) Ptr
)->CommonHeader
.Size
);
1597 if (UiSectionLength
== 0xffffff) {
1598 UiSectionLength
= ((EFI_USER_INTERFACE_SECTION2
*) Ptr
)->CommonHeader
.ExtendedSize
;
1599 UINameSize
= UiSectionLength
- sizeof(EFI_COMMON_SECTION_HEADER2
);
1601 UINameSize
= UiSectionLength
- sizeof(EFI_COMMON_SECTION_HEADER
);
1604 UIName
= (CHAR16
*) malloc (UINameSize
+ 2);
1605 if (UIName
!= NULL
) {
1606 memset (UIName
, '\0', UINameSize
+ 2);
1607 if (UiSectionLength
>= 0xffffff) {
1608 memcpy(UIName
, ((EFI_USER_INTERFACE_SECTION2
*) Ptr
)->FileNameString
, UINameSize
);
1610 memcpy(UIName
, ((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
, UINameSize
);
1613 Error ("FMMT", 0, 0001, "Memory allocate error!", NULL
);
1614 return EFI_OUT_OF_RESOURCES
;
1617 BlankChar
= LibConstructBlankChar( CurrentFv
->FvLevel
* 2);
1618 if (BlankChar
== NULL
) {
1620 return EFI_OUT_OF_RESOURCES
;
1624 UIFileName
= malloc (UINameSize
+ 2);
1625 if (UIFileName
== NULL
) {
1626 Error ("FMMT", 0, 4001, "Memory allocation fail!", NULL
);
1629 return EFI_OUT_OF_RESOURCES
;
1631 Unicode2AsciiString (UIName
, UIFileName
);
1632 fprintf(stdout
, "%sFile \"%s\"\n", BlankChar
, UIFileName
);
1638 // If Ffs file has been generated, then the FfsCount should decrease 1.
1640 if (*IsFfsGenerated
) {
1641 memcpy (CurrentFv
->FfsAttuibutes
[*FfsCount
-1].UiName
, UIName
, UINameSize
);
1642 CurrentFv
->FfsAttuibutes
[*FfsCount
-1].UiNameSize
= UINameSize
;
1644 memcpy (CurrentFv
->FfsAttuibutes
[*FfsCount
].UiName
, UIName
, UINameSize
);
1645 CurrentFv
->FfsAttuibutes
[*FfsCount
].UiNameSize
= UINameSize
;
1648 HasDepexSection
= FALSE
;
1657 ParsedLength
+= SectionLength
;
1659 // We make then next section begin on a 4-byte boundary
1661 ParsedLength
= GetOccupiedSize (ParsedLength
, 4);
1664 if (ParsedLength
< BufferLength
) {
1665 Error ("FMMT", 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL
);
1666 return EFI_SECTION_ERROR
;
1675 Iterates through the files contained within the firmware volume
1677 @param[in] Fv - Address of the Fv in memory
1678 @param[in] Key - Should be 0 to get the first file. After that, it should be
1679 passed back in without modifying it's contents to retrieve
1681 @param[in] File- Output file pointer
1682 File == NULL - invalid parameter
1683 otherwise - *File will be update to the location of the file
1687 EFI_VOLUME_CORRUPTED
1697 EFI_FIRMWARE_VOLUME_HEADER
*hdr
;
1698 EFI_FFS_FILE_HEADER
*fhdr
;
1699 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExtHeader
;
1700 EFI_FVB_ATTRIBUTES_2 FvbAttributes
;
1705 hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
1709 return EFI_INVALID_PARAMETER
;
1712 Status
= FvBufGetSize (Fv
, &fvSize
);
1713 if (EFI_ERROR (Status
)) {
1718 if (hdr
->ExtHeaderOffset
!= 0) {
1720 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
1722 FwVolExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)((UINT8
*)hdr
+ hdr
->ExtHeaderOffset
);
1723 *Key
= (UINTN
)hdr
->ExtHeaderOffset
+ FwVolExtHeader
->ExtHeaderSize
;
1724 *Key
= (UINTN
)ALIGN_POINTER(*Key
, 8);
1726 *Key
= hdr
->HeaderLength
;
1730 FvbAttributes
= hdr
->Attributes
;
1733 *Key
= (UINTN
)ALIGN_POINTER (*Key
, 8);
1734 (*Key
+ sizeof (*fhdr
)) < fvSize
;
1735 *Key
= (UINTN
)ALIGN_POINTER (*Key
, 8)
1737 fhdr
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*)hdr
+ *Key
);
1738 fsize
= GetFfsFileLength (fhdr
);
1739 if (!EFI_TEST_FFS_ATTRIBUTES_BIT(
1742 EFI_FILE_HEADER_VALID
1744 EFI_TEST_FFS_ATTRIBUTES_BIT(
1747 EFI_FILE_HEADER_INVALID
1753 EFI_TEST_FFS_ATTRIBUTES_BIT(
1756 EFI_FILE_MARKED_FOR_UPDATE
1758 EFI_TEST_FFS_ATTRIBUTES_BIT(
1764 *Key
= *Key
+ fsize
;
1766 } else if (EFI_TEST_FFS_ATTRIBUTES_BIT(
1772 *File
= (UINT8
*)hdr
+ *Key
;
1773 *Key
= *Key
+ fsize
;
1780 return EFI_NOT_FOUND
;
1785 TODO: Add function description
1787 FvImage - TODO: add argument description
1788 FileHeader - TODO: add argument description
1789 ErasePolarity - TODO: add argument description
1791 EFI_SUCCESS - TODO: Add description for return value
1792 EFI_ABORTED - TODO: Add description for return value
1797 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
1798 EFI_FFS_FILE_HEADER2
*CurrentFile
,
1799 BOOLEAN ErasePolarity
,
1800 FV_INFORMATION
*CurrentFv
,
1803 ENCAP_INFO_DATA
**CurrentFvEncapData
,
1812 EFI_FFS_FILE_HEADER2 BlankHeader
;
1814 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1815 ENCAP_INFO_DATA
*LocalEncapData
;
1816 BOOLEAN EncapDataNeedUpdateFlag
;
1817 BOOLEAN IsGeneratedFfs
;
1818 UINT32 FfsFileHeaderSize
;
1820 Status
= EFI_SUCCESS
;
1822 LocalEncapData
= NULL
;
1823 EncapDataNeedUpdateFlag
= TRUE
;
1824 IsGeneratedFfs
= FALSE
;
1826 FfsFileHeaderSize
= GetFfsHeaderLength ((EFI_FFS_FILE_HEADER
*) CurrentFile
);
1827 FileLength
= GetFfsFileLength ((EFI_FFS_FILE_HEADER
*) CurrentFile
);
1830 // Check if we have free space
1832 if (ErasePolarity
) {
1833 memset (&BlankHeader
, -1, FfsFileHeaderSize
);
1835 memset (&BlankHeader
, 0, FfsFileHeaderSize
);
1839 // Is this FV blank?
1841 if (memcmp (&BlankHeader
, CurrentFile
, FfsFileHeaderSize
) == 0) {
1846 // Print file information.
1848 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)CurrentFile
);
1849 PrintGuidToBuffer (&(CurrentFile
->Name
), GuidBuffer
, PRINTED_GUID_BUFFER_SIZE
, FALSE
);
1850 if (FileState
== EFI_FILE_DATA_VALID
) {
1852 // Calculate header checksum
1854 Checksum
= CalculateSum8 ((UINT8
*) CurrentFile
, FfsFileHeaderSize
);
1855 Checksum
= (UINT8
) (Checksum
- CurrentFile
->IntegrityCheck
.Checksum
.File
);
1856 Checksum
= (UINT8
) (Checksum
- CurrentFile
->State
);
1857 if (Checksum
!= 0) {
1858 Error ("FMMT", 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer
);
1862 if (CurrentFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
1864 // Calculate file checksum
1866 Checksum
= CalculateSum8 ((UINT8
*) ((UINTN
)CurrentFile
+ FfsFileHeaderSize
), FileLength
- FfsFileHeaderSize
);
1867 Checksum
= Checksum
+ CurrentFile
->IntegrityCheck
.Checksum
.File
;
1868 if (Checksum
!= 0) {
1869 Error ("FMMT", 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer
);
1873 if (CurrentFile
->IntegrityCheck
.Checksum
.File
!= FFS_FIXED_CHECKSUM
) {
1874 Error ("FMMT", 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum -- not set to fixed value of 0xAA", GuidBuffer
);
1879 Error ("FMMT", 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer
);
1885 if ((CurrentFile
->Type
!= EFI_FV_FILETYPE_ALL
) && (CurrentFile
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
1888 // Put in encapsulate data information.
1890 LocalEncapData
= *CurrentFvEncapData
;
1891 if (LocalEncapData
->NextNode
!= NULL
) {
1892 LocalEncapData
= LocalEncapData
->NextNode
;
1893 EncapDataNeedUpdateFlag
= FALSE
;
1894 while (LocalEncapData
->RightNode
!= NULL
) {
1895 LocalEncapData
= LocalEncapData
->RightNode
;
1899 if (EncapDataNeedUpdateFlag
) {
1901 // Construct the new ENCAP_DATA
1903 LocalEncapData
->NextNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
1905 if (LocalEncapData
->NextNode
== NULL
) {
1906 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1910 LocalEncapData
= LocalEncapData
->NextNode
;
1912 LocalEncapData
->Level
= Level
;
1913 LocalEncapData
->Type
= FMMT_ENCAP_TREE_FFS
;
1914 LocalEncapData
->FvExtHeader
= NULL
;
1915 LocalEncapData
->Depex
= NULL
;
1916 LocalEncapData
->DepexLen
= 0;
1917 LocalEncapData
->UiNameSize
= 0;
1919 // Store the header of FFS file.
1921 LocalEncapData
->Data
= malloc (FfsFileHeaderSize
);
1922 if (LocalEncapData
->Data
== NULL
) {
1923 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1927 memcpy (LocalEncapData
->Data
, CurrentFile
, FfsFileHeaderSize
);
1928 LocalEncapData
->FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)malloc(sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER
));
1929 if (LocalEncapData
->FvExtHeader
== NULL
) {
1930 Error(NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1933 LocalEncapData
->FvExtHeader
->FvName
.Data1
= CurrentFile
->Name
.Data1
;
1934 LocalEncapData
->FvExtHeader
->FvName
.Data2
= CurrentFile
->Name
.Data2
;
1935 LocalEncapData
->FvExtHeader
->FvName
.Data3
= CurrentFile
->Name
.Data3
;
1936 LocalEncapData
->FvExtHeader
->FvName
.Data4
[0] = CurrentFile
->Name
.Data4
[0];
1937 LocalEncapData
->FvExtHeader
->FvName
.Data4
[1] = CurrentFile
->Name
.Data4
[1];
1938 LocalEncapData
->FvExtHeader
->FvName
.Data4
[2] = CurrentFile
->Name
.Data4
[2];
1939 LocalEncapData
->FvExtHeader
->FvName
.Data4
[3] = CurrentFile
->Name
.Data4
[3];
1940 LocalEncapData
->FvExtHeader
->FvName
.Data4
[4] = CurrentFile
->Name
.Data4
[4];
1941 LocalEncapData
->FvExtHeader
->FvName
.Data4
[5] = CurrentFile
->Name
.Data4
[5];
1942 LocalEncapData
->FvExtHeader
->FvName
.Data4
[6] = CurrentFile
->Name
.Data4
[6];
1943 LocalEncapData
->FvExtHeader
->FvName
.Data4
[7] = CurrentFile
->Name
.Data4
[7];
1944 LocalEncapData
->NextNode
= NULL
;
1945 LocalEncapData
->RightNode
= NULL
;
1948 // Construct the new ENCAP_DATA
1950 LocalEncapData
->RightNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
1952 if (LocalEncapData
->RightNode
== NULL
) {
1953 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1957 LocalEncapData
= LocalEncapData
->RightNode
;
1959 LocalEncapData
->Level
= Level
;
1960 LocalEncapData
->Type
= FMMT_ENCAP_TREE_FFS
;
1961 LocalEncapData
->FvExtHeader
= NULL
;
1962 LocalEncapData
->Depex
= NULL
;
1963 LocalEncapData
->DepexLen
= 0;
1964 LocalEncapData
->UiNameSize
= 0;
1966 // Store the header of FFS file.
1968 LocalEncapData
->Data
= malloc (FfsFileHeaderSize
);
1969 if (LocalEncapData
->Data
== NULL
) {
1970 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1974 memcpy (LocalEncapData
->Data
, CurrentFile
, FfsFileHeaderSize
);
1975 LocalEncapData
->FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)malloc(sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER
));
1976 if (LocalEncapData
->FvExtHeader
== NULL
) {
1977 Error(NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
1980 LocalEncapData
->FvExtHeader
->FvName
.Data1
= CurrentFile
->Name
.Data1
;
1981 LocalEncapData
->FvExtHeader
->FvName
.Data2
= CurrentFile
->Name
.Data2
;
1982 LocalEncapData
->FvExtHeader
->FvName
.Data3
= CurrentFile
->Name
.Data3
;
1983 LocalEncapData
->FvExtHeader
->FvName
.Data4
[0] = CurrentFile
->Name
.Data4
[0];
1984 LocalEncapData
->FvExtHeader
->FvName
.Data4
[1] = CurrentFile
->Name
.Data4
[1];
1985 LocalEncapData
->FvExtHeader
->FvName
.Data4
[2] = CurrentFile
->Name
.Data4
[2];
1986 LocalEncapData
->FvExtHeader
->FvName
.Data4
[3] = CurrentFile
->Name
.Data4
[3];
1987 LocalEncapData
->FvExtHeader
->FvName
.Data4
[4] = CurrentFile
->Name
.Data4
[4];
1988 LocalEncapData
->FvExtHeader
->FvName
.Data4
[5] = CurrentFile
->Name
.Data4
[5];
1989 LocalEncapData
->FvExtHeader
->FvName
.Data4
[6] = CurrentFile
->Name
.Data4
[6];
1990 LocalEncapData
->FvExtHeader
->FvName
.Data4
[7] = CurrentFile
->Name
.Data4
[7];
1991 LocalEncapData
->RightNode
= NULL
;
1992 LocalEncapData
->NextNode
= NULL
;
1995 if ( CurrentFile
->Type
== EFI_FV_FILETYPE_RAW
){
1996 CurrentFv
->FfsAttuibutes
[*FfsCount
].Level
= Level
;
1998 LibGenFfsFile(CurrentFile
, CurrentFv
, FvName
, Level
, FfsCount
, ErasePolarity
);
2000 } else if( CurrentFile
->Type
== EFI_FV_FILETYPE_FFS_PAD
){
2001 //EFI_FV_FILETYPE_FFS_PAD
2004 // All other files have sections
2006 Status
= LibParseSection (
2007 (UINT8
*) ((UINTN
) CurrentFile
+ FfsFileHeaderSize
),
2008 FileLength
- FfsFileHeaderSize
,
2022 if (EFI_ERROR (Status
)) {
2023 printf ("ERROR: Parsing the FFS file.\n");
2034 Get firmware information. Including the FV headers,
2036 @param[in] Fv - Firmware Volume to get information from
2044 IN OUT FV_INFORMATION
*CurrentFv
,
2047 IN ENCAP_INFO_DATA
**CurrentFvEncapData
,
2048 IN UINT32
*FfsCount
,
2049 IN OUT UINT8
*FvCount
,
2050 IN BOOLEAN ViewFlag
,
2051 IN BOOLEAN IsChildFv
2055 UINTN NumberOfFiles
;
2056 BOOLEAN ErasePolarity
;
2058 EFI_FFS_FILE_HEADER2
*CurrentFile
;
2060 ENCAP_INFO_DATA
*LocalEncapData
;
2061 EFI_FIRMWARE_VOLUME_EXT_HEADER
*ExtHdrPtr
;
2062 EFI_FIRMWARE_VOLUME_HEADER
*FvHdr
;
2066 LocalEncapData
= NULL
;
2068 FvHdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
2073 CurrentFv
->FvLevel
+= 1;
2075 Status
= FvBufGetSize (Fv
, &FvSize
);
2077 ErasePolarity
= (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) ? TRUE
: FALSE
;
2079 Status
= LibReadFvHeader (Fv
, ViewFlag
, CurrentFv
->FvLevel
, *FvCount
- 1, CurrentFv
->FvName
);
2080 if (EFI_ERROR (Status
)) {
2081 Error (NULL
, 0, 0003, "error parsing FV image", "Header is invalid");
2087 // Write FV header information into CurrentFv struct.
2089 CurrentFv
->FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) malloc (FvHdr
->HeaderLength
);
2091 if (CurrentFv
->FvHeader
== NULL
) {
2092 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2097 // Get the FV Header information
2099 memcpy(CurrentFv
->FvHeader
, Fv
, FvHdr
->HeaderLength
);
2100 CurrentFv
->FvExtHeader
= NULL
;
2101 CurrentFv
->FvUiName
= NULL
;
2104 // Exist Extend FV header.
2106 if (CurrentFv
->FvHeader
->ExtHeaderOffset
!= 0){
2107 ExtHdrPtr
= (VOID
*)((UINTN
)Fv
+ CurrentFv
->FvHeader
->ExtHeaderOffset
);
2108 CurrentFv
->FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) malloc (ExtHdrPtr
->ExtHeaderSize
);
2110 if (CurrentFv
->FvExtHeader
== NULL
) {
2111 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2116 // Get the FV extended Header information
2118 memcpy (CurrentFv
->FvExtHeader
, (VOID
*)((UINTN
)Fv
+ CurrentFv
->FvHeader
->ExtHeaderOffset
), ExtHdrPtr
->ExtHeaderSize
);
2119 LibExtractFvUiName(CurrentFv
->FvExtHeader
, &CurrentFv
->FvUiName
);
2124 // Put encapsulate information into structure.
2126 LocalEncapData
= *CurrentFvEncapData
;
2127 if (LocalEncapData
== NULL
&& !IsChildFv
) {
2129 // First time in, the root FV
2131 LocalEncapData
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
2132 CurrentFv
->EncapData
= LocalEncapData
;
2133 if (CurrentFv
->EncapData
== NULL
) {
2134 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2138 CurrentFv
->EncapData
->FvExtHeader
= NULL
;
2139 CurrentFv
->EncapData
->Depex
= NULL
;
2140 CurrentFv
->EncapData
->DepexLen
= 0;
2141 CurrentFv
->EncapData
->UiNameSize
= 0;
2142 CurrentFv
->EncapData
->Level
= Level
;
2143 CurrentFv
->EncapData
->Type
= FMMT_ENCAP_TREE_FV
;
2144 CurrentFv
->EncapData
->Data
= (EFI_FIRMWARE_VOLUME_HEADER
*) malloc (sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
2145 CurrentFv
->EncapData
->FvId
= *FvCount
;
2147 if (CurrentFv
->EncapData
->Data
== NULL
) {
2148 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2152 memcpy (CurrentFv
->EncapData
->Data
, Fv
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
2154 if (((EFI_FIRMWARE_VOLUME_HEADER
*)(CurrentFv
->EncapData
->Data
))->ExtHeaderOffset
!= 0) {
2155 ExtHdrPtr
= (VOID
*)((UINTN
)Fv
+ ((EFI_FIRMWARE_VOLUME_HEADER
*)(CurrentFv
->EncapData
->Data
))->ExtHeaderOffset
);
2156 CurrentFv
->EncapData
->FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) malloc (ExtHdrPtr
->ExtHeaderSize
);
2158 if (CurrentFv
->EncapData
->FvExtHeader
== NULL
) {
2159 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2164 // Get the FV extended Header information
2166 memcpy(CurrentFv
->EncapData
->FvExtHeader
, (VOID
*)((UINTN
)Fv
+ ((EFI_FIRMWARE_VOLUME_HEADER
*)(CurrentFv
->EncapData
->Data
))->ExtHeaderOffset
), ExtHdrPtr
->ExtHeaderSize
);
2169 CurrentFv
->EncapData
->NextNode
= NULL
;
2170 CurrentFv
->EncapData
->RightNode
= NULL
;
2171 } else if (LocalEncapData
== NULL
) {
2173 } else if (IsChildFv
) {
2175 LocalEncapData
= *CurrentFvEncapData
;
2176 while (LocalEncapData
->NextNode
!= NULL
) {
2177 LocalEncapData
= LocalEncapData
->NextNode
;
2181 // Construct the new ENCAP_DATA
2183 LocalEncapData
->NextNode
= (ENCAP_INFO_DATA
*) malloc (sizeof (ENCAP_INFO_DATA
));
2185 if (LocalEncapData
->NextNode
== NULL
) {
2186 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2190 LocalEncapData
= LocalEncapData
->NextNode
;
2192 LocalEncapData
->Level
= Level
;
2193 LocalEncapData
->Type
= FMMT_ENCAP_TREE_FV
;
2194 LocalEncapData
->Data
= (EFI_FIRMWARE_VOLUME_HEADER
*) malloc (sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
2195 LocalEncapData
->FvExtHeader
= NULL
;
2196 LocalEncapData
->Depex
= NULL
;
2197 LocalEncapData
->DepexLen
= 0;
2198 LocalEncapData
->UiNameSize
= 0;
2199 LocalEncapData
->FvId
= *FvCount
;
2200 if (LocalEncapData
->Data
== NULL
) {
2201 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2205 memcpy (LocalEncapData
->Data
, Fv
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
2207 if (((EFI_FIRMWARE_VOLUME_HEADER
*)(LocalEncapData
->Data
))->ExtHeaderOffset
!= 0) {
2208 ExtHdrPtr
= (VOID
*)((UINTN
)Fv
+ ((EFI_FIRMWARE_VOLUME_HEADER
*)(LocalEncapData
->Data
))->ExtHeaderOffset
);
2209 LocalEncapData
->FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)malloc(ExtHdrPtr
->ExtHeaderSize
);
2211 if (LocalEncapData
->FvExtHeader
== NULL
) {
2212 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2217 // Get the FV extended Header information
2219 memcpy(LocalEncapData
->FvExtHeader
, (VOID
*)((UINTN
)Fv
+ ((EFI_FIRMWARE_VOLUME_HEADER
*)(LocalEncapData
->Data
))->ExtHeaderOffset
), ExtHdrPtr
->ExtHeaderSize
);
2222 LocalEncapData
->NextNode
= NULL
;
2223 LocalEncapData
->RightNode
= NULL
;
2229 // Get the first file
2231 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
2232 if (Status
== EFI_NOT_FOUND
) {
2234 } else if (EFI_ERROR (Status
)) {
2235 Error ("FMMT", 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
2239 while (CurrentFile
!= NULL
) {
2242 // Increment the number of files counter
2247 // Store FFS file Header information
2249 CurrentFv
->FfsHeader
[*FfsCount
].Attributes
= CurrentFile
->Attributes
;
2250 CurrentFv
->FfsHeader
[*FfsCount
].IntegrityCheck
= CurrentFile
->IntegrityCheck
;
2251 CurrentFv
->FfsHeader
[*FfsCount
].Name
= CurrentFile
->Name
;
2252 CurrentFv
->FfsHeader
[*FfsCount
].Size
[0] = CurrentFile
->Size
[0];
2253 CurrentFv
->FfsHeader
[*FfsCount
].Size
[1] = CurrentFile
->Size
[1];
2254 CurrentFv
->FfsHeader
[*FfsCount
].Size
[2] = CurrentFile
->Size
[2];
2255 CurrentFv
->FfsHeader
[*FfsCount
].State
= CurrentFile
->State
;
2256 CurrentFv
->FfsHeader
[*FfsCount
].Type
= CurrentFile
->Type
;
2257 CurrentFv
->FfsHeader
[*FfsCount
].ExtendedSize
= CurrentFile
->ExtendedSize
;
2258 CurrentFv
->FfsAttuibutes
[*FfsCount
].Offset
= Key
- GetFfsFileLength ((EFI_FFS_FILE_HEADER
*) CurrentFile
);
2260 CurrentFv
->FfsAttuibutes
[*FfsCount
].FvLevel
= CurrentFv
->FvLevel
;
2261 if (CurrentFv
->FvLevel
> CurrentFv
->MulFvLevel
) {
2262 CurrentFv
->MulFvLevel
= CurrentFv
->FvLevel
;
2265 // Display info about this file
2267 Status
= LibGetFileInfo (Fv
, CurrentFile
, ErasePolarity
, CurrentFv
, FvName
, Level
, &LocalEncapData
, FfsCount
, FvCount
, ViewFlag
);
2268 if (EFI_ERROR (Status
)) {
2269 Error ("FMMT", 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
2274 // Get the next file
2276 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
2277 if (Status
== EFI_NOT_FOUND
) {
2279 } else if (EFI_ERROR (Status
)) {
2280 Error ("FMMT", 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
2286 if (CurrentFv
->FvLevel
> 1) {
2287 CurrentFv
->FvLevel
-= 1;
2295 This function returns the next larger size that meets the alignment
2296 requirement specified.
2298 @param[in] ActualSize The size.
2299 @param[in] Alignment The desired alignment.
2301 @retval EFI_SUCCESS Function completed successfully.
2302 @retval EFI_ABORTED The function encountered an error.
2307 IN UINT32 ActualSize
,
2311 UINT32 OccupiedSize
;
2313 OccupiedSize
= ActualSize
;
2314 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
2318 return OccupiedSize
;
2324 LibDeleteAndRenameFfs(
2325 IN CHAR8
* DeleteFile
,
2329 CHAR8
* SystemCommand
;
2331 SystemCommand
= NULL
;
2333 if (DeleteFile
== NULL
||
2335 return EFI_INVALID_PARAMETER
;
2339 // Delete the file of the specified extract FFS file.
2341 SystemCommand
= malloc (
2343 strlen (DeleteFile
) +
2346 if (SystemCommand
== NULL
) {
2347 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2357 if (system (SystemCommand
) != EFI_SUCCESS
) {
2358 free(SystemCommand
);
2361 free(SystemCommand
);
2363 TemDir
= getcwd (NULL
, _MAX_PATH
);
2364 if (strlen (TemDir
) + strlen(OS_SEP_STR
) + strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
2365 Error("FMMT", 0, 1001, "The directory is too long.", "");
2368 strncat (TemDir
, OS_SEP_STR
, _MAX_PATH
- strlen(TemDir
) - 1);
2369 strncat (TemDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen(TemDir
) - 1);
2371 mkdir(TemDir
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
2373 // Create a copy the new file.
2376 SystemCommand
= malloc (
2379 strlen (DeleteFile
) +
2382 if (SystemCommand
== NULL
) {
2383 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2394 if (system (SystemCommand
) != EFI_SUCCESS
) {
2395 free(SystemCommand
);
2398 free(SystemCommand
);
2405 Converts ASCII characters to Unicode.
2406 Assumes that the Unicode characters are only these defined in the ASCII set.
2408 String - Pointer to string that is written to FILE.
2409 UniString - Pointer to unicode string
2411 The address to the ASCII string - same as AsciiStr.
2417 OUT CHAR16
*UniString
2420 while (*String
!= '\0') {
2421 *(UniString
++) = (CHAR16
) *(String
++);
2424 // End the UniString with a NULL.
2431 LibCreateGuidedSectionOriginalData(
2437 CHAR8
* SystemCommandFormatString
;
2438 CHAR8
* SystemCommand
;
2440 SystemCommandFormatString
= NULL
;
2441 SystemCommand
= NULL
;
2443 if (FileIn
== NULL
||
2446 return EFI_INVALID_PARAMETER
;
2450 // Delete the file of the specified extract FFS file.
2452 SystemCommandFormatString
= "%s -e \"%s\" -o \"%s\"";
2454 SystemCommand
= malloc (
2455 strlen (SystemCommandFormatString
) +
2461 if (SystemCommand
== NULL
) {
2462 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2468 "%s -e \"%s\" -o \"%s\"",
2474 if (system (SystemCommand
) != EFI_SUCCESS
) {
2475 printf("Command failed: %s\n", SystemCommand
);
2476 free(SystemCommand
);
2479 free(SystemCommand
);
2486 This function convert the FV header's attribute to a string. The converted string
2487 will be put into an INF file as the input of GenFV.
2489 @param[in] Attr FV header's attribute.
2490 @param[out] InfFile InfFile contain FV header attribute information.
2492 @retval EFI_SUCCESS.
2493 @retval EFI_INVLID_PARAMETER
2494 @retval EFI_OUT_OF_RESOURCES
2498 LibFvHeaderAttributeToStr (
2499 IN EFI_FVB_ATTRIBUTES_2 Attr
,
2507 LocalStr
= (CHAR8
*) malloc (1024 * 4);
2509 if (LocalStr
== NULL
) {
2510 printf ("Memory allocate error!\n");
2511 return EFI_OUT_OF_RESOURCES
;
2514 memset (LocalStr
, '\0', 1024 * 4);
2516 if (Attr
== 0 || InfFile
== NULL
) {
2518 return EFI_INVALID_PARAMETER
;
2521 strncat (LocalStr
, "[attributes] \n", sizeof("[attributes] \n"));
2523 if (Attr
& EFI_FVB2_READ_DISABLED_CAP
) {
2524 strncat (LocalStr
, "EFI_READ_DISABLED_CAP = TRUE \n", sizeof ("EFI_READ_DISABLED_CAP = TRUE \n"));
2527 if (Attr
& EFI_FVB2_READ_ENABLED_CAP
) {
2528 strncat (LocalStr
, "EFI_READ_ENABLED_CAP = TRUE \n", sizeof ("EFI_READ_ENABLED_CAP = TRUE \n"));
2531 if (Attr
& EFI_FVB2_READ_STATUS
) {
2532 strncat (LocalStr
, "EFI_READ_STATUS = TRUE \n", sizeof ("EFI_READ_STATUS = TRUE \n"));
2535 if (Attr
& EFI_FVB2_WRITE_DISABLED_CAP
) {
2536 strncat (LocalStr
, "EFI_WRITE_DISABLED_CAP = TRUE \n", sizeof ("EFI_WRITE_DISABLED_CAP = TRUE \n"));
2539 if (Attr
& EFI_FVB2_WRITE_ENABLED_CAP
) {
2540 strncat (LocalStr
, "EFI_WRITE_ENABLED_CAP = TRUE \n", sizeof ("EFI_WRITE_ENABLED_CAP = TRUE \n"));
2543 if (Attr
& EFI_FVB2_WRITE_STATUS
) {
2544 strncat (LocalStr
, "EFI_WRITE_STATUS = TRUE \n", sizeof ("EFI_WRITE_STATUS = TRUE \n"));
2547 if (Attr
& EFI_FVB2_LOCK_CAP
) {
2548 strncat (LocalStr
, "EFI_LOCK_CAP = TRUE \n", sizeof ("EFI_LOCK_CAP = TRUE \n"));
2551 if (Attr
& EFI_FVB2_LOCK_STATUS
) {
2552 strncat (LocalStr
, "EFI_LOCK_STATUS = TRUE \n", sizeof ("EFI_LOCK_STATUS = TRUE \n"));
2555 if (Attr
& EFI_FVB2_STICKY_WRITE
) {
2556 strncat (LocalStr
, "EFI_STICKY_WRITE = TRUE \n", sizeof ("EFI_STICKY_WRITE = TRUE \n"));
2559 if (Attr
& EFI_FVB2_MEMORY_MAPPED
) {
2560 strncat (LocalStr
, "EFI_MEMORY_MAPPED = TRUE \n", sizeof ("EFI_MEMORY_MAPPED = TRUE \n"));
2563 if (Attr
& EFI_FVB2_ERASE_POLARITY
) {
2564 strncat (LocalStr
, "EFI_ERASE_POLARITY = 1 \n", sizeof ("EFI_ERASE_POLARITY = 1 \n"));
2567 if (Attr
& EFI_FVB2_READ_LOCK_CAP
) {
2568 strncat (LocalStr
, "EFI_READ_LOCK_CAP = TRUE \n", sizeof ("EFI_READ_LOCK_CAP = TRUE \n"));
2571 if (Attr
& EFI_FVB2_READ_LOCK_STATUS
) {
2572 strncat (LocalStr
, "EFI_READ_LOCK_STATUS = TRUE \n", sizeof ("EFI_READ_LOCK_STATUS = TRUE \n"));
2575 if (Attr
& EFI_FVB2_WRITE_LOCK_CAP
) {
2576 strncat (LocalStr
, "EFI_WRITE_LOCK_CAP = TRUE \n", sizeof ("EFI_WRITE_LOCK_CAP = TRUE \n"));
2579 if (Attr
& EFI_FVB2_WRITE_LOCK_STATUS
) {
2580 strncat (LocalStr
, "EFI_WRITE_LOCK_STATUS = TRUE \n", sizeof ("EFI_WRITE_LOCK_STATUS = TRUE \n"));
2583 if (Attr
& EFI_FVB2_LOCK_STATUS
) {
2584 strncat (LocalStr
, "EFI_READ_LOCK_STATUS = TRUE \n", sizeof ("EFI_READ_LOCK_STATUS = TRUE \n"));
2590 if (Attr
& EFI_FVB2_ALIGNMENT_1
) {
2591 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_1 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1 = TRUE \n"));
2592 } else if (Attr
& EFI_FVB2_ALIGNMENT_2
) {
2593 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_2 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2 = TRUE \n"));
2594 } else if (Attr
& EFI_FVB2_ALIGNMENT_4
) {
2595 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_4 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_4 = TRUE \n"));
2596 } else if (Attr
& EFI_FVB2_ALIGNMENT_8
) {
2597 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_8 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_8 = TRUE \n"));
2598 } else if (Attr
& EFI_FVB2_ALIGNMENT_16
) {
2599 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_16 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_16 = TRUE \n"));
2600 } else if (Attr
& EFI_FVB2_ALIGNMENT_32
) {
2601 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_32 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_32 = TRUE \n"));
2602 } else if (Attr
& EFI_FVB2_ALIGNMENT_64
) {
2603 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_64 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_64 = TRUE \n"));
2604 } else if (Attr
& EFI_FVB2_ALIGNMENT_128
) {
2605 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_128 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_128 = TRUE \n"));
2606 } else if (Attr
& EFI_FVB2_ALIGNMENT_256
) {
2607 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_256 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_256 = TRUE \n"));
2608 } else if (Attr
& EFI_FVB2_ALIGNMENT_512
) {
2609 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_512 = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_512 = TRUE \n"));
2610 } else if (Attr
& EFI_FVB2_ALIGNMENT_1K
) {
2611 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_1K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1K = TRUE \n"));
2612 } else if (Attr
& EFI_FVB2_ALIGNMENT_2K
) {
2613 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_2K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2K = TRUE \n"));
2614 } else if (Attr
& EFI_FVB2_ALIGNMENT_4K
) {
2615 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_4K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_4K = TRUE \n"));
2616 } else if (Attr
& EFI_FVB2_ALIGNMENT_8K
) {
2617 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_8K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_8K = TRUE \n"));
2618 } else if (Attr
& EFI_FVB2_ALIGNMENT_16K
) {
2619 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_16K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_16K = TRUE \n"));
2620 } else if (Attr
& EFI_FVB2_ALIGNMENT_32K
) {
2621 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_32K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_32K = TRUE \n"));
2622 } else if (Attr
& EFI_FVB2_ALIGNMENT_64K
) {
2623 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_64K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_64K = TRUE \n"));
2624 } else if (Attr
& EFI_FVB2_ALIGNMENT_128K
) {
2625 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_128K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_128K = TRUE \n"));
2626 } else if (Attr
& EFI_FVB2_ALIGNMENT_256K
) {
2627 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_256K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_256K = TRUE \n"));
2628 } else if (Attr
& EFI_FVB2_ALIGNMENT_512K
) {
2629 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_512K = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_512K = TRUE \n"));
2630 } else if (Attr
& EFI_FVB2_ALIGNMENT_1M
) {
2631 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_1M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1M = TRUE \n"));
2632 } else if (Attr
& EFI_FVB2_ALIGNMENT_2M
) {
2633 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_2M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2M = TRUE \n"));
2634 } else if (Attr
& EFI_FVB2_ALIGNMENT_4M
) {
2635 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_4M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_4M = TRUE \n"));
2636 } else if (Attr
& EFI_FVB2_ALIGNMENT_8M
) {
2637 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_8M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_8M = TRUE \n"));
2638 } else if (Attr
& EFI_FVB2_ALIGNMENT_16M
) {
2639 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_16M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_16M = TRUE \n"));
2640 } else if (Attr
& EFI_FVB2_ALIGNMENT_32M
) {
2641 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_32M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_32M = TRUE \n"));
2642 } else if (Attr
& EFI_FVB2_ALIGNMENT_64M
) {
2643 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_64M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_64M = TRUE \n"));
2644 } else if (Attr
& EFI_FVB2_ALIGNMENT_128M
) {
2645 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_128M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_128M = TRUE \n"));
2646 } else if (Attr
& EFI_FVB2_ALIGNMENT_256M
) {
2647 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_256M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_256M = TRUE \n"));
2648 } else if (Attr
& EFI_FVB2_ALIGNMENT_512M
) {
2649 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_512M = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_512M = TRUE \n"));
2650 } else if (Attr
& EFI_FVB2_ALIGNMENT_1G
) {
2651 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_1G = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_1G = TRUE \n"));
2652 } else if (Attr
& EFI_FVB2_ALIGNMENT_2G
) {
2653 strncat (LocalStr
, "EFI_FVB2_ALIGNMENT_2G = TRUE \n", sizeof ("EFI_FVB2_ALIGNMENT_2G = TRUE \n"));
2656 if (fwrite (LocalStr
, 1, (size_t) strlen (LocalStr
), InfFile
) != (size_t) strlen (LocalStr
)) {
2657 printf ("Error while writing data to %p file.", (void*)InfFile
);
2669 This function fill the FV inf files option field.
2671 @param[in] BlockMap FV header's attribute.
2672 @param[out] InfFile InfFile contain FV header attribute information.
2674 @retval EFI_SUCCESS.
2675 @retval EFI_INVLID_PARAMETER
2679 LibFvHeaderOptionToStr (
2680 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
2687 EFI_FV_BLOCK_MAP_ENTRY
*BlockMap
;
2692 if (FvHeader
== NULL
|| InfFile
== NULL
) {
2693 return EFI_INVALID_PARAMETER
;
2697 // This section will not over 1024 bytes and each line will never over 128 bytes.
2699 LocalStr
= (CHAR8
*) malloc (1024);
2700 TempStr
= (CHAR8
*) malloc (128);
2702 if (LocalStr
== NULL
||
2704 if (LocalStr
!= NULL
) {
2707 if (TempStr
!= NULL
) {
2710 printf ("Memory allocate error! \n");
2711 return EFI_OUT_OF_RESOURCES
;
2714 BlockMap
= FvHeader
->BlockMap
;
2715 memset (LocalStr
, '\0', 1024);
2716 memset (TempStr
, '\0', 128);
2718 strncat (LocalStr
, "[options] \n", sizeof("[Options] \n"));
2721 snprintf (TempStr
, 128, "EFI_BLOCK_SIZE = 0x%x \n", BlockMap
->Length
);
2722 strncat (LocalStr
, TempStr
, strlen(TempStr
));
2725 snprintf (TempStr
, 128, "EFI_NUM_BLOCKS = 0x%x \n", BlockMap
->NumBlocks
);
2726 strncat (LocalStr
, TempStr
, strlen(TempStr
));
2729 if (fwrite (LocalStr
, 1, (size_t) strlen (LocalStr
), InfFile
) != (size_t) strlen (LocalStr
)) {
2730 printf ("Error while writing data to %p file.", (void*)InfFile
);
2743 This function fill the FV inf files option field.
2745 @param[in] FfsName Ffs file path/name.
2746 @param[out] InfFile InfFile contain FV header attribute information
2747 @param[in] FirstIn Is the first time call this function? If yes, should create [files] section.
2749 @retval EFI_SUCCESS.
2750 @retval EFI_INVLID_PARAMETER
2754 LibAddFfsFileToFvInf (
2765 if (FfsName
== NULL
|| InfFile
== NULL
) {
2766 return EFI_INVALID_PARAMETER
;
2769 if (strlen(FfsName
) == 0) {
2773 LocalStr
= (CHAR8
*) malloc (_MAX_PATH
);
2775 if (LocalStr
== NULL
) {
2776 printf ("Memory allocate error! \n");
2777 return EFI_OUT_OF_RESOURCES
;
2780 memset (LocalStr
, '\0', _MAX_PATH
);
2783 sprintf (LocalStr
, "[files] \nEFI_FILE_NAME = %s \n", FfsName
);
2785 sprintf (LocalStr
, "EFI_FILE_NAME = %s \n", FfsName
);
2788 if (fwrite (LocalStr
, 1, (size_t) strlen (LocalStr
), InfFile
) != (size_t) strlen (LocalStr
)) {
2789 printf ("Error while writing data to %p file.", (void*)InfFile
);
2801 Convert EFI file to PE or TE section
2803 @param[in] InputFilePath .efi file, it's optional unless process PE/TE section.
2804 @param[in] Type PE or TE and UI/Version
2805 @param[in] OutputFilePath .te or .pe file
2806 @param[in] UiString String for generate UI section usage, this parameter is optional
2807 unless Type is EFI_SECTION_USER_INTERFACE.
2808 @param[in] VerString String for generate Version section usage, this parameter is optional
2809 unless Type is EFI_SECTION_VERSION.
2815 LibCreateFfsSection (
2816 IN FV_INFORMATION
*FvInFd
, OPTIONAL
2817 IN CHAR8
* InputFilePath
, OPTIONAL
2818 IN CHAR8
* Sections
, OPTIONAL
2820 IN CHAR8
* OutputFilePath
,
2821 IN CHAR8
* UiString
, OPTIONAL
2822 IN CHAR8
* VerString
, OPTIONAL
2823 IN CHAR8
* GuidToolGuid
, OPTIONAL
2824 IN UINT16 GuidHeaderLength
,
2826 IN CHAR8
* CompressType OPTIONAL
2829 //EFI_STATUS Status;
2830 CHAR8
* SystemCommandFormatString
;
2831 CHAR8
* SystemCommand
;
2836 UINT32 AlignmentValue
;
2838 // Workaround for static code checkers.
2839 // Ensures the size of 'AlignmentStr' can hold all the digits of an
2840 // unsigned 32-bit integer plus the size unit character.
2842 char AlignmentStr
[16];
2844 SystemCommandFormatString
= NULL
;
2845 SystemCommand
= NULL
;
2846 strcpy(AlignmentStr
,"1");
2848 // Call GenSec tool to generate FFS section.
2857 // Process compression section
2859 case EFI_SECTION_COMPRESSION
:
2860 SystemCommandFormatString
= "GenSec -s %s -c %s \"%s\" -o \"%s\"";
2861 SystemCommand
= malloc (
2862 strlen (SystemCommandFormatString
) +
2863 strlen (mSectionTypeName
[Type
]) +
2864 strlen (CompressType
) +
2865 strlen (InputFilePath
) +
2866 strlen (OutputFilePath
) +
2869 if (SystemCommand
== NULL
) {
2870 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2875 "GenSec -s %s -c %s \"%s\" -o \"%s\"",
2876 mSectionTypeName
[Type
],
2882 if (system (SystemCommand
) != EFI_SUCCESS
) {
2883 free(SystemCommand
);
2886 free(SystemCommand
);
2890 // Process GUID defined section
2892 case EFI_SECTION_GUID_DEFINED
:
2893 SystemCommandFormatString
= "GenSec -s %s -g %s \"%s\" -o \"%s\" -r %s -r %s -l %d";
2894 SystemCommand
= malloc (
2895 strlen (SystemCommandFormatString
) +
2896 strlen (mSectionTypeName
[Type
]) +
2897 strlen (GuidToolGuid
) +
2898 strlen (InputFilePath
) +
2899 strlen (OutputFilePath
) +
2900 strlen (mGuidSectionAttr
[GuidAttr
&0x01]) +
2901 strlen (mGuidSectionAttr
[GuidAttr
&0x02]) +
2905 if (SystemCommand
== NULL
) {
2906 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2911 "GenSec -s %s -g %s \"%s\" -o \"%s\" -r %s -r %s -l %d",
2912 mSectionTypeName
[Type
],
2916 mGuidSectionAttr
[GuidAttr
&0x01],
2917 mGuidSectionAttr
[GuidAttr
&0x02],
2921 if (system (SystemCommand
) != EFI_SUCCESS
) {
2922 free(SystemCommand
);
2925 free(SystemCommand
);
2928 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
2930 SystemCommandFormatString
= "GenSec -s %s \"%s\" -o \"%s\"";
2931 SystemCommand
= malloc (
2932 strlen (SystemCommandFormatString
) +
2933 strlen (mSectionTypeName
[Type
]) +
2934 strlen (InputFilePath
) +
2935 strlen (OutputFilePath
) +
2938 if (SystemCommand
== NULL
) {
2939 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
2944 "GenSec -s %s \"%s\" -o \"%s\"",
2945 mSectionTypeName
[Type
],
2950 if (system (SystemCommand
) != EFI_SUCCESS
) {
2951 free(SystemCommand
);
2954 free(SystemCommand
);
2958 Error ("FMMT", 0, 0003, "Please specify the section type while call GenSec tool.", NULL
);
2959 return EFI_UNSUPPORTED
;
2963 // Create Dummy section.
2965 file
= fopen(InputFilePath
, "rb");
2967 Error(NULL
, 0, 0001, "Error opening the file", InputFilePath
);
2968 return EFI_INVALID_PARAMETER
;
2970 // The Section Struct, 3 bits for Size, then 1 bit for Type
2971 if (fread(Buffer
, 1, (size_t)(4), file
) != (size_t)(4)) {
2975 if (*(Buffer
+ 3) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE
) {
2976 // The Section Struct, if size is not 0xFFFF, the length is 4
2978 // If Size is 0xFFFFFF then ExtendedSize contains the size of the section
2979 if ((*Buffer
== 0xFF) && (*(Buffer
+ 1) == 0xFF) && (*(Buffer
+ 2) == 0xFF)) {
2982 //Per EFI_FIRMWARE_VOLUME_HEADER struct, 0x2E bit is EFI_FVB_ATTRIBUTES_2 attr
2983 fseek(file
, 0x2E + Position
, SEEK_SET
);
2984 BitNum
= fgetc(file
);
2985 AlignmentValue
= 1 << (BitNum
& 0x1F);
2986 if (AlignmentValue
>= 0x400){
2987 if (AlignmentValue
>= 0x10000){
2988 strcpy(AlignmentStr
,"64K");
2991 sprintf(AlignmentStr
, "%d", AlignmentValue
/0x400);
2992 strcat(AlignmentStr
, "K");
2996 sprintf(AlignmentStr
, "%d", AlignmentValue
);
2998 strcpy(FvInFd
->AlignmentStr
, AlignmentStr
);
3001 SystemCommandFormatString
= "GenSec \"%s\" -o \"%s\" --sectionalign %s";
3002 SystemCommand
= malloc (
3003 strlen (SystemCommandFormatString
) +
3004 strlen (InputFilePath
) +
3005 strlen (OutputFilePath
) +
3006 4 + // Alignment maximum length
3009 if (SystemCommand
== NULL
) {
3010 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3015 "GenSec \"%s\" -o \"%s\" --sectionalign %s",
3021 if (system (SystemCommand
) != EFI_SUCCESS
) {
3022 free(SystemCommand
);
3025 free(SystemCommand
);
3033 Encapsulate FFSs to FV
3035 @param[in] InputFilePath Section file will be read into this FFS file. This option is required.
3036 @param[in] OutputFilePath The created PI firmware file name. This option is required.
3037 @param[in] BlockSize BlockSize is one HEX or DEC format value required by FV image.
3038 @param[in] FileTakeSize
3044 LibEncapsulateFfsToFv (
3045 IN CHAR8
* InfFilePath
,
3046 IN CHAR8
* InputFFSs
,
3047 IN CHAR8
* OutputFilePath
,
3048 IN CHAR8
* FvGuidName
,
3049 IN BOOLEAN IsLargeFile
3053 CHAR8
* SystemCommandFormatString
;
3054 CHAR8
* SystemCommand
;
3055 CHAR8
* FfsGuid
= "8c8ce578-8a3d-4f1c-9935-896185c32dd3";
3057 if (IsLargeFile
== TRUE
) {
3058 FfsGuid
= "5473c07a-3dcb-4dca-bd6f-1e9689e7349a";
3061 SystemCommandFormatString
= NULL
;
3062 SystemCommand
= NULL
;
3064 if (OutputFilePath
== NULL
||
3065 InfFilePath
== NULL
) {
3066 return EFI_INVALID_PARAMETER
;
3069 if (InfFilePath
!= NULL
) {
3070 if (FvGuidName
== NULL
) {
3071 SystemCommandFormatString
= "GenFv -i \"%s\" -g %s -o \"%s\"";
3073 SystemCommand
= malloc (
3074 strlen (SystemCommandFormatString
) +
3075 strlen (InfFilePath
) +
3077 strlen (OutputFilePath
) +
3080 if (SystemCommand
== NULL
) {
3081 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3086 "GenFv -i \"%s\" -g %s -o \"%s\"",
3089 OutputFilePath
// -o
3092 if (system (SystemCommand
) != EFI_SUCCESS
) {
3093 free(SystemCommand
);
3097 free(SystemCommand
);
3100 // Have FvGuidName in it.
3102 SystemCommandFormatString
= "GenFv -i \"%s\" -g %s -o \"%s\" --FvNameGuid %s";
3104 SystemCommand
= malloc (
3105 strlen (SystemCommandFormatString
) +
3106 strlen (InfFilePath
) +
3108 strlen (OutputFilePath
) +
3109 strlen (FvGuidName
) +
3112 if (SystemCommand
== NULL
) {
3113 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3118 "GenFv -i \"%s\" -g %s -o \"%s\" --FvNameGuid %s",
3121 OutputFilePath
, // -o
3122 FvGuidName
// FvNameGuid
3125 if (system (SystemCommand
) != EFI_SUCCESS
) {
3126 free(SystemCommand
);
3129 free(SystemCommand
);
3140 Convert a GUID to a string.
3143 @param[in] Guid - Pointer to GUID to print.
3146 @return The string after convert.
3159 printf ("The guid is NULL while convert guid to string! \n");
3163 Buffer
= (CHAR8
*) malloc (36 + 1);
3165 if (Buffer
== NULL
) {
3166 printf ("Error while allocate resource! \n");
3169 memset (Buffer
, '\0', 36 + 1);
3173 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
3192 Encapsulate an FFS section file to an FFS file.
3194 @param[in] Type Type is one FV file type defined in PI spec, which is one type of EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FREEFORM,
3195 EFI_FV_FILETYPE_SECURITY_CORE, EFI_FV_FILETYPE_PEIM, EFI_FV_FILETYPE_PEI_CORE, EFI_FV_FILETYPE_DXE_CORE,
3196 EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION, EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,
3197 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE. This option is required.
3198 @param[in] InputFilePath Section file will be read into this FFS file. This option is required.
3199 @param[in] OutputFilePath The created PI firmware file name. This option is required.
3200 @param[in] FileGuid FileGuid is the unique identifier for this FFS file. This option is required.
3201 @param[in] Fixed Set fixed attribute in FFS file header to indicate that the file may not be moved from its present location.
3202 @param[in] SectionAlign FileAlign specifies FFS file alignment, which only support the following alignment: 8,16,128,512,1K,4K,32K,64K.
3208 LibEncapSectionFileToFFS (
3210 IN CHAR8
* InputFilePath
,
3211 IN CHAR8
* OutputFilePath
,
3212 IN EFI_GUID FileGuid
,
3214 IN CHAR8
* SectionAlign
3217 CHAR8
* SystemCommandFormatString
;
3218 CHAR8
* SystemCommand
;
3222 SystemCommandFormatString
= NULL
;
3223 SystemCommand
= NULL
;
3226 GuidStr
= LibFmmtGuidToStr(&FileGuid
);
3228 if (GuidStr
== NULL
) {
3236 // -o OutPutFilePath
3243 SystemCommandFormatString
= "GenFfs -t %s -i \"%s\" -g %s -x -o \"%s\" -a %s";
3244 SystemCommand
= malloc (
3245 strlen (SystemCommandFormatString
) +
3246 strlen (mFfsFileType
[Type
]) +
3247 strlen (InputFilePath
) +
3249 strlen (OutputFilePath
) +
3253 if (SystemCommand
== NULL
) {
3254 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3260 "GenFfs -t %s -i \"%s\" -g %s -x -o \"%s\" -a %s",
3261 mFfsFileType
[Type
], // -t
3262 InputFilePath
, // -i
3264 OutputFilePath
, // -o
3269 if (system (SystemCommand
) != EFI_SUCCESS
) {
3270 free(SystemCommand
);
3273 free(SystemCommand
);
3275 SystemCommandFormatString
= "GenFfs -t %s -i \"%s\" -g %s -o \"%s\" -a %s";
3276 SystemCommand
= malloc (
3277 strlen (SystemCommandFormatString
) +
3278 strlen (mFfsFileType
[Type
]) +
3279 strlen (InputFilePath
) +
3281 strlen (OutputFilePath
) +
3285 if (SystemCommand
== NULL
) {
3287 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3292 "GenFfs -t %s -i \"%s\" -g %s -o \"%s\" -a %s",
3293 mFfsFileType
[Type
], // -t
3294 InputFilePath
, // -i
3296 OutputFilePath
, // -o
3301 if (system (SystemCommand
) != EFI_SUCCESS
) {
3302 free(SystemCommand
);
3305 free(SystemCommand
);
3325 BOOLEAN UseNewDirFlag
;
3333 UseNewDirFlag
= FALSE
;
3335 if (OldFd
== NULL
||
3337 return EFI_INVALID_PARAMETER
;
3341 NewFdDir
= getcwd (NULL
, _MAX_PATH
);
3343 Count
= strlen(NewFdDir
);
3345 if (strlen(NewFd
) > Count
) {
3348 if (NewFdDir
[Count
-1] == NewFd
[Count
-1]) {
3351 if (strlen(NewFdDir
) + strlen (OS_SEP_STR
) + strlen (NewFd
) > _MAX_PATH
-1) {
3354 strncat (NewFdDir
,OS_SEP_STR
, _MAX_PATH
- strlen (NewFdDir
) -1);
3355 strncat (NewFdDir
,NewFd
, _MAX_PATH
- strlen (NewFdDir
) -1);
3356 UseNewDirFlag
= TRUE
;
3360 } while (Count
!= 1);
3363 if (strlen(NewFdDir
) + strlen (OS_SEP_STR
) + strlen (NewFd
) > _MAX_PATH
-1) {
3366 strncat (NewFdDir
,OS_SEP_STR
, _MAX_PATH
- strlen (NewFdDir
) -1);
3367 strncat (NewFdDir
,NewFd
, _MAX_PATH
- strlen (NewFdDir
) -1);
3368 UseNewDirFlag
= TRUE
;
3371 if (UseNewDirFlag
) {
3372 NewFdFile
= fopen (NewFdDir
, "wb+");
3373 if (NewFdFile
== NULL
) {
3374 NewFdFile
= fopen (NewFd
, "wb+");
3377 NewFdFile
= fopen (NewFd
, "wb+");
3379 // support network path file
3380 if (OldFd
[0] == '\\' && OldFd
[1] == '\\') {
3381 OldFdFile
= fopen (OldFd
, "rb");
3383 UseNewDirFlag
= FALSE
;
3385 OldFdDir
= getcwd (NULL
, _MAX_PATH
);
3387 Count
= strlen(OldFdDir
);
3389 if (strlen(OldFd
) > Count
) {
3392 if (OldFdDir
[Count
-1] == OldFd
[Count
-1]) {
3395 if (strlen(OldFdDir
) + strlen (OS_SEP_STR
) + strlen (OldFd
) > _MAX_PATH
-1) {
3396 if (NewFdFile
!= NULL
) {
3401 strncat (OldFdDir
,OS_SEP_STR
, _MAX_PATH
- strlen (OldFdDir
) -1);
3402 strncat (OldFdDir
,OldFd
, _MAX_PATH
- strlen (OldFdDir
) -1);
3403 UseNewDirFlag
= TRUE
;
3407 } while (Count
!= 1);
3410 if (strlen(OldFdDir
) + strlen (OS_SEP_STR
) + strlen (OldFd
) > _MAX_PATH
-1) {
3411 if (NewFdFile
!= NULL
) {
3416 strncat (OldFdDir
,OS_SEP_STR
, _MAX_PATH
- strlen (OldFdDir
) -1);
3417 strncat (OldFdDir
,OldFd
, _MAX_PATH
- strlen (OldFdDir
) -1);
3418 UseNewDirFlag
= TRUE
;
3421 if (UseNewDirFlag
) {
3422 OldFdFile
= fopen (OldFdDir
, "rb+");
3423 if (OldFdFile
== NULL
) {
3424 OldFdFile
= fopen (OldFd
, "rb+");
3427 OldFdFile
= fopen (OldFd
, "rb+");
3431 if (NewFdFile
== NULL
) {
3432 Error ("FMMT", 0, 0003, "error Open FD file", "cannot Create a new FD file.");
3433 if (OldFdFile
!= NULL
) {
3439 if (OldFdFile
== NULL
) {
3440 Error ("FMMT", 0, 0003, "error Open FD file", "cannot Create a new FD file.");
3441 if (NewFdFile
!= NULL
) {
3448 fseek(OldFdFile
,0,SEEK_SET
);
3449 fseek(OldFdFile
,0,SEEK_END
);
3451 FdLength
= ftell(OldFdFile
);
3453 fseek(OldFdFile
,0,SEEK_SET
);
3454 fseek(NewFdFile
,0,SEEK_SET
);
3456 Buffer
= malloc ((size_t)FdLength
);
3458 if (Buffer
== NULL
) {
3464 if (fread (Buffer
, 1, (size_t) FdLength
, OldFdFile
) != (size_t) FdLength
) {
3465 Error ("FMMT", 0, 0003, "error reading FD file %s", OldFd
);
3472 if (fwrite (Buffer
, 1, (size_t) FdLength
, NewFdFile
) != (size_t) FdLength
) {
3473 Error ("FMMT", 0, 0004, "error writing FD file", "cannot Create a new FD file.");
3488 This function will assemble the filename, directory and extend and return the combined string.
3489 Like FileName = file1, Dir = c:\temp extend = txt, the output string will be:
3496 @retrun A string contain all the input information.
3500 LibFilenameStrExtended (
3510 if (FileName
== NULL
) {
3514 if (Dir
== NULL
|| Extend
== NULL
) {
3518 RetStr
= (CHAR8
*) malloc (strlen (FileName
) +
3521 strlen ("%s%s.%s") +
3523 if (RetStr
== NULL
) {
3524 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3528 memset (RetStr
, '\0', (strlen (FileName
) + strlen (Dir
) + strlen (Extend
) + strlen ("%s%s.%s") + 1));
3530 sprintf (RetStr
, "%s%s.%s", Dir
, FileName
, Extend
);
3536 Delete a directory and files in it.
3538 @param[in] DirName Name of the directory need to be deleted.
3540 @return EFI_INVALID_PARAMETER
3548 CHAR8
* SystemCommand
;
3550 SystemCommand
= NULL
;
3553 if (DirName
== NULL
) {
3554 return EFI_INVALID_PARAMETER
;
3557 if (access (DirName
, 0) == -1){
3562 // Delete a directory and files in it.
3565 SystemCommand
= malloc (
3566 strlen (RMDIR_STR
) +
3570 if (SystemCommand
== NULL
) {
3571 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3581 if (system (SystemCommand
) != EFI_SUCCESS
) {
3582 free(SystemCommand
);
3585 free(SystemCommand
);
3592 CONST EFI_FIRMWARE_VOLUME_EXT_HEADER
*ExtPtr
,
3598 CHAR8 OutputExtFile
[_MAX_PATH
];
3604 TempDir
= getcwd(NULL
, _MAX_PATH
);
3605 if (strlen (TempDir
) + strlen(OS_SEP_STR
) + strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
3606 Error("FMMT", 0, 1001, "The directory is too long.", "");
3609 strncat (TempDir
, OS_SEP_STR
, _MAX_PATH
- strlen (TempDir
) -1);
3610 strncat (TempDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen (TempDir
) -1);
3612 mkdir(TempDir
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
3616 "%c%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%d.ext",
3618 (unsigned)ExtPtr
->FvName
.Data1
,
3619 ExtPtr
->FvName
.Data2
,
3620 ExtPtr
->FvName
.Data3
,
3621 ExtPtr
->FvName
.Data4
[0],
3622 ExtPtr
->FvName
.Data4
[1],
3623 ExtPtr
->FvName
.Data4
[2],
3624 ExtPtr
->FvName
.Data4
[3],
3625 ExtPtr
->FvName
.Data4
[4],
3626 ExtPtr
->FvName
.Data4
[5],
3627 ExtPtr
->FvName
.Data4
[6],
3628 ExtPtr
->FvName
.Data4
[7],
3629 ExtPtr
->ExtHeaderSize
3631 if (strlen (TempDir
) + strlen (Line
) > _MAX_PATH
- 1) {
3632 Error("FMMT", 0, 1001, "The directory is too long.", "");
3635 strncpy (OutputExtFile
, TempDir
, _MAX_PATH
- 1);
3636 OutputExtFile
[_MAX_PATH
- 1] = 0;
3637 strncat (OutputExtFile
, Line
, _MAX_PATH
- strlen (OutputExtFile
) - 1);
3640 ExtFile
= fopen(OutputExtFile
, "wb+");
3641 if (ExtFile
== NULL
) {
3645 if (fwrite(ExtPtr
, 1, ExtPtr
->ExtHeaderSize
, ExtFile
) != ExtPtr
->ExtHeaderSize
) {
3652 strcpy (Line
, "EFI_FV_EXT_HEADER_FILE_NAME = ");
3653 if (strlen (Line
) + strlen (OutputExtFile
) + 1 > sizeof(Line
) / sizeof (CHAR8
) - 1) {
3654 Error("FMMT", 0, 1001, "The directory is too long.", "");
3657 strncat (Line
, OutputExtFile
, sizeof(Line
) / sizeof (CHAR8
) - strlen (Line
) - 1);
3658 strncat (Line
, "\n", sizeof(Line
) / sizeof (CHAR8
) - strlen (Line
) - 1);
3660 if (fwrite(Line
, 1, Len
, InfFile
) != Len
) {
3670 @param[in] FileName Name of the file need to be deleted.
3672 @return EFI_INVALID_PARAMETER
3680 CHAR8
* SystemCommand
;
3683 SystemCommand
= NULL
;
3687 if (FileName
== NULL
) {
3688 return EFI_INVALID_PARAMETER
;
3691 // if the FileName is not in TemDir, we don't need to delete.
3692 TemDir
= getcwd (NULL
, _MAX_PATH
);
3693 if (*(TemDir
+ strlen(TemDir
) - 1) == OS_SEP
) {
3694 *(TemDir
+ strlen(TemDir
) - 1) = '\0';
3696 if (strlen (TemDir
) + strlen (OS_SEP_STR
) + strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
3697 Error (NULL
, 0, 2000, "Path: The current path is too long.", NULL
);
3700 strncat (TemDir
, OS_SEP_STR
, _MAX_PATH
- strlen (TemDir
) - 1);
3701 strncat (TemDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen (TemDir
) - 1);
3702 if (strstr(FileName
, TemDir
) == NULL
) {
3710 SystemCommand
= malloc (
3715 if (SystemCommand
== NULL
) {
3716 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
3726 if (system (SystemCommand
) != EFI_SUCCESS
) {
3727 free(SystemCommand
);
3730 free(SystemCommand
);
3739 Free the whole Fd data structure.
3741 @param[in] Fd The pointer point to the Fd data structure.
3749 FV_INFORMATION
*CurrentFv
;
3750 FV_INFORMATION
*TempFv
;
3751 ENCAP_INFO_DATA
*EncapData1
;
3752 ENCAP_INFO_DATA
*EncapData2
;
3767 CurrentFv
= CurrentFv
->FvNext
;
3769 free (TempFv
->FvHeader
);
3771 if (TempFv
->FvExtHeader
!= NULL
) {
3772 free (TempFv
->FvExtHeader
);
3774 if (TempFv
->FvUiName
) {
3775 free(TempFv
->FvUiName
);
3779 // Free encapsulate data;
3781 EncapData1
= TempFv
->EncapData
;
3783 while (EncapData1
!= NULL
) {
3785 EncapData2
= EncapData1
;
3786 EncapData1
= EncapData1
->NextNode
;
3788 if (EncapData2
->Data
!= NULL
) {
3789 free (EncapData2
->Data
);
3791 if (EncapData2
->FvExtHeader
!= NULL
) {
3792 free(EncapData2
->FvExtHeader
);
3803 } while (CurrentFv
!= NULL
);
3813 Generate the compressed section with specific type.
3814 Type could be EFI_STANDARD_COMPRESSION or EFI_NOT_COMPRESSED
3816 @param[in] InputFileName File name of the raw data.
3817 @param[in] OutPutFileName File name of the sectioned data.
3818 @param[in] CompressionType The compression type.
3820 @return EFI_INVALID_PARAMETER
3822 @return EFI_OUT_OF_RESOURCES
3827 LibGenCompressedSection (
3828 CHAR8
*InputFileName
,
3829 CHAR8
*OutPutFileName
,
3830 UINT8 CompressionType
3833 //FILE *UnCompressFile;
3834 //FILE *CompressedFile;
3835 //VOID *UnCompressedBuffer;
3836 //VOID *CompressedBuffer;
3837 //UINT32 UnCompressedSize;
3838 //UINT32 CompressedSize;
3841 //EFI_STATUS Status;
3843 //UnCompressFile = NULL;
3844 //CompressedFile = NULL;
3845 //UnCompressedBuffer = NULL;
3846 //CompressedBuffer = NULL;
3849 //UnCompressedSize = 0;
3850 //CompressedSize = 0;
3852 if ( InputFileName
== NULL
||
3853 OutPutFileName
== NULL
) {
3854 printf ("Error while generate compressed section!\n");
3855 return EFI_INVALID_PARAMETER
;
3858 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
3861 UnCompressFile = fopen (InputFileName, "rb");
3862 if (UnCompressFile == NULL) {
3863 printf ("Error while open file %s \n", InputFileName);
3867 TemDir = _getcwd (NULL, _MAX_PATH);
3868 sprintf(TemDir, "%s\\%s", TemDir, TEMP_DIR_NAME);
3870 TempName= LibFilenameStrExtended (strrchr(CloneString (tmpnam (NULL)),'\\'), TemDir, "comp");
3872 CompressedFile = fopen (TempName, "wb+");
3873 if (CompressedFile == NULL) {
3874 printf ("Error while open file %s \n", TempName);
3879 // Get the original file size;
3881 fseek(UnCompressFile,0,SEEK_SET);
3882 fseek(UnCompressFile,0,SEEK_END);
3884 UnCompressedSize = ftell(UnCompressFile);
3886 fseek(UnCompressFile,0,SEEK_SET);
3888 UnCompressedBuffer = malloc (UnCompressedSize);
3890 if (UnCompressedBuffer == NULL) {
3891 printf("Error while allocate memory! \n");
3892 return EFI_OUT_OF_RESOURCES;
3895 CompressedBuffer = malloc (UnCompressedSize);
3897 if (CompressedBuffer == NULL) {
3898 printf("Error while allocate memory! \n");
3899 return EFI_OUT_OF_RESOURCES;
3902 if (fread (UnCompressedBuffer, 1, (size_t) UnCompressedSize, UnCompressFile) == (size_t) UnCompressedSize) {
3903 CompressedSize = UnCompressedSize;
3905 Status = EfiCompress ( UnCompressedBuffer,
3910 if (EFI_ERROR(Status)) {
3911 printf("Error while do compress operation! \n");
3915 if (CompressedSize > UnCompressedSize) {
3916 printf("Error while do compress operation! \n");
3920 printf("Error while reading file %s! \n", InputFileName);
3925 // Write the compressed data into output file
3927 if (fwrite (CompressedBuffer, 1, (size_t) CompressedSize, CompressedFile) != (size_t) CompressedSize) {
3928 Error ("FMMT", 0, 0004, "error writing %s file", OutPutFileName);
3929 fclose(UnCompressFile);
3930 fclose (CompressedFile);
3934 fclose(UnCompressFile);
3935 fclose (CompressedFile);
3939 // Call GenSec tool to generate the compressed section.
3941 LibCreateFfsSection(NULL
, InputFileName
, NULL
, EFI_SECTION_COMPRESSION
, OutPutFileName
, NULL
, NULL
, NULL
, 0, 0, "PI_STD");
3943 } else if (CompressionType
== EFI_NOT_COMPRESSED
) {
3945 LibCreateFfsSection(NULL
, InputFileName
, NULL
, EFI_SECTION_COMPRESSION
, OutPutFileName
, NULL
, NULL
, NULL
, 0, 0, "PI_NONE");
3948 printf ("Error while generate compressed section, unknown compression type! \n");
3949 return EFI_INVALID_PARAMETER
;
3958 IN FV_INFORMATION
*FvInFd
,
3960 IN ENCAP_INFO_DATA
*CurrentEncapData
,
3961 IN UINT32 Level_Break
,
3962 OUT FFS_INFORMATION
**OutputFile
3972 ENCAP_INFO_DATA
*LocalEncapData
;
3973 ENCAP_INFO_DATA
*LocalEncapDataTemp
;
3974 ENCAP_INFO_DATA
*LocalEncapDataNext
;
3975 BOOLEAN FfsFoundFlag
;
3978 CHAR8
*ExtractionTool
;
3979 BOOLEAN IsLastLevelFfs
;
3980 BOOLEAN IsLeafFlagIgnore
;
3981 BOOLEAN FirstInFlag
;
3982 BOOLEAN OutputFileNameListFlag
;
3983 CHAR8
*InputFileName
;
3984 CHAR8
*OutputFileName
;
3985 FFS_INFORMATION
*OutputFileNameList
;
3986 FFS_INFORMATION
*ChildFileNameList
;
3987 FFS_INFORMATION
*NewFileNameList
;
3989 UINT16 GuidAttributes
;
3990 UINT16 GuidDataOffset
;
3992 BOOLEAN IsLargeFile
;
3993 UINT32 EncapFvStart
;
3994 UINT32 EncapFvIndex
;
3999 UINT32 InputFileSize
;
4000 UINT32 OutputFileSize
;
4001 UINT32 LargeFileSize
;
4002 UINT8
*Buffer
= NULL
;
4003 UINT8 SectionHeader
[4] = { 0x00, 0x00, 0x00, 0x00 };
4008 UINT8 AlignV
[1] = {0xFF};
4020 FfsFoundFlag
= FALSE
;
4021 LocalEncapDataTemp
= NULL
;
4022 LocalEncapDataNext
= NULL
;
4023 ExtractionTool
= NULL
;
4024 InputFileName
= NULL
;
4025 OutputFileName
= NULL
;
4026 IsLastLevelFfs
= TRUE
;
4027 IsLeafFlagIgnore
= FALSE
;
4030 OutputFileNameListFlag
= TRUE
;
4031 IsLargeFile
= FALSE
;
4033 LargeFileSize
= 0x1000000;
4036 OutputFileNameList
= (FFS_INFORMATION
*)malloc(sizeof(FV_INFORMATION
));
4037 if (OutputFileNameList
== NULL
) {
4038 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4039 return EFI_OUT_OF_RESOURCES
;
4041 OutputFileNameList
->FFSName
= NULL
;
4042 OutputFileNameList
->InFvId
= 0;
4043 OutputFileNameList
->IsFFS
= FALSE
;
4044 OutputFileNameList
->ParentLevel
= 0;
4045 OutputFileNameList
->Next
= NULL
;
4046 OutputFileNameList
->UiNameSize
= 0;
4047 OutputFileNameList
->Depex
= NULL
;
4048 OutputFileNameList
->DepexLen
= 0;
4049 OutputFileNameList
->FfsFoundFlag
= FALSE
;
4051 ChildFileNameList
= (FFS_INFORMATION
*)malloc(sizeof(FV_INFORMATION
));
4052 if (ChildFileNameList
== NULL
) {
4053 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4054 return EFI_OUT_OF_RESOURCES
;
4056 ChildFileNameList
->FFSName
= NULL
;
4057 ChildFileNameList
->InFvId
= 0;
4058 ChildFileNameList
->ParentLevel
= 0;
4059 ChildFileNameList
->Next
= NULL
;
4060 ChildFileNameList
->IsFFS
= FALSE
;
4061 ChildFileNameList
->UiNameSize
= 0;
4062 ChildFileNameList
->Depex
= NULL
;
4063 ChildFileNameList
->DepexLen
= 0;
4064 ChildFileNameList
->FfsFoundFlag
= FALSE
;
4066 // Encapsulate from the lowest FFS file level.
4068 LocalEncapData
= CurrentEncapData
;
4069 if (LocalEncapData
== NULL
) {
4070 LocalEncapData
= FvInFd
->EncapData
;
4072 Level
= LocalEncapData
->Level
;
4073 Type
= LocalEncapData
->Type
;
4075 if (CurrentEncapData
== NULL
) {
4076 LocalEncapData
= FvInFd
->EncapData
;
4077 while (LocalEncapData
!= NULL
) {
4078 if (LocalEncapData
->Type
== FMMT_ENCAP_TREE_FFS
) {
4079 LocalEncapDataTemp
= LocalEncapData
->RightNode
;
4080 while (LocalEncapDataTemp
!= NULL
) {
4081 LocalEncapDataNext
= LocalEncapDataTemp
->NextNode
;
4082 if (LocalEncapDataNext
!= NULL
&& LocalEncapDataNext
->NextNode
!= NULL
) {
4084 LibEncapNewFvFile(FvInFd
, TemDir
, LocalEncapDataTemp
, 1, &ChildFileNameList
);
4085 ChildFileNameList
->ParentLevel
= LocalEncapDataTemp
->Level
-1;
4086 if (FvInFd
->ChildFvFFS
== NULL
) {
4087 FvInFd
->ChildFvFFS
= ChildFileNameList
;
4089 NewFileNameList
= FvInFd
->ChildFvFFS
;
4090 while (NewFileNameList
->Next
!= NULL
) {
4091 NewFileNameList
= NewFileNameList
->Next
;
4093 NewFileNameList
->Next
= ChildFileNameList
;
4096 LocalEncapDataTemp
= LocalEncapDataTemp
->RightNode
;
4100 if (LocalEncapData
->Level
> Level
) {
4101 if (LocalEncapData
->Type
== FMMT_ENCAP_TREE_FFS
) {
4102 ParentLevel
= Level
;
4105 Level
= LocalEncapData
->Level
;
4106 Type
= LocalEncapData
->Type
;
4108 LocalEncapData
= LocalEncapData
->NextNode
;
4111 LocalEncapData
= CurrentEncapData
;
4112 while (LocalEncapData
!= NULL
) {
4113 if (LocalEncapData
->Level
> Level
) {
4114 if (LocalEncapData
->Type
== FMMT_ENCAP_TREE_FFS
) {
4115 ParentLevel
= Level
;
4118 Level
= LocalEncapData
->Level
;
4119 Type
= LocalEncapData
->Type
;
4121 LocalEncapData
= LocalEncapData
->NextNode
;
4126 switch (ParentType
) {
4127 case FMMT_ENCAP_TREE_FV
:
4128 OutputFileNameListFlag
= TRUE
;
4130 for(OuterIndex
=0;OutputFileNameListFlag
;OuterIndex
++){
4132 // Generate FV.inf attributes.
4134 InfFileName
= LibFilenameStrExtended (strrchr(GenTempFile (),OS_SEP
), TemDir
, "inf");
4137 InfFile
= fopen (InfFileName
, "wt+");
4139 if (InfFile
== NULL
) {
4140 Error ("FMMT", 0, 0004, "Could not open inf file %s to store FV information! \n", "");
4141 free (OutputFileNameList
);
4142 free (ChildFileNameList
);
4146 if (CurrentEncapData
== NULL
) {
4147 LocalEncapData
= FvInFd
->EncapData
;
4149 LocalEncapData
= CurrentEncapData
;
4152 while (LocalEncapData
->NextNode
!= NULL
) {
4153 if (LocalEncapData
->Level
== ParentLevel
) {
4156 LocalEncapData
= LocalEncapData
->NextNode
;
4159 if (((EFI_FIRMWARE_VOLUME_HEADER
*)(LocalEncapData
->Data
))->ExtHeaderOffset
!= 0) {
4161 // FV GUID Name memory allocation
4163 FvGuidName
= (CHAR8
*) malloc (255);
4165 if (FvGuidName
== NULL
) {
4166 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4168 free (OutputFileNameList
);
4169 free (ChildFileNameList
);
4173 memset(FvGuidName
, '\0', 255);
4177 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
4178 LocalEncapData
->FvExtHeader
->FvName
.Data1
,
4179 LocalEncapData
->FvExtHeader
->FvName
.Data2
,
4180 LocalEncapData
->FvExtHeader
->FvName
.Data3
,
4181 LocalEncapData
->FvExtHeader
->FvName
.Data4
[0],
4182 LocalEncapData
->FvExtHeader
->FvName
.Data4
[1],
4183 LocalEncapData
->FvExtHeader
->FvName
.Data4
[2],
4184 LocalEncapData
->FvExtHeader
->FvName
.Data4
[3],
4185 LocalEncapData
->FvExtHeader
->FvName
.Data4
[4],
4186 LocalEncapData
->FvExtHeader
->FvName
.Data4
[5],
4187 LocalEncapData
->FvExtHeader
->FvName
.Data4
[6],
4188 LocalEncapData
->FvExtHeader
->FvName
.Data4
[7]
4196 if (ParentLevel
== 1) {
4197 Status
= LibFvHeaderOptionToStr((EFI_FIRMWARE_VOLUME_HEADER
*)LocalEncapData
->Data
, InfFile
, TRUE
);
4199 Status
= LibFvHeaderOptionToStr((EFI_FIRMWARE_VOLUME_HEADER
*)LocalEncapData
->Data
, InfFile
, FALSE
);
4203 if (EFI_ERROR (Status
)) {
4204 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "generate FV INF file [Options] section failed.");
4206 free (OutputFileNameList
);
4207 free (ChildFileNameList
);
4211 Status
= LibFvHeaderAttributeToStr(((EFI_FIRMWARE_VOLUME_HEADER
*)LocalEncapData
->Data
)->Attributes
, InfFile
);
4213 if (EFI_ERROR (Status
)) {
4214 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV header attribute failed");
4216 free (OutputFileNameList
);
4217 free (ChildFileNameList
);
4220 if (LocalEncapData
->FvExtHeader
!= NULL
) {
4221 Status
= LibGenExtFile(LocalEncapData
->FvExtHeader
, InfFile
);
4222 if (EFI_ERROR(Status
)) {
4223 Error("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV EXT header failed");
4225 free (OutputFileNameList
);
4226 free (ChildFileNameList
);
4232 if (CurrentEncapData
!= NULL
) {
4233 for (Index
= 0; Index
<= FvInFd
->FfsNumbers
; Index
++) {
4234 if ((memcmp(&FvInFd
->FfsAttuibutes
[Index
].GuidName
, &(CurrentEncapData
->FvExtHeader
->FvName
), sizeof(EFI_GUID
)) == 0)) {
4241 // Found FFSs from Fv structure.
4243 FfsFoundFlag
= FALSE
;
4245 for (Index
=0; Index
<= FvInFd
->FfsNumbers
; Index
++) {
4246 if (OutputFileNameList
!= NULL
&& OutputFileNameList
->FFSName
!= NULL
&& OutputFileNameList
->IsFFS
== FALSE
){
4249 if (OutputFileNameList
!= NULL
&& OutputFileNameList
->FFSName
!= NULL
&& OutputFileNameList
->IsFFS
== TRUE
){
4250 if (Index
== EncapFvIndex
) {
4252 Status
= LibAddFfsFileToFvInf (OutputFileNameList
->FFSName
, InfFile
, TRUE
);
4253 FirstInFlag
= FALSE
;
4255 Status
= LibAddFfsFileToFvInf (OutputFileNameList
->FFSName
, InfFile
, FALSE
);
4257 if (EFI_ERROR (Status
)) {
4258 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4260 free (OutputFileNameList
);
4261 free (ChildFileNameList
);
4267 NewFileNameList
= FvInFd
->ChildFvFFS
;
4268 while (NewFileNameList
!= NULL
&& NewFileNameList
-> FFSName
!= NULL
) {
4269 if (NewFileNameList
-> ParentLevel
== ParentLevel
&& Index
== NewFileNameList
->InFvId
&& NewFileNameList
->FfsFoundFlag
==TRUE
) {
4271 Status
= LibAddFfsFileToFvInf (NewFileNameList
->FFSName
, InfFile
, TRUE
);
4272 FirstInFlag
= FALSE
;
4274 Status
= LibAddFfsFileToFvInf (NewFileNameList
->FFSName
, InfFile
, FALSE
);
4276 if (EFI_ERROR (Status
)) {
4277 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4279 free (OutputFileNameList
);
4280 free (ChildFileNameList
);
4284 NewFileNameList
= NewFileNameList
->Next
;
4287 if (FvInFd
->FfsAttuibutes
[Index
].IsHandle
==TRUE
) {
4290 if (SubFvId
> 0 && Index
< SubFvId
) {
4295 // For the last level FFS, the level below FFSs we should not care the IsLeaf Flag.
4297 if (IsLastLevelFfs
) {
4298 IsLeafFlagIgnore
= TRUE
;
4300 IsLeafFlagIgnore
= FvInFd
->FfsAttuibutes
[Index
].IsLeaf
;
4303 if (FvInFd
->FfsAttuibutes
[Index
].Level
>= ParentLevel
+ 1 && IsLeafFlagIgnore
) {
4305 if (FvInFd
->FfsAttuibutes
[Index
].Level
< 0xFF) {
4306 FfsFoundFlag
= TRUE
;
4307 Status
= LibAddFfsFileToFvInf (FvInFd
->FfsAttuibutes
[Index
].FfsName
, InfFile
, TRUE
);
4308 FirstInFlag
= FALSE
;
4309 FvInFd
->FfsAttuibutes
[Index
].IsHandle
=TRUE
;
4310 EncapFvStart
= Index
;
4313 if (EFI_ERROR (Status
)) {
4314 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4316 free (OutputFileNameList
);
4317 free (ChildFileNameList
);
4321 // Root FV need to include all FFS files.
4325 if (FvInFd
->FfsAttuibutes
[Index
].Level
< 0xFF) {
4326 FfsFoundFlag
= TRUE
;
4327 Status
= LibAddFfsFileToFvInf (FvInFd
->FfsAttuibutes
[Index
].FfsName
, InfFile
, FALSE
);
4328 FvInFd
->FfsAttuibutes
[Index
].IsHandle
=TRUE
;
4331 if (EFI_ERROR (Status
)) {
4332 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4334 free (OutputFileNameList
);
4335 free (ChildFileNameList
);
4339 // Root FV need to include all FFS files.
4345 //avoid a FV contain too many ffs files
4346 if ((!IsRootFv
) && (FvInFd
->FfsAttuibutes
[Index
].FvLevel
<= FvInFd
->MulFvLevel
) && (FvInFd
->FfsAttuibutes
[Index
+1].FvLevel
<= FvInFd
->MulFvLevel
) &&
4347 (FvInFd
->FfsAttuibutes
[Index
].FvLevel
!= FvInFd
->FfsAttuibutes
[Index
+1].FvLevel
) && (ParentLevel
!= 1) && (FvInFd
->FfsAttuibutes
[Index
].Level
!= FvInFd
->FfsAttuibutes
[Index
+1].Level
) &&
4348 FvInFd
->FfsAttuibutes
[Index
].Level
!= 0xFF && FvInFd
->FfsAttuibutes
[Index
+1].Level
!= 0xFF && FvInFd
->FfsAttuibutes
[Index
+1].Level
!= 0x0){
4349 FvInFd
->FfsAttuibutes
[Index
].Level
= 0;
4352 if (FvInFd
->FfsAttuibutes
[Index
].Level
!= 0xFF){
4353 FvInFd
->FfsAttuibutes
[Index
].Level
= 0;
4359 // The Fv may has multiple level (> 2), when it is in the FvLevel == 2, we set the IsLastLevelFfs Flag
4360 if (Index
<=FvInFd
->FfsNumbers
&& FvInFd
->FfsAttuibutes
[Index
].FvLevel
<= FvInFd
->MulFvLevel
) {
4361 if (FvInFd
->FfsAttuibutes
[Index
].FvLevel
== 2) {
4362 IsLastLevelFfs
= FALSE
;
4366 OutputFileNameListFlag
= FALSE
;
4367 if (OuterIndex
> 0){
4377 EncapFvIndex
= EncapFvStart
;
4379 OutputFileName
= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP
), TemDir
, "FV");
4381 Status
= LibEncapsulateFfsToFv (InfFileName
, NULL
, OutputFileName
, FvGuidName
, IsLargeFile
);
4383 if (EFI_ERROR (Status
)) {
4384 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV failed!");
4385 free (OutputFileNameList
);
4386 free (ChildFileNameList
);
4390 OutputFileNameList
->FFSName
= (char *)malloc(strlen(OutputFileName
)+1);
4391 if (OutputFileNameList
->FFSName
== NULL
) {
4392 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4393 return EFI_OUT_OF_RESOURCES
;
4395 memcpy((char *)OutputFileNameList
->FFSName
, (char *)OutputFileName
, strlen(OutputFileName
)+1);
4396 if (CurrentEncapData
!= NULL
) {
4397 OutputFileNameList
->InFvId
= EncapFvIndex
;
4398 if (EncapFvIndex
> 0) {
4399 memcpy(OutputFileNameList
->UiName
,FvInFd
->FfsAttuibutes
[EncapFvIndex
- 1].UiName
, FvInFd
->FfsAttuibutes
[EncapFvIndex
- 1].UiNameSize
);
4400 OutputFileNameList
->UiNameSize
= FvInFd
->FfsAttuibutes
[EncapFvIndex
- 1].UiNameSize
;
4401 OutputFileNameList
->Depex
= FvInFd
->FfsAttuibutes
[EncapFvIndex
- 1].Depex
;
4402 OutputFileNameList
->DepexLen
= FvInFd
->FfsAttuibutes
[EncapFvIndex
- 1].DepexLen
;
4403 OutputFileNameList
->FfsFoundFlag
= FfsFoundFlag
;
4408 case FMMT_ENCAP_TREE_FFS
:
4410 while(OutputFileNameList
!= NULL
&& OutputFileNameList
->FFSName
!= NULL
){
4411 InputFileName
= OutputFileNameList
->FFSName
;
4412 OutputFileName
= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP
), TemDir
, "ffs");
4413 LocalEncapData
= CurrentEncapData
;
4414 if (LocalEncapData
== NULL
) {
4415 LocalEncapData
= FvInFd
->EncapData
;
4417 while (LocalEncapData
->NextNode
!= NULL
) {
4418 if (LocalEncapData
->Level
== ParentLevel
) {
4419 for(;LocalEncapData
->NextNode
!= NULL
;) {
4420 if(LocalEncapData
->FvExtHeader
!= NULL
) {
4423 LocalEncapData
= LocalEncapData
->NextNode
;
4427 LocalEncapData
= LocalEncapData
->NextNode
;
4430 if (LocalEncapData
->FvExtHeader
== NULL
) {
4431 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FFS file failed!");
4432 free (OutputFileNameList
);
4433 free (ChildFileNameList
);
4437 if (OutputFileNameList
->UiNameSize
> 0) {
4438 TmpFileName
= LibFilenameStrExtended(strrchr(GenTempFile (), OS_SEP
), TemDir
, "tmp");
4439 TmpFile
= fopen(TmpFileName
, "wb+");
4440 if (TmpFile
== NULL
) {
4441 Error("FMMT", 0, 0004, "Could not open tmp file %s to store UI section information! \n", "");
4442 free (OutputFileNameList
);
4443 free (ChildFileNameList
);
4446 header
= (OutputFileNameList
->UiNameSize
+4) | (EFI_SECTION_USER_INTERFACE
<< 24);
4449 SectionHeader
[Index
] = header
% 0x100;
4453 InputFile
= fopen(InputFileName
, "rb+");
4454 if (InputFile
== NULL
) {
4455 Error("FMMT", 0, 0004, "Could not open input file %s! \n", "");
4457 free (OutputFileNameList
);
4458 free (ChildFileNameList
);
4461 fseek(InputFile
, 0, SEEK_SET
);
4462 fseek(InputFile
, 0, SEEK_END
);
4463 InputFileSize
= ftell(InputFile
);
4464 fseek(InputFile
, 0, SEEK_SET
);
4466 Buffer
= malloc(InputFileSize
+OutputFileNameList
->UiNameSize
+4);
4467 memcpy(Buffer
, (CHAR16
*)SectionHeader
, 4);
4468 memcpy(Buffer
+ 4, (CHAR16
*)(OutputFileNameList
->UiName
), OutputFileNameList
->UiNameSize
);
4469 if (fread(Buffer
+4+OutputFileNameList
->UiNameSize
, 1, InputFileSize
, InputFile
) != InputFileSize
) {
4470 Error("FMMT", 0, 0004, "Could not open sec file %s to add UI section information! \n", "");
4474 free (OutputFileNameList
);
4475 free (ChildFileNameList
);
4478 fwrite(Buffer
, 1, InputFileSize
+ OutputFileNameList
->UiNameSize
+ 4, TmpFile
);
4482 InputFileName
= TmpFileName
;
4484 if (OutputFileNameList
->DepexLen
> 0) {
4485 TmpFileName
= LibFilenameStrExtended(strrchr(GenTempFile (), OS_SEP
), TemDir
, "tmp");
4486 TmpFile
= fopen(TmpFileName
, "wb+");
4487 if (TmpFile
== NULL
) {
4488 Error("FMMT", 0, 0004, "Could not open tmp file %s to store Depex section information! \n", "");
4489 free (OutputFileNameList
);
4490 free (ChildFileNameList
);
4493 InputFile
= fopen(InputFileName
, "rb+");
4494 if (InputFile
== NULL
) {
4495 Error("FMMT", 0, 0004, "Could not open input file %s! \n", "");
4497 free (OutputFileNameList
);
4498 free (ChildFileNameList
);
4501 fseek(InputFile
, 0, SEEK_SET
);
4502 fseek(InputFile
, 0, SEEK_END
);
4503 InputFileSize
= ftell(InputFile
);
4504 fseek(InputFile
, 0, SEEK_SET
);
4505 // make sure the section is 4 byte align
4506 if (OutputFileNameList
->DepexLen
% 4 != 0) {
4507 AlignN
= 4 - OutputFileNameList
->DepexLen
% 4;
4509 Buffer
= malloc(InputFileSize
+ OutputFileNameList
->DepexLen
+ AlignN
);
4510 memcpy(Buffer
, OutputFileNameList
->Depex
, OutputFileNameList
->DepexLen
);
4512 for (Index
= 0; Index
< AlignN
; Index
++) {
4513 memcpy(Buffer
+ OutputFileNameList
->DepexLen
+ Index
, AlignV
, 1);
4516 if (fread(Buffer
+ OutputFileNameList
->DepexLen
+ AlignN
, 1, InputFileSize
, InputFile
) != InputFileSize
) {
4517 Error("FMMT", 0, 0004, "Could not open sec file %s to add Depex section information! \n", "");
4521 free (OutputFileNameList
);
4522 free (ChildFileNameList
);
4525 fwrite(Buffer
, 1, InputFileSize
+ OutputFileNameList
->DepexLen
+ AlignN
, TmpFile
);
4529 InputFileName
= TmpFileName
;
4531 for (Id
= FvInFd
->FfsNumbers
; Id
<= FvInFd
->FfsNumbers
; Id
--) {
4532 if ((memcmp(&FvInFd
->FfsAttuibutes
[Id
].GuidName
, &(LocalEncapData
->FvExtHeader
->FvName
), sizeof(EFI_GUID
)) == 0)){
4533 if (access(FvInFd
->FfsAttuibutes
[Id
].FfsName
, 0) != -1) {
4534 Status
= LibFmmtDeleteFile(FvInFd
->FfsAttuibutes
[Id
].FfsName
);
4535 if (EFI_ERROR(Status
)) {
4536 Error("FMMT", 0, 0004, "error while encapsulate FD Image", "Delete the specified file failed!");
4537 free (OutputFileNameList
);
4538 free (ChildFileNameList
);
4541 memset(FvInFd
->FfsAttuibutes
[Id
].FfsName
, '\0', _MAX_PATH
);
4542 FvInFd
->FfsAttuibutes
[Id
].Level
= 0xFF;
4547 if (LocalEncapData
->NextNode
!= NULL
) {
4548 LocalEncapDataTemp
= LocalEncapData
->NextNode
;
4549 if ((LocalEncapDataTemp
->Type
== FMMT_ENCAP_TREE_GUIDED_SECTION
) || (LocalEncapDataTemp
->Type
== FMMT_ENCAP_TREE_COMPRESS_SECTION
)) {
4550 Status
= LibEncapSectionFileToFFS(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
, InputFileName
, OutputFileName
, LocalEncapData
->FvExtHeader
->FvName
, FALSE
, "1");
4553 Status
= LibEncapSectionFileToFFS(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
, InputFileName
, OutputFileName
, LocalEncapData
->FvExtHeader
->FvName
, FALSE
, FvInFd
->AlignmentStr
);
4557 Status
= LibEncapSectionFileToFFS(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
, InputFileName
, OutputFileName
, LocalEncapData
->FvExtHeader
->FvName
, FALSE
, FvInFd
->AlignmentStr
);
4559 if (EFI_ERROR (Status
)) {
4560 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FFS file failed!");
4561 free (OutputFileNameList
);
4562 free (ChildFileNameList
);
4565 free(LocalEncapData
->FvExtHeader
);
4566 LocalEncapData
->FvExtHeader
= NULL
;
4567 OutputFileNameList
->FFSName
= (char *)malloc(strlen(OutputFileName
)+1);
4568 if (OutputFileNameList
->FFSName
== NULL
) {
4569 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4570 return EFI_OUT_OF_RESOURCES
;
4572 memcpy((char *)OutputFileNameList
->FFSName
, (char *)OutputFileName
, strlen(OutputFileName
)+1);
4573 OutputFileNameList
->IsFFS
= TRUE
;
4574 if (OutputFileNameList
->Next
== NULL
){
4577 OutputFileNameList
= OutputFileNameList
->Next
;
4580 case FMMT_ENCAP_TREE_GUIDED_SECTION
:
4581 while(OutputFileNameList
!= NULL
&& OutputFileNameList
->FFSName
!= NULL
){
4583 // Create the guided section original data, do compress operation.
4585 InputFileName
= OutputFileNameList
->FFSName
;
4586 OutputFileName
= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP
), TemDir
, "compressed");
4589 // Use the guided section header guid to find out compress application name.
4591 LocalEncapData
= CurrentEncapData
;
4592 if (LocalEncapData
== NULL
) {
4593 LocalEncapData
= FvInFd
->EncapData
;
4595 while (LocalEncapData
->NextNode
!= NULL
) {
4596 if (LocalEncapData
->Level
== ParentLevel
) {
4599 LocalEncapData
= LocalEncapData
->NextNode
;
4603 LookupGuidedSectionToolPath (
4604 mParsedGuidedSectionTools
,
4605 (EFI_GUID
*)LocalEncapData
->Data
4607 GuidDataOffset
= *(UINT16
*) ((UINT8
*) LocalEncapData
->Data
+ sizeof (EFI_GUID
));
4608 GuidAttributes
= *(UINT16
*) ((UINT8
*) LocalEncapData
->Data
+ sizeof (EFI_GUID
) + sizeof (UINT16
));
4610 Status
= LibCreateGuidedSectionOriginalData (InputFileName
, ExtractionTool
, OutputFileName
);
4612 if (EFI_ERROR (Status
) || GuidDataOffset
< sizeof (EFI_GUID_DEFINED_SECTION
)) {
4613 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Compress guided data failed!");
4614 free (OutputFileNameList
);
4615 free (ChildFileNameList
);
4619 GuidDataOffset
= GuidDataOffset
- sizeof (EFI_GUID_DEFINED_SECTION
);
4620 InputFileName
= OutputFileName
;
4621 OutputFileName
= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP
), TemDir
, "guided");
4623 Status
= LibCreateFfsSection(NULL
, InputFileName
, NULL
, EFI_SECTION_GUID_DEFINED
, OutputFileName
, NULL
, NULL
, LibFmmtGuidToStr((EFI_GUID
*)LocalEncapData
->Data
), GuidDataOffset
, GuidAttributes
, NULL
);
4624 OutFile
= fopen(OutputFileName
, "rb+");
4625 if (OutFile
== NULL
) {
4626 Error("FMMT", 0, 0004, "Could not open the file %s! \n", "");
4627 free (OutputFileNameList
);
4628 free (ChildFileNameList
);
4631 fseek(OutFile
, 0, SEEK_SET
);
4632 fseek(OutFile
, 0, SEEK_END
);
4633 OutputFileSize
= ftell(OutFile
);
4635 if (OutputFileSize
> LargeFileSize
) {
4638 OutputFileNameList
->FFSName
= (char *)malloc(strlen(OutputFileName
)+1);
4639 if (OutputFileNameList
->FFSName
== NULL
) {
4640 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4641 return EFI_OUT_OF_RESOURCES
;
4643 memcpy((char *)OutputFileNameList
->FFSName
, (char *)OutputFileName
, strlen(OutputFileName
)+1);
4645 if (EFI_ERROR (Status
)) {
4646 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate guided section failed!");
4647 free (OutputFileNameList
);
4648 free (ChildFileNameList
);
4651 if (OutputFileNameList
->Next
== NULL
){
4654 OutputFileNameList
= OutputFileNameList
->Next
;
4657 case FMMT_ENCAP_TREE_COMPRESS_SECTION
:
4658 while(OutputFileNameList
!= NULL
&& OutputFileNameList
->FFSName
!= NULL
){
4659 InputFileName
= OutputFileNameList
->FFSName
;
4661 OutputFileName
= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP
), TemDir
, "comsec");
4662 LocalEncapData
= CurrentEncapData
;
4663 if (LocalEncapData
== NULL
) {
4664 LocalEncapData
= FvInFd
->EncapData
;
4666 while (LocalEncapData
->NextNode
!= NULL
) {
4667 if (LocalEncapData
->Level
== ParentLevel
) {
4670 LocalEncapData
= LocalEncapData
->NextNode
;
4673 Status
= LibGenCompressedSection (InputFileName
, OutputFileName
, *(UINT8
*)(LocalEncapData
->Data
));
4674 OutputFileNameList
->FFSName
= (char *)malloc(strlen(OutputFileName
)+1);
4675 if (OutputFileNameList
->FFSName
== NULL
) {
4676 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4677 return EFI_OUT_OF_RESOURCES
;
4679 memcpy((char *)OutputFileNameList
->FFSName
, (char *)OutputFileName
, strlen(OutputFileName
)+1);
4681 if (EFI_ERROR (Status
)) {
4682 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate compressed section failed!");
4683 free (OutputFileNameList
);
4684 free (ChildFileNameList
);
4687 if (OutputFileNameList
->Next
== NULL
){
4690 OutputFileNameList
= OutputFileNameList
->Next
;
4693 case FMMT_ENCAP_TREE_FV_SECTION
:
4694 while(OutputFileNameList
!= NULL
&& OutputFileNameList
->FFSName
!= NULL
){
4695 InputFileName
= OutputFileNameList
->FFSName
;
4696 OutputFileName
= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP
), TemDir
, "sec");
4698 Status
= LibCreateFfsSection(NULL
, InputFileName
, NULL
, EFI_SECTION_FIRMWARE_VOLUME_IMAGE
, OutputFileName
, NULL
, NULL
, NULL
, 0, 0, NULL
);
4700 if (EFI_ERROR (Status
)) {
4701 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV section failed!");
4702 free (OutputFileNameList
);
4703 free (ChildFileNameList
);
4707 InputFileName
= OutputFileName
;
4708 OutputFileName
= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP
), TemDir
, "sec");
4711 // Make it alignment.
4713 Status
= LibCreateFfsSection(FvInFd
, InputFileName
, NULL
, 0, OutputFileName
, NULL
, NULL
, NULL
, 0, 0, NULL
);
4714 OutFile
= fopen(OutputFileName
, "rb+");
4715 if (OutFile
== NULL
) {
4716 Error("FMMT", 0, 0004, "Could not open the file %s! \n", "");
4717 free (OutputFileNameList
);
4718 free (ChildFileNameList
);
4721 fseek(OutFile
, 0, SEEK_SET
);
4722 fseek(OutFile
, 0, SEEK_END
);
4723 OutputFileSize
= ftell(OutFile
);
4725 if (OutputFileSize
> LargeFileSize
) {
4729 OutputFileNameList
->FFSName
= (char *)malloc(strlen(OutputFileName
)+1);
4730 if (OutputFileNameList
->FFSName
== NULL
) {
4731 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4732 return EFI_OUT_OF_RESOURCES
;
4734 memcpy((char *)OutputFileNameList
->FFSName
, (char *)OutputFileName
, strlen(OutputFileName
)+1);
4736 if (EFI_ERROR (Status
)) {
4737 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV section failed!");
4738 free (OutputFileNameList
);
4739 free (ChildFileNameList
);
4742 if (OutputFileNameList
->Next
== NULL
){
4745 OutputFileNameList
= OutputFileNameList
->Next
;
4749 for (Id
= FvInFd
->FfsNumbers
; Id
<= FvInFd
->FfsNumbers
; Id
--) {
4750 if ((memcmp(&FvInFd
->FfsAttuibutes
[Id
].GuidName
, &(CurrentEncapData
->FvExtHeader
->FvName
), sizeof(EFI_GUID
)) == 0)){
4751 FvInFd
->FfsAttuibutes
[Id
].IsHandle
= TRUE
;
4752 memcpy(OutputFileNameList
->UiName
, FvInFd
->FfsAttuibutes
[Id
].UiName
, FvInFd
->FfsAttuibutes
[Id
].UiNameSize
);
4753 OutputFileNameList
->UiNameSize
= FvInFd
->FfsAttuibutes
[Id
].UiNameSize
;
4754 OutputFileNameList
->FFSName
= FvInFd
->FfsAttuibutes
[Id
].FfsName
;
4755 OutputFileNameList
->Depex
= FvInFd
->FfsAttuibutes
[Id
].Depex
;
4756 OutputFileNameList
->DepexLen
= FvInFd
->FfsAttuibutes
[Id
].DepexLen
;
4757 OutputFileNameList
->FfsFoundFlag
= TRUE
;
4758 OutputFileNameList
->IsFFS
= TRUE
;
4759 OutputFileNameList
->InFvId
= Id
;
4760 *OutputFile
= OutputFileNameList
;
4766 if (CurrentEncapData
== NULL
) {
4767 LocalEncapData
= FvInFd
->EncapData
;
4769 if (OutputFileNameList
!= NULL
&& OutputFileNameList
->FFSName
!= NULL
&& OutputFileNameList
->IsFFS
== TRUE
) {
4770 *OutputFile
= OutputFileNameList
;
4773 LocalEncapData
= CurrentEncapData
;
4777 while (LocalEncapData
->NextNode
!= NULL
) {
4778 if (LocalEncapData
->Level
== ParentLevel
) {
4779 LocalEncapDataTemp
= LocalEncapData
->NextNode
;
4780 if ((LocalEncapDataTemp
!= NULL
) && (LocalEncapDataTemp
->Level
== ParentLevel
)) {
4781 ParentType
= LocalEncapDataTemp
->Type
;
4784 ParentType
= LocalEncapData
->Type
;
4787 LocalEncapData
= LocalEncapData
->NextNode
;
4789 } while (ParentLevel
!= Level_Break
);
4791 *OutputFile
= OutputFileNameList
;
4797 LibFindFvInEncapData (
4798 ENCAP_INFO_DATA
*EncapData
,
4802 ENCAP_INFO_DATA
*LocalEncapData
;
4803 LocalEncapData
= EncapData
;
4804 if (LocalEncapData
== NULL
) {
4805 Error("FMMT", 0, 0005, "error while find FV in Encapulate buffer", "Invalid parameters.");
4806 return EFI_INVALID_PARAMETER
;
4808 while (LocalEncapData
!= NULL
) {
4809 if (LocalEncapData
->RightNode
!= NULL
) {
4810 LibFindFvInEncapData (LocalEncapData
->RightNode
, Index
);
4812 if (LocalEncapData
->Type
== FMMT_ENCAP_TREE_FV
) {
4815 LocalEncapData
= LocalEncapData
->NextNode
;
4821 LibLocateFvViaFvId (
4822 IN FIRMWARE_DEVICE
*FdData
,
4824 IN OUT FV_INFORMATION
**FvInFd
4829 BOOLEAN FvFoundFlag
;
4831 ENCAP_INFO_DATA
*LocalEncapData
;
4832 ENCAP_INFO_DATA
*LocalEncapDataRight
;
4833 ENCAP_INFO_DATA
*LocalEncapDataNext
;
4836 FvFoundFlag
= FALSE
;
4838 LocalEncapDataNext
= NULL
;
4839 LocalEncapDataRight
= NULL
;
4841 if (FdData
== NULL
|| FvId
== NULL
|| FvInFd
== NULL
|| FdData
->Fv
== NULL
) {
4842 Error ("FMMT", 0, 0005, "error while find FV in FD", "Invalid parameters.");
4843 return EFI_INVALID_PARAMETER
;
4846 *FvInFd
= FdData
->Fv
;
4848 if (strlen(FvId
) < 3) {
4849 Error ("FMMT", 0, 0005, "error while find FV in FD", "Invalid FvId, please double check the FvId. You can use view operate to get the FvId information!");
4853 FvGuidName
= (CHAR8
*) malloc (255);
4854 if (FvGuidName
== NULL
) {
4855 Error ("FMMT", 0, 0005, "Resource: Memory can't be allocated", NULL
);
4858 memset(FvGuidName
, '\0', 255);
4859 LocalEncapData
= NULL
;
4861 if (strlen(FvId
) == 36) {
4862 while (FvInFd
!= NULL
) {
4863 if (((*FvInFd
)->FvExtHeader
) != NULL
) {
4866 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
4867 (*FvInFd
)->FvExtHeader
->FvName
.Data1
,
4868 (*FvInFd
)->FvExtHeader
->FvName
.Data2
,
4869 (*FvInFd
)->FvExtHeader
->FvName
.Data3
,
4870 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[0],
4871 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[1],
4872 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[2],
4873 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[3],
4874 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[4],
4875 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[5],
4876 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[6],
4877 (*FvInFd
)->FvExtHeader
->FvName
.Data4
[7]);
4878 if (strcmp(FvGuidName
, FvId
) == 0) {
4879 FvId
= (*FvInFd
)->FvName
;
4883 if ((*FvInFd
)->MulFvLevel
> 1) {
4884 LocalEncapData
= (*FvInFd
) -> EncapData
;
4885 LocalEncapData
= LocalEncapData
->NextNode
;
4886 while (LocalEncapData
!= NULL
) {
4887 if (LocalEncapData
->RightNode
!= NULL
) {
4888 LocalEncapDataRight
= LocalEncapData
->RightNode
;
4889 while (LocalEncapDataRight
!=NULL
) {
4890 if (LocalEncapDataRight
->NextNode
!= NULL
) {
4891 LocalEncapDataNext
= LocalEncapDataRight
->NextNode
;
4892 while (LocalEncapDataNext
!= NULL
) {
4893 if (LocalEncapDataNext
->Type
== FMMT_ENCAP_TREE_FV
) {
4894 if (LocalEncapDataNext
->FvExtHeader
!= NULL
) {
4897 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
4898 LocalEncapDataNext
->FvExtHeader
->FvName
.Data1
,
4899 LocalEncapDataNext
->FvExtHeader
->FvName
.Data2
,
4900 LocalEncapDataNext
->FvExtHeader
->FvName
.Data3
,
4901 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[0],
4902 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[1],
4903 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[2],
4904 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[3],
4905 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[4],
4906 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[5],
4907 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[6],
4908 LocalEncapDataNext
->FvExtHeader
->FvName
.Data4
[7]);
4909 if (strcmp(FvGuidName
, FvId
) == 0)
4911 sprintf(FvId
, "%s%d", "FV", LocalEncapDataNext
->FvId
- 1);
4917 LocalEncapDataNext
= LocalEncapDataNext
->NextNode
;
4920 LocalEncapDataRight
= LocalEncapDataRight
->RightNode
;
4923 if (LocalEncapData
->Type
== FMMT_ENCAP_TREE_FV
) {
4924 if (LocalEncapData
->FvExtHeader
!= NULL
) {
4927 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
4928 LocalEncapData
->FvExtHeader
->FvName
.Data1
,
4929 LocalEncapData
->FvExtHeader
->FvName
.Data2
,
4930 LocalEncapData
->FvExtHeader
->FvName
.Data3
,
4931 LocalEncapData
->FvExtHeader
->FvName
.Data4
[0],
4932 LocalEncapData
->FvExtHeader
->FvName
.Data4
[1],
4933 LocalEncapData
->FvExtHeader
->FvName
.Data4
[2],
4934 LocalEncapData
->FvExtHeader
->FvName
.Data4
[3],
4935 LocalEncapData
->FvExtHeader
->FvName
.Data4
[4],
4936 LocalEncapData
->FvExtHeader
->FvName
.Data4
[5],
4937 LocalEncapData
->FvExtHeader
->FvName
.Data4
[6],
4938 LocalEncapData
->FvExtHeader
->FvName
.Data4
[7]);
4940 if (strcmp(FvGuidName
, FvId
) == 0) {
4941 sprintf(FvId
, "%s%d", "FV", LocalEncapData
->FvId
- 1);
4946 LocalEncapData
= LocalEncapData
->NextNode
;
4949 if ((*FvInFd
)->FvNext
== 0) {
4952 *FvInFd
= (*FvInFd
)->FvNext
;
4955 *FvInFd
= FdData
->Fv
;
4956 FvIndex1
= (UINT8
) atoi (FvId
+ 2);
4958 while (FvInFd
!= NULL
) {
4959 if (((*FvInFd
)->FvName
) != NULL
) {
4960 FvIndex2
= (UINT8
) atoi ((*FvInFd
)->FvName
+ 2);
4961 LocalEncapData
= (*FvInFd
)->EncapData
;
4962 LibFindFvInEncapData (LocalEncapData
, &FvIndex2
);
4964 if ((FvIndex2
- 1 >= FvIndex1
)) {
4968 if ((*FvInFd
)->FvNext
== 0) {
4972 *FvInFd
= (*FvInFd
)->FvNext
;
4974 if (FvGuidName
!= NULL
) {
4978 // The specified FV id has issue, can not find the FV in FD.
4981 Error ("FMMT", 0, 0005, "error while find FV in FD", "Invalid FvId, please double check the FvId. You can use view operate to get the FvId information!");
4989 #define BUILD_IN_TOOL_COUNT 4
4992 LibPreDefinedGuidedTools (
4998 GUID_SEC_TOOL_ENTRY
*FirstGuidTool
;
4999 GUID_SEC_TOOL_ENTRY
*LastGuidTool
;
5000 GUID_SEC_TOOL_ENTRY
*NewGuidTool
;
5004 CHAR8 PreDefinedGuidedTool
[BUILD_IN_TOOL_COUNT
][255] = {
5005 "a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress",
5006 "ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress",
5007 "fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32",
5008 "3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress"
5012 FirstGuidTool
= NULL
;
5013 LastGuidTool
= NULL
;
5017 for (Index
= 0; Index
< BUILD_IN_TOOL_COUNT
; Index
++) {
5018 Tool
= SplitStringByWhitespace (PreDefinedGuidedTool
[Index
]);
5019 if ((Tool
!= NULL
) &&
5022 Status
= StringToGuid (Tool
->Strings
[0], &Guid
);
5023 if (!EFI_ERROR (Status
)) {
5024 NewGuidTool
= malloc (sizeof (GUID_SEC_TOOL_ENTRY
));
5025 if (NewGuidTool
!= NULL
) {
5026 memcpy (&(NewGuidTool
->Guid
), &Guid
, sizeof (Guid
));
5027 NewGuidTool
->Name
= CloneString(Tool
->Strings
[1]);
5028 NewGuidTool
->Path
= CloneString(Tool
->Strings
[2]);
5029 NewGuidTool
->Next
= NULL
;
5031 printf ("Error while allocate resource! \n");
5032 FreeStringList (Tool
);
5035 if (FirstGuidTool
== NULL
) {
5036 FirstGuidTool
= NewGuidTool
;
5038 LastGuidTool
->Next
= NewGuidTool
;
5040 LastGuidTool
= NewGuidTool
;
5043 fprintf (stdout
, "Error");
5046 FreeStringList (Tool
);
5050 return FirstGuidTool
;