]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/FMMT/FmmtLib.c
Revert "BaseTools: fix FCE build when edksetup not executed"
[mirror_edk2.git] / BaseTools / Source / C / FMMT / FmmtLib.c
1 /** @file
2
3 Library to parse and generate FV image.
4
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "FirmwareModuleManagement.h"
11
12 #define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \
13 ( \
14 (BOOLEAN) ( \
15 (FvbAttributes & EFI_FVB2_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \
16 ) \
17 )
18
19 CHAR8 mFirmwareFileSystem2Guid[16] = {0x78, 0xE5, 0x8C, 0x8C, 0x3D, 0x8A, 0x1C, 0x4F, 0x99, 0x35, 0x89, 0x61, 0x85, 0xC3, 0x2D, 0xD3};
20
21 CHAR8 mFirmwareFileSystem3Guid[16] = {0x7A, 0xC0, 0x73, 0x54, 0xCB, 0x3D, 0xCA, 0x4D, 0xBD, 0x6F, 0x1E, 0x96, 0x89, 0xE7, 0x34, 0x9A };
22
23 EFI_GUID mEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
24 extern CHAR8* mGuidToolDefinition;
25
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
53 NULL, // 0x1A
54 "EFI_SECTION_PEI_DEPEX", // 0x1B
55 "EFI_SECTION_SMM_DEPEX" // 0x1C
56 };
57
58
59 static CHAR8 *mFfsFileType[] = {
60 NULL, // 0x00
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
74 };
75
76 static CHAR8 *mGuidSectionAttr[] = {
77 "NONE", // 0x00
78 "PROCESSING_REQUIRED", // 0x01
79 "AUTH_STATUS_VALID" // 0x02
80 };
81
82 static EFI_GUID mFvUiGuid = {
83 0xA67DF1FA, 0x8DE8, 0x4E98, {
84 0xAF, 0x09, 0x4B, 0xDF, 0x2E, 0xFF, 0xBC, 0x7C
85 }
86 };
87
88
89 /**
90 Generate the unique template filename.
91 **/
92 CHAR8 *
93 GenTempFile (
94 VOID
95 )
96 {
97 CHAR8 *TemString;
98 TemString = NULL;
99 #ifndef __GNUC__
100 TemString = CloneString (tmpnam (NULL));
101 #else
102 CHAR8 tmp[] = "/tmp/fileXXXXXX";
103 UINTN Fdtmp;
104 Fdtmp = mkstemp(tmp);
105 TemString = CloneString(tmp);
106 close(Fdtmp);
107 #endif
108 return TemString;
109 }
110
111 static
112 EFI_STATUS
113 LibExtractFvUiName(CONST EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader, CHAR8 **FvUiName)
114 {
115 UINT8 *ExtEnd;
116 UINT32 ExtDataSize;
117 EFI_FIRMWARE_VOLUME_EXT_ENTRY *ExtEntry;
118 EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE *GuidEntry;
119
120
121 ExtEnd = (UINT8 *)FvExtHeader + FvExtHeader->ExtHeaderSize;
122 ExtEntry = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *)(FvExtHeader + 1);
123 while ((UINT8 *)ExtEntry < ExtEnd) {
124 //
125 // GUID type EXT
126 //
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';
135 return EFI_SUCCESS;
136 }
137 }
138 }
139
140 ExtEntry = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *)((UINT8 *)ExtEntry + ExtEntry->ExtEntrySize);
141 }
142 return EFI_NOT_FOUND;
143 }
144
145 FV_INFORMATION *
146 LibInitializeFvStruct (
147 FV_INFORMATION *Fv
148 )
149 {
150 UINT32 Index;
151
152 if (Fv == NULL) {
153 return NULL;
154 }
155
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;
169 }
170
171 Fv->EncapData = NULL;
172 Fv->FvNext = NULL;
173 Fv->ChildFvFFS = NULL;
174 Fv->FvLevel = 0;
175 Fv->MulFvLevel = 1;
176 strcpy(Fv->AlignmentStr,"8");
177 return Fv;
178 }
179
180
181 EFI_STATUS
182 LibFindFvInFd (
183 IN FILE *InputFile,
184 IN OUT FIRMWARE_DEVICE **FdData
185 )
186 {
187 FIRMWARE_DEVICE *LocalFdData;
188 UINT16 Index;
189 CHAR8 Ffs2Guid[16];
190 CHAR8 SignatureCheck[5] = "";
191 CHAR8 Signature[5] = "_FVH";
192 FV_INFORMATION *CurrentFv;
193 FV_INFORMATION *NewFoundFv;
194 BOOLEAN FirstMatch;
195 UINT32 FdSize;
196 UINT16 FvCount;
197 UINT8 *FdBuffer;
198 UINT8 *FdBufferEnd;
199 UINT8 *FdBufferOri;
200 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
201
202 CurrentFv = NULL;
203 NewFoundFv = NULL;
204 FdBuffer = NULL;
205 FdBufferOri = NULL;
206 FirstMatch = TRUE;
207 Index = 0;
208 FdSize = 0;
209 FvCount = 0;
210 LocalFdData = NULL;
211
212 if (InputFile == NULL) {
213 Error ("FMMT", 0, 0001, "Error opening the input file", "");
214 return EFI_ABORTED;
215 }
216
217 //
218 // Find each FVs in the FD
219 //
220
221 fseek(InputFile,0,SEEK_SET);
222 fseek(InputFile,0,SEEK_END);
223
224 FdSize = ftell(InputFile);
225
226 fseek(InputFile,0,SEEK_SET);
227 //
228 // Create an FD structure to store useful information.
229 //
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;
234 }
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");
238 free (LocalFdData);
239 return EFI_OUT_OF_RESOURCES;
240 }
241
242 LibInitializeFvStruct (LocalFdData->Fv);
243
244 //
245 // Readout the FD file data to buffer.
246 //
247 FdBuffer = malloc (FdSize);
248
249 if (FdBuffer == NULL) {
250 Error ("FMMT", 0, 0002, "Error searching FVs in the input fd", "Allocate memory error");
251 free (LocalFdData->Fv);
252 free (LocalFdData);
253 return EFI_OUT_OF_RESOURCES;
254 }
255
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);
259 free (LocalFdData);
260 free (FdBuffer);
261 return EFI_ABORTED;
262 }
263
264 FdBufferOri = FdBuffer;
265 FdBufferEnd = FdBuffer + FdSize;
266
267 while (FdBuffer <= FdBufferEnd - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {
268 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FdBuffer;
269 //
270 // Copy 4 bytes of fd data to check the _FVH signature
271 //
272 memcpy (SignatureCheck, &FvHeader->Signature, 4);
273
274 if (strncmp(SignatureCheck, Signature, 4) == 0){
275 //
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.
279 //
280 memcpy (Ffs2Guid, &FvHeader->FileSystemGuid, 16);
281
282 //
283 // Compare GUID.
284 //
285 for (Index = 0; Index < 16; Index ++) {
286 if (Ffs2Guid[Index] != mFirmwareFileSystem2Guid[Index]) {
287 break;
288 }
289 }
290 if (Index != 16) {
291 for (Index = 0; Index < 16; Index ++) {
292 if (Ffs2Guid[Index] != mFirmwareFileSystem3Guid[Index]) {
293 break;
294 }
295 }
296 }
297
298 //
299 // Here we found an FV.
300 //
301 if ((Index == 16) && ((FdBuffer + FvHeader->FvLength) <= FdBufferEnd)) {
302 if (FirstMatch) {
303 LocalFdData->Fv->ImageAddress = (UINTN)((UINT8 *)FdBuffer - (UINT8 *)FdBufferOri);
304 CurrentFv = LocalFdData->Fv;
305 CurrentFv->FvNext = NULL;
306 //
307 // Store the FV name by found sequence
308 //
309 sprintf(CurrentFv->FvName, "FV%d", FvCount);
310
311 FirstMatch = FALSE;
312 } else {
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);
317 free (LocalFdData);
318 free (FdBuffer);
319 return EFI_OUT_OF_RESOURCES;
320 }
321
322 LibInitializeFvStruct (NewFoundFv);
323
324 //
325 // Need to turn back 0x2c bytes
326 //
327 NewFoundFv->ImageAddress = (UINTN)((UINT8 *)FdBuffer - (UINT8 *)FdBufferOri);
328
329 //
330 // Store the FV name by found sequence
331 //
332 sprintf(NewFoundFv->FvName, "FV%d", FvCount);
333
334 //
335 // Value it to NULL for found FV usage.
336 //
337 NewFoundFv->FvNext = NULL;
338 CurrentFv->FvNext = NewFoundFv;
339
340 //
341 // Make the CurrentFv point to next FV.
342 //
343 CurrentFv = CurrentFv->FvNext;
344 }
345
346 FvCount ++;
347 FdBuffer = FdBuffer + FvHeader->FvLength;
348 } else {
349 FdBuffer ++;
350 }
351
352 } else {
353 FdBuffer ++;
354 }
355 }
356
357 LocalFdData->Size = FdSize;
358
359 *FdData = LocalFdData;
360
361 free (FdBufferOri);
362
363 return EFI_SUCCESS;
364 }
365
366 UINTN
367 GetFreeOffset (
368 IN VOID *InputFv
369 )
370 {
371 UINTN FreeOffset;
372 UINTN Offset;
373 EFI_STATUS Status;
374 EFI_FFS_FILE_HEADER2 *CurrentFile;
375
376 Offset = 0;
377 CurrentFile = NULL;
378 FreeOffset = 0;
379 do {
380 FreeOffset = (UINTN)ALIGN_POINTER(Offset, 8);
381 Status = FvBufFindNextFile(InputFv, &Offset, (VOID **)&CurrentFile);
382 if (Status == EFI_NOT_FOUND) {
383 CurrentFile = NULL;
384 break;
385 }
386 else if (EFI_ERROR(Status)) {
387 return Status;
388 }
389 } while (CurrentFile != NULL);
390
391 return FreeOffset;
392 }
393
394 /*
395 Construct a set of blank chars based on the number.
396
397 @param[in] Count The number of blank chars.
398
399 @return A string contained the blank chars.
400
401 */
402 CHAR8 *
403 LibConstructBlankChar (
404 IN UINT8 Count
405 )
406 {
407 CHAR8 *RetStr;
408 UINT8 Index;
409
410 Index = 0;
411 RetStr = NULL;
412
413 RetStr = (CHAR8 *) malloc (Count +1);
414
415 if (RetStr == NULL) {
416 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
417 return NULL;
418 }
419
420 memset (RetStr , '\0', Count + 1);
421
422 for (Index=0; Index <= Count -1; Index ++) {
423 RetStr[Index] = ' ';
424 }
425
426 return RetStr;
427
428 }
429
430 /**
431
432 This function determines the size of the FV and the erase polarity. The
433 erase polarity is the FALSE value for file state.
434
435
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.
439
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.
443
444 **/
445 EFI_STATUS
446 LibReadFvHeader (
447 IN VOID *InputFv,
448 IN BOOLEAN ViewFlag,
449 IN UINT8 FvLevel,
450 IN UINT8 FvCount,
451 IN CHAR8 *FvName
452 )
453 {
454 EFI_FIRMWARE_VOLUME_HEADER *VolumeHeader;
455 CHAR8 *BlankSpace;
456 CHAR8 *FvUiName;
457 EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
458
459 BlankSpace = NULL;
460 FvUiName = NULL;
461
462 //
463 // Check input parameters
464 //
465 if (InputFv == NULL) {
466 Error (__FILE__, __LINE__, 0, "FMMT application error", "invalid parameter to function");
467 return EFI_INVALID_PARAMETER;
468 }
469
470 //
471 // Read the header
472 //
473 VolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *) InputFv;
474
475
476 BlankSpace = LibConstructBlankChar((FvLevel)*2);
477
478 if (BlankSpace == NULL) {
479 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
480 return EFI_OUT_OF_RESOURCES;
481 }
482
483
484 if (ViewFlag) {
485 if ((FvLevel -1) == 0) {
486 printf ("\n%s :\n", FvName);
487 } else {
488 printf ("%sChild FV named FV%d of %s\n", BlankSpace, FvCount, FvName);
489 }
490 }
491
492 //
493 // Print FV header information
494 //
495 if (ViewFlag) {
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)));
499 }
500
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",
504 BlankSpace,
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);
519 }
520 free(FvUiName);
521 }
522 free (BlankSpace);
523 return EFI_SUCCESS;
524 }
525
526 /*
527 Get size info from FV file.
528
529 @param[in]
530 @param[out]
531
532 @retval
533
534 */
535 EFI_STATUS
536 LibGetFvSize (
537 IN FILE *InputFile,
538 OUT UINT32 *FvSize
539 )
540 {
541
542 UINTN BytesRead;
543 UINT32 Size;
544 EFI_FV_BLOCK_MAP_ENTRY BlockMap;
545
546 BytesRead = 0;
547 Size = 0;
548
549 if (InputFile == NULL || FvSize == NULL) {
550 Error (__FILE__, __LINE__, 0, "FMMT application error", "invalid parameter to function");
551 return EFI_INVALID_PARAMETER;
552 }
553
554 fseek (InputFile, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), SEEK_CUR);
555 do {
556 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
557 BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
558
559 if (BlockMap.NumBlocks != 0) {
560 Size += BlockMap.NumBlocks * BlockMap.Length;
561 }
562 } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));
563
564
565 *FvSize = Size;
566
567 return EFI_SUCCESS;
568 }
569
570 /**
571
572 Clears out all files from the Fv buffer in memory
573
574 @param[in] Fv - Address of the Fv in memory
575
576 @return EFI_STATUS
577
578 **/
579 EFI_STATUS
580 FvBufGetSize (
581 IN VOID *Fv,
582 OUT UINTN *Size
583 )
584 {
585 EFI_FIRMWARE_VOLUME_HEADER *hdr;
586 EFI_FV_BLOCK_MAP_ENTRY *blk;
587
588 *Size = 0;
589 hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
590 blk = hdr->BlockMap;
591
592 while (blk->Length != 0 || blk->NumBlocks != 0) {
593 *Size = *Size + (blk->Length * blk->NumBlocks);
594 if (*Size >= 0x40000000) {
595 //
596 // If size is greater than 1GB, then assume it is corrupted
597 //
598 return EFI_VOLUME_CORRUPTED;
599 }
600 blk++;
601 }
602
603 if (*Size == 0) {
604 //
605 // If size is 0, then assume the volume is corrupted
606 //
607 return EFI_VOLUME_CORRUPTED;
608 }
609
610 return EFI_SUCCESS;
611 }
612
613 /*
614 Generate the leaf FFS files.
615
616 */
617 EFI_STATUS
618 LibGenFfsFile (
619 EFI_FFS_FILE_HEADER2 *CurrentFile,
620 FV_INFORMATION *CurrentFv,
621 CHAR8 *FvName,
622 UINT8 Level,
623 UINT32 *FfsCount,
624 BOOLEAN ErasePolarity
625 )
626 {
627 UINT32 FfsFileSize;
628 CHAR8 *FfsFileName;
629 FILE *FfsFile;
630 CHAR8 *TempDir;
631
632
633 FfsFileSize = 0;
634 FfsFileName = NULL;
635 FfsFile = NULL;
636 TempDir = NULL;
637
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.", "");
641 return EFI_ABORTED;
642 }
643 strncat (TempDir, OS_SEP_STR, _MAX_PATH - strlen(TempDir) - 1);
644 strncat (TempDir, TEMP_DIR_NAME, _MAX_PATH - strlen(TempDir) - 1);
645
646 mkdir(TempDir, S_IRWXU | S_IRWXG | S_IRWXO);
647
648 FfsFileName = (CHAR8 *) malloc (_MAX_PATH);
649 if (FfsFileName == NULL) {
650 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
651 return EFI_ABORTED;
652 }
653 memset (FfsFileName, '\0', _MAX_PATH);
654 FfsFileSize = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) CurrentFile);
655 sprintf (
656 (CHAR8 *)FfsFileName,
657 "%s%cNum%d-%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X-Level%d",
658 TempDir,
659 OS_SEP,
660 *FfsCount,
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],
672 Level
673 );
674
675 memcpy (CurrentFv->FfsAttuibutes[*FfsCount].FfsName, FfsFileName, strlen(FfsFileName));
676 memcpy (&CurrentFv->FfsAttuibutes[*FfsCount].GuidName, &CurrentFile->Name, sizeof(EFI_GUID));
677 //
678 // Update current FFS files file state.
679 //
680 if (ErasePolarity) {
681 CurrentFile->State = (UINT8)~(CurrentFile->State);
682 }
683
684 FfsFile = fopen (FfsFileName, "wb+");
685 if (FfsFile == NULL) {
686 Error ("FMMT", 0, 0003, "error writing FFS file", "cannot Create a new ffs file.");
687 free(FfsFileName);
688 return EFI_ABORTED;
689 }
690
691 if (fwrite (CurrentFile, 1, FfsFileSize, FfsFile) != FfsFileSize) {
692 Error ("FMMT", 0, 0004, "error writing FFS file", "cannot Create a new ffs file.");
693 fclose(FfsFile);
694 free(FfsFileName);
695 return EFI_ABORTED;
696 }
697
698 fclose(FfsFile);
699 free(FfsFileName);
700 FfsFileName = NULL;
701
702 CurrentFv->FfsNumbers = *FfsCount;
703
704 *FfsCount += 1;
705
706 if (ErasePolarity) {
707 CurrentFile->State = (UINT8)~(CurrentFile->State);
708 }
709
710 return EFI_SUCCESS;
711 }
712
713 VOID
714 Unicode2AsciiString (
715 IN CHAR16 *Source,
716 OUT CHAR8 *Destination
717 )
718 /*++
719
720 Routine Description:
721
722 Convert a null-terminated unicode string to a null-terminated ascii string.
723
724 Arguments:
725
726 Source - The pointer to the null-terminated input unicode string.
727 Destination - The pointer to the null-terminated output ascii string.
728
729 Returns:
730
731 N/A
732
733 --*/
734 {
735 while (*Source != '\0') {
736 *(Destination++) = (CHAR8) *(Source++);
737 }
738 //
739 // End the ascii with a NULL.
740 //
741 *Destination = '\0';
742 }
743
744
745 /**
746
747 Parses EFI Sections, if the view flag turn on, then will collect FFS section information
748 and extract FFS files.
749
750 @param[in] SectionBuffer - Buffer containing the section to parse.
751 @param[in] BufferLength - Length of SectionBuffer
752 @param[in, out] CurrentFv
753 @param[in] FvName
754 @param[in] CurrentFile
755 @param[in] Level
756 @param[in, out] FfsCount
757 @param[in] ViewFlag
758 @param[in] ErasePolarity
759
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.
766
767 --*/
768 EFI_STATUS
769 LibParseSection (
770 UINT8 *SectionBuffer,
771 UINT32 BufferLength,
772 FV_INFORMATION *CurrentFv,
773 CHAR8 *FvName,
774 EFI_FFS_FILE_HEADER2 *CurrentFile,
775 UINT8 Level,
776 ENCAP_INFO_DATA **CurrentFvEncapData,
777 UINT8 FfsLevel,
778 UINT32 *FfsCount,
779 UINT8 *FvCount,
780 BOOLEAN ViewFlag,
781 BOOLEAN ErasePolarity,
782 BOOLEAN *IsFfsGenerated
783 )
784 {
785 UINT32 ParsedLength;
786 UINT8 *Ptr;
787 UINT32 SectionLength;
788 UINT32 UiSectionLength;
789 EFI_SECTION_TYPE Type;
790 EFI_STATUS Status;
791 CHAR8 *ExtractionTool;
792 CHAR8 *ToolInputFile;
793 CHAR8 *ToolOutputFile;
794 CHAR8 *SystemCommandFormatString;
795 CHAR8 *SystemCommand;
796 UINT8 *ToolOutputBuffer;
797 UINT32 ToolOutputLength;
798 CHAR16 *UIName;
799 UINT32 UINameSize;
800 BOOLEAN HasDepexSection;
801 UINT32 NumberOfSections;
802 ENCAP_INFO_DATA *LocalEncapData;
803 ENCAP_INFO_DATA *LocalEncapDataTemp;
804 CHAR8 *BlankChar;
805 UINT8 *UncompressedBuffer;
806 UINT32 UncompressedLength;
807 UINT8 *CompressedBuffer;
808 UINT32 CompressedLength;
809 UINT8 CompressionType;
810 DECOMPRESS_FUNCTION DecompressFunction;
811 GETINFO_FUNCTION GetInfoFunction;
812 UINT32 DstSize;
813 UINT32 ScratchSize;
814 UINT8 *ScratchBuffer;
815 BOOLEAN EncapDataNeedUpdata;
816 CHAR8 *TempDir;
817 CHAR8 *ToolInputFileFullName;
818 CHAR8 *ToolOutputFileFullName;
819 UINT8 LargeHeaderOffset;
820 UINT16 GuidAttr;
821 UINT16 DataOffset;
822 CHAR8 *UIFileName;
823 CHAR8 *ToolInputFileName;
824 CHAR8 *ToolOutputFileName;
825
826 DataOffset = 0;
827 GuidAttr = 0;
828 ParsedLength = 0;
829 ToolOutputLength = 0;
830 UINameSize = 0;
831 NumberOfSections = 0;
832 UncompressedLength = 0;
833 CompressedLength = 0;
834 CompressionType = 0;
835 DstSize = 0;
836 ScratchSize = 0;
837 Ptr = NULL;
838 ExtractionTool = NULL;
839 ToolInputFile = NULL;
840 ToolOutputFile = NULL;
841 SystemCommand = NULL;
842 SystemCommandFormatString = NULL;
843 ToolOutputBuffer = NULL;
844 UIName = NULL;
845 LocalEncapData = NULL;
846 LocalEncapDataTemp = NULL;
847 BlankChar = NULL;
848 UncompressedBuffer = NULL;
849 CompressedBuffer = NULL;
850 ScratchBuffer = NULL;
851 TempDir = NULL;
852 ToolInputFileFullName = NULL;
853 ToolOutputFileFullName = NULL;
854 ToolInputFileName = NULL;
855 ToolOutputFileFullName = NULL;
856 HasDepexSection = FALSE;
857 EncapDataNeedUpdata = TRUE;
858 LargeHeaderOffset = 0;
859
860
861 while (ParsedLength < BufferLength) {
862 Ptr = SectionBuffer + ParsedLength;
863
864 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);
865 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;
866
867 //
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.
871 //
872 if (SectionLength == 0xffffff && Type == 0xff) {
873 ParsedLength += 4;
874 continue;
875 }
876 //
877 //If Size is 0xFFFFFF then ExtendedSize contains the size of the section.
878 //
879 if (SectionLength == 0xffffff) {
880 SectionLength = ((EFI_COMMON_SECTION_HEADER2 *) Ptr)->ExtendedSize;
881 LargeHeaderOffset = sizeof (EFI_COMMON_SECTION_HEADER2) - sizeof (EFI_COMMON_SECTION_HEADER);
882 }
883
884 switch (Type) {
885
886 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
887
888 EncapDataNeedUpdata = TRUE;
889
890 Level ++;
891 NumberOfSections ++;
892
893 CurrentFv->FfsAttuibutes[*FfsCount].IsLeaf = FALSE;
894 CurrentFv->FfsAttuibutes[*FfsCount].IsFvStart = TRUE;
895 //
896 // Put in encapsulate data information.
897 //
898 LocalEncapData = *CurrentFvEncapData;
899 if (LocalEncapData->NextNode != NULL) {
900 LocalEncapData = LocalEncapData->NextNode;
901 while (LocalEncapData->RightNode != NULL) {
902 LocalEncapData = LocalEncapData->RightNode;
903 }
904 }
905
906 if (EncapDataNeedUpdata) {
907 //
908 // Put in this is an FFS with FV section
909 //
910
911 //
912 // Construct the new ENCAP_DATA
913 //
914 LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));
915
916 if (LocalEncapData->NextNode == NULL) {
917 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
918 return EFI_ABORTED;
919 }
920
921 LocalEncapData = LocalEncapData->NextNode;
922
923 LocalEncapData->Level = Level;
924 LocalEncapData->Type = FMMT_ENCAP_TREE_FV_SECTION;
925
926 //
927 // We don't need additional data for encapsulate this FFS but type.
928 //
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;
937 }
938
939 //
940 //save parent level FFS file's GUID name
941 //
942 LocalEncapDataTemp = CurrentFv->EncapData;
943 while (LocalEncapDataTemp->NextNode != NULL) {
944 if (LocalEncapDataTemp->Level == FfsLevel) {
945 while (LocalEncapDataTemp->RightNode != NULL) {
946 LocalEncapDataTemp = LocalEncapDataTemp->RightNode;
947 }
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);
952 return EFI_ABORTED;
953 }
954
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);
963 return EFI_ABORTED;
964 }
965 memcpy(LocalEncapDataTemp->Depex, CurrentFv->FfsAttuibutes[*FfsCount - 1].Depex, LocalEncapDataTemp->DepexLen);
966 }
967 }
968 }
969 break;
970 }
971 LocalEncapDataTemp = LocalEncapDataTemp->NextNode;
972 }
973
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;
978 }
979 if (*FfsCount >= 1) {
980 CurrentFv->FfsAttuibutes[*FfsCount -1].IsFvEnd = TRUE;
981 }
982 break;
983
984 case EFI_SECTION_COMPRESSION:
985 Level ++;
986 NumberOfSections ++;
987
988 EncapDataNeedUpdata = TRUE;
989 //
990 // Put in encapsulate data information.
991 //
992 LocalEncapData = *CurrentFvEncapData;
993 if (LocalEncapData->NextNode != NULL) {
994 EncapDataNeedUpdata = FALSE;
995 while (LocalEncapData->RightNode != NULL) {
996 LocalEncapData = LocalEncapData->RightNode;
997 }
998 }
999
1000 if (EncapDataNeedUpdata) {
1001 //
1002 // Put in this is an FFS with FV section
1003 //
1004
1005 //
1006 // Construct the new ENCAP_DATA
1007 //
1008 LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));
1009
1010 if (LocalEncapData->NextNode == NULL) {
1011 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1012 return EFI_ABORTED;
1013 }
1014
1015 LocalEncapData = LocalEncapData->NextNode;
1016
1017 LocalEncapData->Level = Level;
1018 LocalEncapData->Type = FMMT_ENCAP_TREE_COMPRESS_SECTION;
1019
1020 //
1021 // Store the compress type
1022 //
1023 LocalEncapData->Data = malloc (sizeof (UINT8));
1024
1025 if (LocalEncapData->Data == NULL) {
1026 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL);
1027 return EFI_OUT_OF_RESOURCES;
1028 }
1029
1030 *(UINT8 *)LocalEncapData->Data = ((EFI_COMPRESSION_SECTION *) (Ptr + LargeHeaderOffset))->CompressionType;
1031 LocalEncapData->FvExtHeader = NULL;
1032 LocalEncapData->NextNode = NULL;
1033 LocalEncapData->RightNode = NULL;
1034 } else {
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);
1038 return EFI_ABORTED;
1039 }
1040 LocalEncapData = LocalEncapData->RightNode;
1041
1042 LocalEncapData->Level = Level;
1043 LocalEncapData->Type = FMMT_ENCAP_TREE_COMPRESS_SECTION;
1044
1045 //
1046 // Store the compress type
1047 //
1048 LocalEncapData->Data = malloc (sizeof (UINT8));
1049
1050 if (LocalEncapData->Data == NULL) {
1051 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL);
1052 return EFI_OUT_OF_RESOURCES;
1053 }
1054
1055 *(UINT8 *)LocalEncapData->Data = ((EFI_COMPRESSION_SECTION *) (Ptr + LargeHeaderOffset))->CompressionType;
1056 LocalEncapData->FvExtHeader = NULL;
1057 LocalEncapData->NextNode = NULL;
1058 LocalEncapData->RightNode = NULL;
1059
1060 }
1061
1062 //
1063 // Process compressed section
1064 //
1065 CurrentFv->FfsAttuibutes[*FfsCount].IsLeaf = FALSE;
1066
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;
1071
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;
1077 }
1078
1079 UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION) + LargeHeaderOffset;
1080 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {
1081 GetInfoFunction = EfiGetInfo;
1082 DecompressFunction = EfiDecompress;
1083
1084 CompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION) + LargeHeaderOffset;
1085
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;
1090 }
1091
1092 if (DstSize != UncompressedLength) {
1093 Error ("FMMT", 0, 0003, "compression error in the compression section", NULL);
1094 return EFI_SECTION_ERROR;
1095 }
1096
1097 ScratchBuffer = malloc (ScratchSize);
1098 if (ScratchBuffer == NULL) {
1099 Error ("FMMT", 0, 0003, "Allocate memory failed", NULL);
1100 return EFI_OUT_OF_RESOURCES;
1101 }
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;
1107 }
1108 //
1109 // Decompress the section.
1110 //
1111 Status = DecompressFunction (
1112 CompressedBuffer,
1113 CompressedLength,
1114 UncompressedBuffer,
1115 UncompressedLength,
1116 ScratchBuffer,
1117 ScratchSize
1118 );
1119 free (ScratchBuffer);
1120 if (EFI_ERROR (Status)) {
1121 Error ("FMMT", 0, 0003, "decompress failed", NULL);
1122 free (UncompressedBuffer);
1123 return EFI_SECTION_ERROR;
1124 }
1125 } else {
1126 Error ("FMMT", 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);
1127 return EFI_SECTION_ERROR;
1128 }
1129
1130 Status = LibParseSection ( UncompressedBuffer,
1131 UncompressedLength,
1132 CurrentFv,
1133 FvName,
1134 CurrentFile,
1135 Level,
1136 &LocalEncapData,
1137 FfsLevel,
1138 FfsCount,
1139 FvCount,
1140 ViewFlag,
1141 ErasePolarity,
1142 IsFfsGenerated);
1143
1144 if (CompressionType == EFI_STANDARD_COMPRESSION) {
1145 //
1146 // We need to deallocate Buffer
1147 //
1148 free (UncompressedBuffer);
1149 }
1150
1151 if (EFI_ERROR (Status)) {
1152 Error (NULL, 0, 0003, "failed to parse section", NULL);
1153 return EFI_SECTION_ERROR;
1154 }
1155
1156 break;
1157
1158 case EFI_SECTION_GUID_DEFINED:
1159 //
1160 // Process GUID defined
1161 // looks up the appropriate tool to use for extracting
1162 // a GUID defined FV section.
1163 //
1164 Level ++;
1165 NumberOfSections++;
1166 EncapDataNeedUpdata = TRUE;
1167 //
1168 // Put in encapsulate data information.
1169 //
1170 LocalEncapData = *CurrentFvEncapData;
1171 if (LocalEncapData->NextNode != NULL) {
1172 EncapDataNeedUpdata = FALSE;
1173 while (LocalEncapData->RightNode != NULL) {
1174 LocalEncapData = LocalEncapData->RightNode;
1175 }
1176 }
1177 GuidAttr = ((EFI_GUID_DEFINED_SECTION *)(Ptr + LargeHeaderOffset))->Attributes;
1178 DataOffset = ((EFI_GUID_DEFINED_SECTION *)(Ptr + LargeHeaderOffset))->DataOffset;
1179
1180 if ((ViewFlag) && ((GuidAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0)) {
1181 ToolOutputBuffer = Ptr + DataOffset;
1182 ToolOutputLength = SectionLength - DataOffset;
1183 Status = LibParseSection(
1184 ToolOutputBuffer,
1185 ToolOutputLength,
1186 CurrentFv,
1187 FvName,
1188 CurrentFile,
1189 Level,
1190 &LocalEncapData,
1191 FfsLevel,
1192 FfsCount,
1193 FvCount,
1194 ViewFlag,
1195 ErasePolarity,
1196 IsFfsGenerated
1197 );
1198 if (EFI_ERROR(Status)) {
1199 Error(NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
1200 return EFI_SECTION_ERROR;
1201 }
1202 break;
1203 }
1204
1205 if (EncapDataNeedUpdata) {
1206
1207 //
1208 // Put in this is an FFS with FV section
1209 //
1210
1211 //
1212 // Construct the new ENCAP_DATA
1213 //
1214 LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));
1215
1216 if (LocalEncapData->NextNode == NULL) {
1217 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1218 return EFI_ABORTED;
1219 }
1220
1221 LocalEncapData = LocalEncapData->NextNode;
1222
1223 LocalEncapData->Level = Level;
1224 LocalEncapData->Type = FMMT_ENCAP_TREE_GUIDED_SECTION;
1225 LocalEncapData->Depex = NULL;
1226 LocalEncapData->DepexLen = 0;
1227 LocalEncapData->UiNameSize = 0;
1228 //
1229 // We don't need additional data for encapsulate this FFS but type.
1230 // include DataOffset + Attributes
1231 //
1232
1233 LocalEncapData->Data = (EFI_GUID *) malloc (sizeof (EFI_GUID) + 4);
1234
1235 if (LocalEncapData->Data == NULL) {
1236 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1237 return EFI_ABORTED;
1238 }
1239
1240 //
1241 // include guid attribute and dataoffset
1242 //
1243 memcpy (LocalEncapData->Data, Ptr + LargeHeaderOffset + OFFSET_OF (EFI_GUID_DEFINED_SECTION, SectionDefinitionGuid), sizeof (EFI_GUID) + 4);
1244
1245 LocalEncapData->FvExtHeader = NULL;
1246 LocalEncapData->NextNode = NULL;
1247 LocalEncapData->RightNode = NULL;
1248 } else {
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);
1252 return EFI_ABORTED;
1253 }
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;
1260 //
1261 // We don't need additional data for encapsulate this FFS but type.
1262 // include DataOffset + Attributes
1263 //
1264
1265 LocalEncapData->Data = (EFI_GUID *) malloc (sizeof (EFI_GUID) + 4);
1266
1267 if (LocalEncapData->Data == NULL) {
1268 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1269 return EFI_ABORTED;
1270 }
1271
1272 //
1273 // include guid attribute and dataoffset
1274 //
1275 memcpy (LocalEncapData->Data, Ptr + LargeHeaderOffset + OFFSET_OF (EFI_GUID_DEFINED_SECTION, SectionDefinitionGuid), sizeof (EFI_GUID) + 4);
1276
1277 LocalEncapData->FvExtHeader = NULL;
1278 LocalEncapData->NextNode = NULL;
1279 LocalEncapData->RightNode = NULL;
1280 }
1281
1282 CurrentFv->FfsAttuibutes[*FfsCount].IsLeaf = FALSE;
1283
1284 ExtractionTool =
1285 LookupGuidedSectionToolPath (
1286 mParsedGuidedSectionTools,
1287 &((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->SectionDefinitionGuid
1288 );
1289
1290 if (ExtractionTool != NULL && ((GuidAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0)) {
1291
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;
1297 }
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;
1306 }
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;
1313 }
1314 ToolInputFileName = strrchr(ToolInputFile, OS_SEP);
1315 if (ToolInputFileName == NULL) {
1316 free (ToolInputFile);
1317 free (ToolOutputFile);
1318 free (ExtractionTool);
1319 return EFI_ABORTED;
1320 }
1321 ToolOutputFileName = strrchr(ToolOutputFile, OS_SEP);
1322 if (ToolOutputFileName == NULL) {
1323 free (ToolInputFile);
1324 free (ToolOutputFile);
1325 free (ExtractionTool);
1326 return EFI_ABORTED;
1327 }
1328
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;
1336 }
1337 ToolOutputFileFullName = malloc (strlen("%s%s") + strlen(TempDir) + strlen(ToolOutputFileName) + 1);
1338
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;
1346 }
1347
1348 sprintf (ToolInputFileFullName, "%s%s", TempDir, ToolInputFileName);
1349 sprintf (ToolOutputFileFullName, "%s%s", TempDir, ToolOutputFileName);
1350
1351 //
1352 // Construction 'system' command string
1353 //
1354 SystemCommandFormatString = "%s -d -o \"%s\" \"%s\"";
1355 SystemCommand = malloc (
1356 strlen (SystemCommandFormatString) +
1357 strlen (ExtractionTool) +
1358 strlen (ToolInputFileFullName) +
1359 strlen (ToolOutputFileFullName) +
1360 1
1361 );
1362 if (SystemCommand == NULL) {
1363 free (ToolInputFile);
1364 free (ToolOutputFile);
1365 free (ToolInputFileFullName);
1366 free (ToolOutputFileFullName);
1367 free (ExtractionTool);
1368 return EFI_ABORTED;
1369 }
1370 sprintf (
1371 SystemCommand,
1372 "%s -d -o \"%s\" \"%s\"",
1373 ExtractionTool,
1374 ToolOutputFileFullName,
1375 ToolInputFileFullName
1376 );
1377 free (ExtractionTool);
1378 ExtractionTool = NULL;
1379
1380 Status = PutFileImage (
1381 ToolInputFileFullName,
1382 (CHAR8*) Ptr + ((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->DataOffset,
1383 SectionLength - ((EFI_GUID_DEFINED_SECTION *) (Ptr + LargeHeaderOffset))->DataOffset
1384 );
1385
1386 if (HasDepexSection) {
1387 HasDepexSection = FALSE;
1388 }
1389
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;
1399 }
1400
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);
1409 return EFI_ABORTED;
1410 }
1411 free (SystemCommand);
1412 remove (ToolInputFileFullName);
1413 free (ToolInputFile);
1414 free (ToolInputFileFullName);
1415 ToolInputFile = NULL;
1416 ToolInputFileFullName = NULL;
1417
1418
1419 Status = GetFileImage (
1420 ToolOutputFileFullName,
1421 (CHAR8 **)&ToolOutputBuffer,
1422 &ToolOutputLength
1423 );
1424 remove (ToolOutputFileFullName);
1425 free (ToolOutputFile);
1426 free (ToolOutputFileFullName);
1427 ToolOutputFile = NULL;
1428 ToolOutputFileFullName = NULL;
1429
1430 if (EFI_ERROR (Status)) {
1431 Error ("FMMT", 0, 0004, "unable to read decoded GUIDED section", NULL);
1432 return EFI_SECTION_ERROR;
1433 }
1434
1435 Status = LibParseSection (
1436 ToolOutputBuffer,
1437 ToolOutputLength,
1438 CurrentFv,
1439 FvName,
1440 CurrentFile,
1441 Level,
1442 &LocalEncapData,
1443 FfsLevel,
1444 FfsCount,
1445 FvCount,
1446 ViewFlag,
1447 ErasePolarity,
1448 IsFfsGenerated
1449 );
1450 if (EFI_ERROR (Status)) {
1451 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
1452 return EFI_SECTION_ERROR;
1453 }
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,
1458 CurrentFv,
1459 FvName,
1460 CurrentFile,
1461 Level,
1462 &LocalEncapData,
1463 FfsLevel,
1464 FfsCount,
1465 FvCount,
1466 ViewFlag,
1467 ErasePolarity,
1468 IsFfsGenerated
1469 );
1470 if (ExtractionTool != NULL) {
1471 free (ExtractionTool);
1472 ExtractionTool = NULL;
1473 }
1474 if (EFI_ERROR (Status)) {
1475 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
1476 return EFI_SECTION_ERROR;
1477 }
1478 }else {
1479 //
1480 // We don't know how to parse it now.
1481 //
1482 if (ExtractionTool != NULL) {
1483 free (ExtractionTool);
1484 ExtractionTool = NULL;
1485 }
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;
1491 }
1492 break;
1493
1494 //
1495 //Leaf sections
1496 //
1497 case EFI_SECTION_RAW:
1498 NumberOfSections ++;
1499 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1500 if (!ViewFlag) {
1501 if (!*IsFfsGenerated) {
1502 LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
1503 *IsFfsGenerated = TRUE;
1504 }
1505 }
1506
1507 break;
1508 case EFI_SECTION_PE32:
1509 NumberOfSections ++;
1510 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1511 if (!ViewFlag) {
1512 if (!*IsFfsGenerated) {
1513 LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
1514 *IsFfsGenerated = TRUE;
1515 }
1516 }
1517
1518 break;
1519 case EFI_SECTION_PIC:
1520 NumberOfSections ++;
1521 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1522 if (!ViewFlag) {
1523 if (!*IsFfsGenerated) {
1524 LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
1525 *IsFfsGenerated = TRUE;
1526 }
1527 }
1528
1529 break;
1530 case EFI_SECTION_TE:
1531 NumberOfSections ++;
1532 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1533 if (!ViewFlag) {
1534 if (!*IsFfsGenerated) {
1535 LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
1536 *IsFfsGenerated = TRUE;
1537 }
1538 }
1539 break;
1540
1541 case EFI_SECTION_COMPATIBILITY16:
1542 NumberOfSections ++;
1543 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1544 if (!ViewFlag) {
1545 if (!*IsFfsGenerated) {
1546 LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
1547 *IsFfsGenerated = TRUE;
1548 }
1549 }
1550 break;
1551
1552 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
1553 NumberOfSections ++;
1554 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1555 if (!ViewFlag) {
1556 if (!*IsFfsGenerated) {
1557 LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
1558 *IsFfsGenerated = TRUE;
1559 }
1560 }
1561 break;
1562
1563 case EFI_SECTION_VERSION:
1564 NumberOfSections ++;
1565 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1566 break;
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;
1574 break;
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;
1582 break;
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;
1590 break;
1591
1592 case EFI_SECTION_USER_INTERFACE:
1593 NumberOfSections ++;
1594 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1595
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);
1600 } else {
1601 UINameSize = UiSectionLength - sizeof(EFI_COMMON_SECTION_HEADER);
1602 }
1603
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);
1609 } else {
1610 memcpy(UIName, ((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UINameSize);
1611 }
1612 } else {
1613 Error ("FMMT", 0, 0001, "Memory allocate error!", NULL);
1614 return EFI_OUT_OF_RESOURCES;
1615 }
1616
1617 BlankChar = LibConstructBlankChar( CurrentFv->FvLevel * 2);
1618 if (BlankChar == NULL) {
1619 free(UIName);
1620 return EFI_OUT_OF_RESOURCES;
1621 }
1622
1623 if (ViewFlag) {
1624 UIFileName = malloc (UINameSize + 2);
1625 if (UIFileName == NULL) {
1626 Error ("FMMT", 0, 4001, "Memory allocation fail!", NULL);
1627 free (UIName);
1628 free (BlankChar);
1629 return EFI_OUT_OF_RESOURCES;
1630 }
1631 Unicode2AsciiString (UIName, UIFileName);
1632 fprintf(stdout, "%sFile \"%s\"\n", BlankChar, UIFileName);
1633 free(UIFileName);
1634 }
1635 free (BlankChar);
1636
1637 //
1638 // If Ffs file has been generated, then the FfsCount should decrease 1.
1639 //
1640 if (*IsFfsGenerated) {
1641 memcpy (CurrentFv->FfsAttuibutes[*FfsCount -1].UiName, UIName, UINameSize);
1642 CurrentFv->FfsAttuibutes[*FfsCount -1].UiNameSize = UINameSize;
1643 } else {
1644 memcpy (CurrentFv->FfsAttuibutes[*FfsCount].UiName, UIName, UINameSize);
1645 CurrentFv->FfsAttuibutes[*FfsCount].UiNameSize = UINameSize;
1646 }
1647
1648 HasDepexSection = FALSE;
1649 free(UIName);
1650 UINameSize = 0;
1651
1652 break;
1653 default:
1654 break;
1655 }
1656
1657 ParsedLength += SectionLength;
1658 //
1659 // We make then next section begin on a 4-byte boundary
1660 //
1661 ParsedLength = GetOccupiedSize (ParsedLength, 4);
1662 }
1663
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;
1667 }
1668
1669
1670 return EFI_SUCCESS;
1671 }
1672
1673 /**
1674
1675 Iterates through the files contained within the firmware volume
1676
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
1680 subsequent files.
1681 @param[in] File- Output file pointer
1682 File == NULL - invalid parameter
1683 otherwise - *File will be update to the location of the file
1684
1685 @return EFI_STATUS
1686 EFI_NOT_FOUND
1687 EFI_VOLUME_CORRUPTED
1688
1689 **/
1690 EFI_STATUS
1691 FvBufFindNextFile (
1692 IN VOID *Fv,
1693 IN OUT UINTN *Key,
1694 OUT VOID **File
1695 )
1696 {
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;
1701 UINTN fsize;
1702 EFI_STATUS Status;
1703 UINTN fvSize;
1704
1705 hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
1706 fhdr = NULL;
1707
1708 if (Fv == NULL) {
1709 return EFI_INVALID_PARAMETER;
1710 }
1711
1712 Status = FvBufGetSize (Fv, &fvSize);
1713 if (EFI_ERROR (Status)) {
1714 return Status;
1715 }
1716
1717 if (*Key == 0) {
1718 if (hdr->ExtHeaderOffset != 0) {
1719 //
1720 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
1721 //
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);
1725 } else {
1726 *Key = hdr->HeaderLength;
1727 }
1728 }
1729
1730 FvbAttributes = hdr->Attributes;
1731
1732 for(
1733 *Key = (UINTN)ALIGN_POINTER (*Key, 8);
1734 (*Key + sizeof (*fhdr)) < fvSize;
1735 *Key = (UINTN)ALIGN_POINTER (*Key, 8)
1736 ) {
1737 fhdr = (EFI_FFS_FILE_HEADER*) ((UINT8*)hdr + *Key);
1738 fsize = GetFfsFileLength (fhdr);
1739 if (!EFI_TEST_FFS_ATTRIBUTES_BIT(
1740 FvbAttributes,
1741 fhdr->State,
1742 EFI_FILE_HEADER_VALID
1743 ) ||
1744 EFI_TEST_FFS_ATTRIBUTES_BIT(
1745 FvbAttributes,
1746 fhdr->State,
1747 EFI_FILE_HEADER_INVALID
1748 )
1749 ) {
1750 *Key = *Key + 1;
1751 continue;
1752 } else if(
1753 EFI_TEST_FFS_ATTRIBUTES_BIT(
1754 FvbAttributes,
1755 fhdr->State,
1756 EFI_FILE_MARKED_FOR_UPDATE
1757 ) ||
1758 EFI_TEST_FFS_ATTRIBUTES_BIT(
1759 FvbAttributes,
1760 fhdr->State,
1761 EFI_FILE_DELETED
1762 )
1763 ) {
1764 *Key = *Key + fsize;
1765 continue;
1766 } else if (EFI_TEST_FFS_ATTRIBUTES_BIT(
1767 FvbAttributes,
1768 fhdr->State,
1769 EFI_FILE_DATA_VALID
1770 )
1771 ) {
1772 *File = (UINT8*)hdr + *Key;
1773 *Key = *Key + fsize;
1774 return EFI_SUCCESS;
1775 }
1776
1777 *Key = *Key + 1;
1778 }
1779
1780 return EFI_NOT_FOUND;
1781 }
1782
1783 /**
1784
1785 TODO: Add function description
1786
1787 FvImage - TODO: add argument description
1788 FileHeader - TODO: add argument description
1789 ErasePolarity - TODO: add argument description
1790
1791 EFI_SUCCESS - TODO: Add description for return value
1792 EFI_ABORTED - TODO: Add description for return value
1793
1794 **/
1795 EFI_STATUS
1796 LibGetFileInfo (
1797 EFI_FIRMWARE_VOLUME_HEADER *FvImage,
1798 EFI_FFS_FILE_HEADER2 *CurrentFile,
1799 BOOLEAN ErasePolarity,
1800 FV_INFORMATION *CurrentFv,
1801 CHAR8 *FvName,
1802 UINT8 Level,
1803 ENCAP_INFO_DATA **CurrentFvEncapData,
1804 UINT32 *FfsCount,
1805 UINT8 *FvCount,
1806 BOOLEAN ViewFlag
1807 )
1808 {
1809 UINT32 FileLength;
1810 UINT8 FileState;
1811 UINT8 Checksum;
1812 EFI_FFS_FILE_HEADER2 BlankHeader;
1813 EFI_STATUS Status;
1814 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
1815 ENCAP_INFO_DATA *LocalEncapData;
1816 BOOLEAN EncapDataNeedUpdateFlag;
1817 BOOLEAN IsGeneratedFfs;
1818 UINT32 FfsFileHeaderSize;
1819
1820 Status = EFI_SUCCESS;
1821
1822 LocalEncapData = NULL;
1823 EncapDataNeedUpdateFlag = TRUE;
1824 IsGeneratedFfs = FALSE;
1825
1826 FfsFileHeaderSize = GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile);
1827 FileLength = GetFfsFileLength ((EFI_FFS_FILE_HEADER *) CurrentFile);
1828
1829 //
1830 // Check if we have free space
1831 //
1832 if (ErasePolarity) {
1833 memset (&BlankHeader, -1, FfsFileHeaderSize);
1834 } else {
1835 memset (&BlankHeader, 0, FfsFileHeaderSize);
1836 }
1837
1838 //
1839 // Is this FV blank?
1840 //
1841 if (memcmp (&BlankHeader, CurrentFile, FfsFileHeaderSize) == 0) {
1842 return EFI_SUCCESS;
1843 }
1844
1845 //
1846 // Print file information.
1847 //
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) {
1851 //
1852 // Calculate header checksum
1853 //
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);
1859 return EFI_ABORTED;
1860 }
1861
1862 if (CurrentFile->Attributes & FFS_ATTRIB_CHECKSUM) {
1863 //
1864 // Calculate file checksum
1865 //
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);
1870 return EFI_ABORTED;
1871 }
1872 } else {
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);
1875 return EFI_ABORTED;
1876 }
1877 }
1878 } else {
1879 Error ("FMMT", 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);
1880 return EFI_ABORTED;
1881 }
1882
1883 Level += 1;
1884
1885 if ((CurrentFile->Type != EFI_FV_FILETYPE_ALL) && (CurrentFile->Type != EFI_FV_FILETYPE_FFS_PAD)) {
1886
1887 //
1888 // Put in encapsulate data information.
1889 //
1890 LocalEncapData = *CurrentFvEncapData;
1891 if (LocalEncapData->NextNode != NULL) {
1892 LocalEncapData = LocalEncapData->NextNode;
1893 EncapDataNeedUpdateFlag = FALSE;
1894 while (LocalEncapData->RightNode != NULL) {
1895 LocalEncapData = LocalEncapData->RightNode;
1896 }
1897 }
1898
1899 if (EncapDataNeedUpdateFlag) {
1900 //
1901 // Construct the new ENCAP_DATA
1902 //
1903 LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));
1904
1905 if (LocalEncapData->NextNode == NULL) {
1906 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1907 return EFI_ABORTED;
1908 }
1909
1910 LocalEncapData = LocalEncapData->NextNode;
1911
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;
1918 //
1919 // Store the header of FFS file.
1920 //
1921 LocalEncapData->Data = malloc (FfsFileHeaderSize);
1922 if (LocalEncapData->Data == NULL) {
1923 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1924 return EFI_ABORTED;
1925 }
1926
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);
1931 return EFI_ABORTED;
1932 }
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;
1946 }else{
1947 //
1948 // Construct the new ENCAP_DATA
1949 //
1950 LocalEncapData->RightNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));
1951
1952 if (LocalEncapData->RightNode == NULL) {
1953 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1954 return EFI_ABORTED;
1955 }
1956
1957 LocalEncapData = LocalEncapData->RightNode;
1958
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;
1965 //
1966 // Store the header of FFS file.
1967 //
1968 LocalEncapData->Data = malloc (FfsFileHeaderSize);
1969 if (LocalEncapData->Data == NULL) {
1970 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
1971 return EFI_ABORTED;
1972 }
1973
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);
1978 return EFI_ABORTED;
1979 }
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;
1993 }
1994
1995 if ( CurrentFile->Type == EFI_FV_FILETYPE_RAW){
1996 CurrentFv->FfsAttuibutes[*FfsCount].Level = Level;
1997 if (!ViewFlag){
1998 LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
1999 }
2000 } else if( CurrentFile->Type == EFI_FV_FILETYPE_FFS_PAD){
2001 //EFI_FV_FILETYPE_FFS_PAD
2002 } else {
2003 //
2004 // All other files have sections
2005 //
2006 Status = LibParseSection (
2007 (UINT8 *) ((UINTN) CurrentFile + FfsFileHeaderSize),
2008 FileLength - FfsFileHeaderSize,
2009 CurrentFv,
2010 FvName,
2011 CurrentFile,
2012 Level,
2013 &LocalEncapData,
2014 Level,
2015 FfsCount,
2016 FvCount,
2017 ViewFlag,
2018 ErasePolarity,
2019 &IsGeneratedFfs
2020 );
2021 }
2022 if (EFI_ERROR (Status)) {
2023 printf ("ERROR: Parsing the FFS file.\n");
2024 return Status;
2025 }
2026 }
2027
2028
2029 return EFI_SUCCESS;
2030 }
2031
2032 /**
2033
2034 Get firmware information. Including the FV headers,
2035
2036 @param[in] Fv - Firmware Volume to get information from
2037
2038 @return EFI_STATUS
2039
2040 **/
2041 EFI_STATUS
2042 LibGetFvInfo (
2043 IN VOID *Fv,
2044 IN OUT FV_INFORMATION *CurrentFv,
2045 IN CHAR8 *FvName,
2046 IN UINT8 Level,
2047 IN ENCAP_INFO_DATA **CurrentFvEncapData,
2048 IN UINT32 *FfsCount,
2049 IN OUT UINT8 *FvCount,
2050 IN BOOLEAN ViewFlag,
2051 IN BOOLEAN IsChildFv
2052 )
2053 {
2054 EFI_STATUS Status;
2055 UINTN NumberOfFiles;
2056 BOOLEAN ErasePolarity;
2057 UINTN FvSize;
2058 EFI_FFS_FILE_HEADER2 *CurrentFile;
2059 UINTN Key;
2060 ENCAP_INFO_DATA *LocalEncapData;
2061 EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHdrPtr;
2062 EFI_FIRMWARE_VOLUME_HEADER *FvHdr;
2063
2064 NumberOfFiles = 0;
2065 Key = 0;
2066 LocalEncapData = NULL;
2067 CurrentFile = NULL;
2068 FvHdr = (EFI_FIRMWARE_VOLUME_HEADER *)Fv;
2069
2070
2071 Level += 1;
2072 *FvCount += 1;
2073 CurrentFv->FvLevel += 1;
2074
2075 Status = FvBufGetSize (Fv, &FvSize);
2076
2077 ErasePolarity = (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ? TRUE : FALSE;
2078
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");
2082 return EFI_ABORTED;
2083 }
2084
2085 if (!IsChildFv) {
2086 //
2087 // Write FV header information into CurrentFv struct.
2088 //
2089 CurrentFv->FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) malloc (FvHdr->HeaderLength);
2090
2091 if (CurrentFv->FvHeader == NULL) {
2092 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2093 return EFI_ABORTED;
2094 }
2095
2096 //
2097 // Get the FV Header information
2098 //
2099 memcpy(CurrentFv->FvHeader, Fv, FvHdr->HeaderLength);
2100 CurrentFv->FvExtHeader = NULL;
2101 CurrentFv->FvUiName = NULL;
2102
2103 //
2104 // Exist Extend FV header.
2105 //
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);
2109
2110 if (CurrentFv->FvExtHeader == NULL) {
2111 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2112 return EFI_ABORTED;
2113 }
2114
2115 //
2116 // Get the FV extended Header information
2117 //
2118 memcpy (CurrentFv->FvExtHeader, (VOID *)((UINTN)Fv + CurrentFv->FvHeader->ExtHeaderOffset), ExtHdrPtr->ExtHeaderSize);
2119 LibExtractFvUiName(CurrentFv->FvExtHeader, &CurrentFv->FvUiName);
2120 }
2121 }
2122
2123 //
2124 // Put encapsulate information into structure.
2125 //
2126 LocalEncapData = *CurrentFvEncapData;
2127 if (LocalEncapData == NULL && !IsChildFv) {
2128 //
2129 // First time in, the root FV
2130 //
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);
2135 return EFI_ABORTED;
2136 }
2137
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;
2146
2147 if (CurrentFv->EncapData->Data == NULL) {
2148 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2149 return EFI_ABORTED;
2150 }
2151
2152 memcpy (CurrentFv->EncapData->Data, Fv, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
2153
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);
2157
2158 if (CurrentFv->EncapData->FvExtHeader == NULL) {
2159 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2160 return EFI_ABORTED;
2161 }
2162
2163 //
2164 // Get the FV extended Header information
2165 //
2166 memcpy(CurrentFv->EncapData->FvExtHeader, (VOID *)((UINTN)Fv + ((EFI_FIRMWARE_VOLUME_HEADER *)(CurrentFv->EncapData->Data))->ExtHeaderOffset), ExtHdrPtr->ExtHeaderSize);
2167 }
2168
2169 CurrentFv->EncapData->NextNode = NULL;
2170 CurrentFv->EncapData->RightNode = NULL;
2171 } else if (LocalEncapData == NULL) {
2172 return EFI_ABORTED;
2173 } else if (IsChildFv) {
2174
2175 LocalEncapData = *CurrentFvEncapData;
2176 while (LocalEncapData->NextNode != NULL) {
2177 LocalEncapData = LocalEncapData->NextNode;
2178 }
2179
2180 //
2181 // Construct the new ENCAP_DATA
2182 //
2183 LocalEncapData->NextNode = (ENCAP_INFO_DATA *) malloc (sizeof (ENCAP_INFO_DATA));
2184
2185 if (LocalEncapData->NextNode == NULL) {
2186 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2187 return EFI_ABORTED;
2188 }
2189
2190 LocalEncapData = LocalEncapData->NextNode;
2191
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);
2202 return EFI_ABORTED;
2203 }
2204
2205 memcpy (LocalEncapData->Data, Fv, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
2206
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);
2210
2211 if (LocalEncapData->FvExtHeader == NULL) {
2212 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2213 return EFI_ABORTED;
2214 }
2215
2216 //
2217 // Get the FV extended Header information
2218 //
2219 memcpy(LocalEncapData->FvExtHeader, (VOID *)((UINTN)Fv + ((EFI_FIRMWARE_VOLUME_HEADER *)(LocalEncapData->Data))->ExtHeaderOffset), ExtHdrPtr->ExtHeaderSize);
2220 }
2221
2222 LocalEncapData->NextNode = NULL;
2223 LocalEncapData->RightNode = NULL;
2224
2225 }
2226
2227
2228 //
2229 // Get the first file
2230 //
2231 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
2232 if (Status == EFI_NOT_FOUND) {
2233 CurrentFile = NULL;
2234 } else if (EFI_ERROR (Status)) {
2235 Error ("FMMT", 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
2236 return Status;
2237 }
2238
2239 while (CurrentFile != NULL) {
2240
2241 //
2242 // Increment the number of files counter
2243 //
2244 NumberOfFiles++;
2245
2246 //
2247 // Store FFS file Header information
2248 //
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);
2259
2260 CurrentFv->FfsAttuibutes[*FfsCount].FvLevel = CurrentFv->FvLevel;
2261 if (CurrentFv->FvLevel > CurrentFv->MulFvLevel) {
2262 CurrentFv->MulFvLevel = CurrentFv->FvLevel;
2263 }
2264 //
2265 // Display info about this file
2266 //
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");
2270 return Status;
2271 }
2272
2273 //
2274 // Get the next file
2275 //
2276 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
2277 if (Status == EFI_NOT_FOUND) {
2278 CurrentFile = NULL;
2279 } else if (EFI_ERROR (Status)) {
2280 Error ("FMMT", 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
2281 return Status;
2282 }
2283 }
2284
2285 if (IsChildFv) {
2286 if (CurrentFv->FvLevel > 1) {
2287 CurrentFv->FvLevel -= 1;
2288 }
2289 }
2290 return EFI_SUCCESS;
2291 }
2292
2293 /**
2294
2295 This function returns the next larger size that meets the alignment
2296 requirement specified.
2297
2298 @param[in] ActualSize The size.
2299 @param[in] Alignment The desired alignment.
2300
2301 @retval EFI_SUCCESS Function completed successfully.
2302 @retval EFI_ABORTED The function encountered an error.
2303
2304 **/
2305 UINT32
2306 GetOccupiedSize (
2307 IN UINT32 ActualSize,
2308 IN UINT32 Alignment
2309 )
2310 {
2311 UINT32 OccupiedSize;
2312
2313 OccupiedSize = ActualSize;
2314 while ((OccupiedSize & (Alignment - 1)) != 0) {
2315 OccupiedSize++;
2316 }
2317
2318 return OccupiedSize;
2319 }
2320
2321
2322
2323 EFI_STATUS
2324 LibDeleteAndRenameFfs(
2325 IN CHAR8* DeleteFile,
2326 IN CHAR8* NewFile
2327 )
2328 {
2329 CHAR8* SystemCommand;
2330 CHAR8* TemDir;
2331 SystemCommand = NULL;
2332
2333 if (DeleteFile == NULL ||
2334 NewFile == NULL) {
2335 return EFI_INVALID_PARAMETER;
2336 }
2337
2338 //
2339 // Delete the file of the specified extract FFS file.
2340 //
2341 SystemCommand = malloc (
2342 strlen (DEL_STR) +
2343 strlen (DeleteFile) +
2344 1
2345 );
2346 if (SystemCommand == NULL) {
2347 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2348 return EFI_ABORTED;
2349 }
2350
2351 sprintf (
2352 SystemCommand,
2353 DEL_STR,
2354 DeleteFile
2355 );
2356
2357 if (system (SystemCommand) != EFI_SUCCESS) {
2358 free(SystemCommand);
2359 return EFI_ABORTED;
2360 }
2361 free(SystemCommand);
2362
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.", "");
2366 return EFI_ABORTED;
2367 }
2368 strncat (TemDir, OS_SEP_STR, _MAX_PATH - strlen(TemDir) - 1);
2369 strncat (TemDir, TEMP_DIR_NAME, _MAX_PATH - strlen(TemDir) - 1);
2370
2371 mkdir(TemDir, S_IRWXU | S_IRWXG | S_IRWXO);
2372 //
2373 // Create a copy the new file.
2374 //
2375
2376 SystemCommand = malloc (
2377 strlen (COPY_STR) +
2378 strlen (NewFile) +
2379 strlen (DeleteFile) +
2380 1
2381 );
2382 if (SystemCommand == NULL) {
2383 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2384 return EFI_ABORTED;
2385 }
2386
2387 sprintf (
2388 SystemCommand,
2389 COPY_STR,
2390 NewFile,
2391 DeleteFile
2392 );
2393
2394 if (system (SystemCommand) != EFI_SUCCESS) {
2395 free(SystemCommand);
2396 return EFI_ABORTED;
2397 }
2398 free(SystemCommand);
2399
2400 return EFI_SUCCESS;
2401
2402 }
2403
2404 /**
2405 Converts ASCII characters to Unicode.
2406 Assumes that the Unicode characters are only these defined in the ASCII set.
2407
2408 String - Pointer to string that is written to FILE.
2409 UniString - Pointer to unicode string
2410
2411 The address to the ASCII string - same as AsciiStr.
2412
2413 **/
2414 VOID
2415 LibAscii2Unicode (
2416 IN CHAR8 *String,
2417 OUT CHAR16 *UniString
2418 )
2419 {
2420 while (*String != '\0') {
2421 *(UniString++) = (CHAR16) *(String++);
2422 }
2423 //
2424 // End the UniString with a NULL.
2425 //
2426 *UniString = '\0';
2427 }
2428
2429
2430 EFI_STATUS
2431 LibCreateGuidedSectionOriginalData(
2432 IN CHAR8* FileIn,
2433 IN CHAR8* ToolName,
2434 IN CHAR8* FileOut
2435 )
2436 {
2437 CHAR8* SystemCommandFormatString;
2438 CHAR8* SystemCommand;
2439
2440 SystemCommandFormatString = NULL;
2441 SystemCommand = NULL;
2442
2443 if (FileIn == NULL ||
2444 ToolName == NULL ||
2445 FileOut == NULL) {
2446 return EFI_INVALID_PARAMETER;
2447 }
2448
2449 //
2450 // Delete the file of the specified extract FFS file.
2451 //
2452 SystemCommandFormatString = "%s -e \"%s\" -o \"%s\"";
2453
2454 SystemCommand = malloc (
2455 strlen (SystemCommandFormatString) +
2456 strlen (FileIn) +
2457 strlen (ToolName) +
2458 strlen (FileOut) +
2459 1
2460 );
2461 if (SystemCommand == NULL) {
2462 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2463 return EFI_ABORTED;
2464 }
2465
2466 sprintf (
2467 SystemCommand,
2468 "%s -e \"%s\" -o \"%s\"",
2469 ToolName,
2470 FileIn,
2471 FileOut
2472 );
2473
2474 if (system (SystemCommand) != EFI_SUCCESS) {
2475 printf("Command failed: %s\n", SystemCommand);
2476 free(SystemCommand);
2477 return EFI_ABORTED;
2478 }
2479 free(SystemCommand);
2480
2481 return EFI_SUCCESS;
2482 }
2483
2484 /**
2485
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.
2488
2489 @param[in] Attr FV header's attribute.
2490 @param[out] InfFile InfFile contain FV header attribute information.
2491
2492 @retval EFI_SUCCESS.
2493 @retval EFI_INVLID_PARAMETER
2494 @retval EFI_OUT_OF_RESOURCES
2495
2496 **/
2497 EFI_STATUS
2498 LibFvHeaderAttributeToStr (
2499 IN EFI_FVB_ATTRIBUTES_2 Attr,
2500 IN FILE* InfFile
2501 )
2502 {
2503 CHAR8 *LocalStr;
2504
2505 LocalStr = NULL;
2506
2507 LocalStr = (CHAR8 *) malloc (1024 * 4);
2508
2509 if (LocalStr == NULL) {
2510 printf ("Memory allocate error!\n");
2511 return EFI_OUT_OF_RESOURCES;
2512 }
2513
2514 memset (LocalStr, '\0', 1024 * 4);
2515
2516 if (Attr == 0 || InfFile == NULL) {
2517 free (LocalStr);
2518 return EFI_INVALID_PARAMETER;
2519 }
2520
2521 strncat (LocalStr, "[attributes] \n", sizeof("[attributes] \n"));
2522
2523 if (Attr & EFI_FVB2_READ_DISABLED_CAP) {
2524 strncat (LocalStr, "EFI_READ_DISABLED_CAP = TRUE \n", sizeof ("EFI_READ_DISABLED_CAP = TRUE \n"));
2525 }
2526
2527 if (Attr & EFI_FVB2_READ_ENABLED_CAP) {
2528 strncat (LocalStr, "EFI_READ_ENABLED_CAP = TRUE \n", sizeof ("EFI_READ_ENABLED_CAP = TRUE \n"));
2529 }
2530
2531 if (Attr & EFI_FVB2_READ_STATUS) {
2532 strncat (LocalStr, "EFI_READ_STATUS = TRUE \n", sizeof ("EFI_READ_STATUS = TRUE \n"));
2533 }
2534
2535 if (Attr & EFI_FVB2_WRITE_DISABLED_CAP) {
2536 strncat (LocalStr, "EFI_WRITE_DISABLED_CAP = TRUE \n", sizeof ("EFI_WRITE_DISABLED_CAP = TRUE \n"));
2537 }
2538
2539 if (Attr & EFI_FVB2_WRITE_ENABLED_CAP) {
2540 strncat (LocalStr, "EFI_WRITE_ENABLED_CAP = TRUE \n", sizeof ("EFI_WRITE_ENABLED_CAP = TRUE \n"));
2541 }
2542
2543 if (Attr & EFI_FVB2_WRITE_STATUS) {
2544 strncat (LocalStr, "EFI_WRITE_STATUS = TRUE \n", sizeof ("EFI_WRITE_STATUS = TRUE \n"));
2545 }
2546
2547 if (Attr & EFI_FVB2_LOCK_CAP) {
2548 strncat (LocalStr, "EFI_LOCK_CAP = TRUE \n", sizeof ("EFI_LOCK_CAP = TRUE \n"));
2549 }
2550
2551 if (Attr & EFI_FVB2_LOCK_STATUS) {
2552 strncat (LocalStr, "EFI_LOCK_STATUS = TRUE \n", sizeof ("EFI_LOCK_STATUS = TRUE \n"));
2553 }
2554
2555 if (Attr & EFI_FVB2_STICKY_WRITE) {
2556 strncat (LocalStr, "EFI_STICKY_WRITE = TRUE \n", sizeof ("EFI_STICKY_WRITE = TRUE \n"));
2557 }
2558
2559 if (Attr & EFI_FVB2_MEMORY_MAPPED) {
2560 strncat (LocalStr, "EFI_MEMORY_MAPPED = TRUE \n", sizeof ("EFI_MEMORY_MAPPED = TRUE \n"));
2561 }
2562
2563 if (Attr & EFI_FVB2_ERASE_POLARITY) {
2564 strncat (LocalStr, "EFI_ERASE_POLARITY = 1 \n", sizeof ("EFI_ERASE_POLARITY = 1 \n"));
2565 }
2566
2567 if (Attr & EFI_FVB2_READ_LOCK_CAP) {
2568 strncat (LocalStr, "EFI_READ_LOCK_CAP = TRUE \n", sizeof ("EFI_READ_LOCK_CAP = TRUE \n"));
2569 }
2570
2571 if (Attr & EFI_FVB2_READ_LOCK_STATUS) {
2572 strncat (LocalStr, "EFI_READ_LOCK_STATUS = TRUE \n", sizeof ("EFI_READ_LOCK_STATUS = TRUE \n"));
2573 }
2574
2575 if (Attr & EFI_FVB2_WRITE_LOCK_CAP) {
2576 strncat (LocalStr, "EFI_WRITE_LOCK_CAP = TRUE \n", sizeof ("EFI_WRITE_LOCK_CAP = TRUE \n"));
2577 }
2578
2579 if (Attr & EFI_FVB2_WRITE_LOCK_STATUS) {
2580 strncat (LocalStr, "EFI_WRITE_LOCK_STATUS = TRUE \n", sizeof ("EFI_WRITE_LOCK_STATUS = TRUE \n"));
2581 }
2582
2583 if (Attr & EFI_FVB2_LOCK_STATUS) {
2584 strncat (LocalStr, "EFI_READ_LOCK_STATUS = TRUE \n", sizeof ("EFI_READ_LOCK_STATUS = TRUE \n"));
2585 }
2586
2587 //
2588 // Alignment
2589 //
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"));
2654 }
2655
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);
2658 free (LocalStr);
2659 return EFI_ABORTED;
2660 }
2661
2662 free (LocalStr);
2663
2664 return EFI_SUCCESS;
2665 }
2666
2667
2668 /**
2669 This function fill the FV inf files option field.
2670
2671 @param[in] BlockMap FV header's attribute.
2672 @param[out] InfFile InfFile contain FV header attribute information.
2673
2674 @retval EFI_SUCCESS.
2675 @retval EFI_INVLID_PARAMETER
2676
2677 **/
2678 EFI_STATUS
2679 LibFvHeaderOptionToStr (
2680 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
2681 IN FILE* InfFile,
2682 IN BOOLEAN IsRootFv
2683 )
2684 {
2685 CHAR8 *LocalStr;
2686 CHAR8 *TempStr;
2687 EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
2688
2689 LocalStr = NULL;
2690 TempStr = NULL;
2691
2692 if (FvHeader == NULL || InfFile == NULL) {
2693 return EFI_INVALID_PARAMETER;
2694 }
2695
2696 //
2697 // This section will not over 1024 bytes and each line will never over 128 bytes.
2698 //
2699 LocalStr = (CHAR8 *) malloc (1024);
2700 TempStr = (CHAR8 *) malloc (128);
2701
2702 if (LocalStr == NULL ||
2703 TempStr == NULL ) {
2704 if (LocalStr != NULL) {
2705 free (LocalStr);
2706 }
2707 if (TempStr != NULL) {
2708 free (TempStr);
2709 }
2710 printf ("Memory allocate error! \n");
2711 return EFI_OUT_OF_RESOURCES;
2712 }
2713
2714 BlockMap = FvHeader->BlockMap;
2715 memset (LocalStr, '\0', 1024);
2716 memset (TempStr, '\0', 128);
2717
2718 strncat (LocalStr, "[options] \n", sizeof("[Options] \n"));
2719
2720
2721 snprintf (TempStr, 128, "EFI_BLOCK_SIZE = 0x%x \n", BlockMap->Length);
2722 strncat (LocalStr, TempStr, strlen(TempStr));
2723
2724 if (IsRootFv) {
2725 snprintf (TempStr, 128, "EFI_NUM_BLOCKS = 0x%x \n", BlockMap->NumBlocks);
2726 strncat (LocalStr, TempStr, strlen(TempStr));
2727 }
2728
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);
2731 free (LocalStr);
2732 free (TempStr);
2733 return EFI_ABORTED;
2734 }
2735
2736 free (LocalStr);
2737 free (TempStr);
2738
2739 return EFI_SUCCESS;
2740 }
2741
2742 /**
2743 This function fill the FV inf files option field.
2744
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.
2748
2749 @retval EFI_SUCCESS.
2750 @retval EFI_INVLID_PARAMETER
2751
2752 **/
2753 EFI_STATUS
2754 LibAddFfsFileToFvInf (
2755 IN CHAR8 *FfsName,
2756 IN FILE* InfFile,
2757 IN BOOLEAN FirstIn
2758 )
2759 {
2760
2761 CHAR8 *LocalStr;
2762
2763 LocalStr = NULL;
2764
2765 if (FfsName == NULL || InfFile == NULL) {
2766 return EFI_INVALID_PARAMETER;
2767 }
2768
2769 if (strlen(FfsName) == 0) {
2770 return EFI_SUCCESS;
2771 }
2772
2773 LocalStr = (CHAR8 *) malloc (_MAX_PATH);
2774
2775 if (LocalStr == NULL) {
2776 printf ("Memory allocate error! \n");
2777 return EFI_OUT_OF_RESOURCES;
2778 }
2779
2780 memset (LocalStr, '\0', _MAX_PATH);
2781
2782 if (FirstIn) {
2783 sprintf (LocalStr, "[files] \nEFI_FILE_NAME = %s \n", FfsName);
2784 } else {
2785 sprintf (LocalStr, "EFI_FILE_NAME = %s \n", FfsName);
2786 }
2787
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);
2790 free (LocalStr);
2791 return EFI_ABORTED;
2792 }
2793
2794 free (LocalStr);
2795
2796 return EFI_SUCCESS;
2797 }
2798
2799
2800 /**
2801 Convert EFI file to PE or TE section
2802
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.
2810
2811 @retval EFI_SUCCESS
2812
2813 **/
2814 EFI_STATUS
2815 LibCreateFfsSection (
2816 IN FV_INFORMATION *FvInFd, OPTIONAL
2817 IN CHAR8* InputFilePath, OPTIONAL
2818 IN CHAR8* Sections, OPTIONAL
2819 IN UINT8 Type,
2820 IN CHAR8* OutputFilePath,
2821 IN CHAR8* UiString, OPTIONAL
2822 IN CHAR8* VerString, OPTIONAL
2823 IN CHAR8* GuidToolGuid, OPTIONAL
2824 IN UINT16 GuidHeaderLength,
2825 IN UINT16 GuidAttr,
2826 IN CHAR8* CompressType OPTIONAL
2827 )
2828 {
2829 //EFI_STATUS Status;
2830 CHAR8* SystemCommandFormatString;
2831 CHAR8* SystemCommand;
2832 FILE *file;
2833 UINT8 Buffer[4];
2834 int BitNum;
2835 int Position;
2836 UINT32 AlignmentValue;
2837 //
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.
2841 //
2842 char AlignmentStr[16];
2843
2844 SystemCommandFormatString = NULL;
2845 SystemCommand = NULL;
2846 strcpy(AlignmentStr,"1");
2847 //
2848 // Call GenSec tool to generate FFS section.
2849 //
2850
2851 //
2852 // -s SectionType.
2853 //
2854 if (Type != 0) {
2855 switch (Type) {
2856 //
2857 // Process compression section
2858 //
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) +
2867 1
2868 );
2869 if (SystemCommand == NULL) {
2870 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2871 return EFI_ABORTED;
2872 }
2873 sprintf (
2874 SystemCommand,
2875 "GenSec -s %s -c %s \"%s\" -o \"%s\"",
2876 mSectionTypeName[Type],
2877 CompressType,
2878 InputFilePath,
2879 OutputFilePath
2880 );
2881
2882 if (system (SystemCommand) != EFI_SUCCESS) {
2883 free(SystemCommand);
2884 return EFI_ABORTED;
2885 }
2886 free(SystemCommand);
2887 break;
2888
2889 //
2890 // Process GUID defined section
2891 //
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]) +
2902 4 +
2903 1
2904 );
2905 if (SystemCommand == NULL) {
2906 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2907 return EFI_ABORTED;
2908 }
2909 sprintf (
2910 SystemCommand,
2911 "GenSec -s %s -g %s \"%s\" -o \"%s\" -r %s -r %s -l %d",
2912 mSectionTypeName[Type],
2913 GuidToolGuid,
2914 InputFilePath,
2915 OutputFilePath,
2916 mGuidSectionAttr[GuidAttr&0x01],
2917 mGuidSectionAttr[GuidAttr&0x02],
2918 GuidHeaderLength
2919 );
2920
2921 if (system (SystemCommand) != EFI_SUCCESS) {
2922 free(SystemCommand);
2923 return EFI_ABORTED;
2924 }
2925 free(SystemCommand);
2926 break;
2927
2928 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
2929
2930 SystemCommandFormatString = "GenSec -s %s \"%s\" -o \"%s\"";
2931 SystemCommand = malloc (
2932 strlen (SystemCommandFormatString) +
2933 strlen (mSectionTypeName[Type]) +
2934 strlen (InputFilePath) +
2935 strlen (OutputFilePath) +
2936 1
2937 );
2938 if (SystemCommand == NULL) {
2939 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
2940 return EFI_ABORTED;
2941 }
2942 sprintf (
2943 SystemCommand,
2944 "GenSec -s %s \"%s\" -o \"%s\"",
2945 mSectionTypeName[Type],
2946 InputFilePath,
2947 OutputFilePath
2948 );
2949
2950 if (system (SystemCommand) != EFI_SUCCESS) {
2951 free(SystemCommand);
2952 return EFI_ABORTED;
2953 }
2954 free(SystemCommand);
2955 break;
2956
2957 default:
2958 Error ("FMMT", 0, 0003, "Please specify the section type while call GenSec tool.", NULL);
2959 return EFI_UNSUPPORTED;
2960 }
2961 } else {
2962 //
2963 // Create Dummy section.
2964 //
2965 file = fopen(InputFilePath, "rb");
2966 if (file == NULL) {
2967 Error(NULL, 0, 0001, "Error opening the file", InputFilePath);
2968 return EFI_INVALID_PARAMETER;
2969 }
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)) {
2972 fclose(file);
2973 return EFI_ABORTED;
2974 }
2975 if (*(Buffer + 3) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
2976 // The Section Struct, if size is not 0xFFFF, the length is 4
2977 Position = 4;
2978 // If Size is 0xFFFFFF then ExtendedSize contains the size of the section
2979 if ((*Buffer == 0xFF) && (*(Buffer + 1) == 0xFF) && (*(Buffer + 2) == 0xFF)) {
2980 Position = 8;
2981 }
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");
2989 }
2990 else{
2991 sprintf(AlignmentStr, "%d", AlignmentValue/0x400);
2992 strcat(AlignmentStr, "K");
2993 }
2994 }
2995 else{
2996 sprintf(AlignmentStr, "%d", AlignmentValue);
2997 }
2998 strcpy(FvInFd->AlignmentStr, AlignmentStr);
2999 }
3000 fclose(file);
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
3007 1
3008 );
3009 if (SystemCommand == NULL) {
3010 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3011 return EFI_ABORTED;
3012 }
3013 sprintf (
3014 SystemCommand,
3015 "GenSec \"%s\" -o \"%s\" --sectionalign %s",
3016 InputFilePath,
3017 OutputFilePath,
3018 AlignmentStr
3019 );
3020
3021 if (system (SystemCommand) != EFI_SUCCESS) {
3022 free(SystemCommand);
3023 return EFI_ABORTED;
3024 }
3025 free(SystemCommand);
3026
3027 }
3028
3029 return EFI_SUCCESS;
3030 }
3031
3032 /**
3033 Encapsulate FFSs to FV
3034
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
3039
3040 @retval EFI_SUCCESS
3041
3042 **/
3043 EFI_STATUS
3044 LibEncapsulateFfsToFv (
3045 IN CHAR8* InfFilePath,
3046 IN CHAR8* InputFFSs,
3047 IN CHAR8* OutputFilePath,
3048 IN CHAR8* FvGuidName,
3049 IN BOOLEAN IsLargeFile
3050 )
3051 {
3052
3053 CHAR8* SystemCommandFormatString;
3054 CHAR8* SystemCommand;
3055 CHAR8* FfsGuid = "8c8ce578-8a3d-4f1c-9935-896185c32dd3";
3056
3057 if (IsLargeFile == TRUE) {
3058 FfsGuid = "5473c07a-3dcb-4dca-bd6f-1e9689e7349a";
3059 }
3060
3061 SystemCommandFormatString = NULL;
3062 SystemCommand = NULL;
3063
3064 if (OutputFilePath == NULL ||
3065 InfFilePath == NULL ) {
3066 return EFI_INVALID_PARAMETER;
3067 }
3068
3069 if (InfFilePath != NULL) {
3070 if (FvGuidName == NULL) {
3071 SystemCommandFormatString = "GenFv -i \"%s\" -g %s -o \"%s\"";
3072
3073 SystemCommand = malloc (
3074 strlen (SystemCommandFormatString) +
3075 strlen (InfFilePath) +
3076 strlen (FfsGuid) +
3077 strlen (OutputFilePath) +
3078 1
3079 );
3080 if (SystemCommand == NULL) {
3081 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3082 return EFI_ABORTED;
3083 }
3084 sprintf (
3085 SystemCommand,
3086 "GenFv -i \"%s\" -g %s -o \"%s\"",
3087 InfFilePath, // -i
3088 FfsGuid, // -g
3089 OutputFilePath // -o
3090 );
3091
3092 if (system (SystemCommand) != EFI_SUCCESS) {
3093 free(SystemCommand);
3094 return EFI_ABORTED;
3095 }
3096
3097 free(SystemCommand);
3098 } else {
3099 //
3100 // Have FvGuidName in it.
3101 //
3102 SystemCommandFormatString = "GenFv -i \"%s\" -g %s -o \"%s\" --FvNameGuid %s";
3103
3104 SystemCommand = malloc (
3105 strlen (SystemCommandFormatString) +
3106 strlen (InfFilePath) +
3107 strlen (FfsGuid) +
3108 strlen (OutputFilePath) +
3109 strlen (FvGuidName) +
3110 1
3111 );
3112 if (SystemCommand == NULL) {
3113 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3114 return EFI_ABORTED;
3115 }
3116 sprintf (
3117 SystemCommand,
3118 "GenFv -i \"%s\" -g %s -o \"%s\" --FvNameGuid %s",
3119 InfFilePath, // -i
3120 FfsGuid, // -g
3121 OutputFilePath, // -o
3122 FvGuidName // FvNameGuid
3123 );
3124
3125 if (system (SystemCommand) != EFI_SUCCESS) {
3126 free(SystemCommand);
3127 return EFI_ABORTED;
3128 }
3129 free(SystemCommand);
3130
3131 }
3132 }
3133
3134 return EFI_SUCCESS;
3135 }
3136
3137
3138 /**
3139
3140 Convert a GUID to a string.
3141
3142
3143 @param[in] Guid - Pointer to GUID to print.
3144
3145
3146 @return The string after convert.
3147
3148 **/
3149 CHAR8 *
3150 LibFmmtGuidToStr (
3151 IN EFI_GUID *Guid
3152 )
3153 {
3154 CHAR8 * Buffer;
3155
3156 Buffer = NULL;
3157
3158 if (Guid == NULL) {
3159 printf ("The guid is NULL while convert guid to string! \n");
3160 return NULL;
3161 }
3162
3163 Buffer = (CHAR8 *) malloc (36 + 1);
3164
3165 if (Buffer == NULL) {
3166 printf ("Error while allocate resource! \n");
3167 return NULL;
3168 }
3169 memset (Buffer, '\0', 36 + 1);
3170
3171 sprintf (
3172 Buffer,
3173 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
3174 Guid->Data1,
3175 Guid->Data2,
3176 Guid->Data3,
3177 Guid->Data4[0],
3178 Guid->Data4[1],
3179 Guid->Data4[2],
3180 Guid->Data4[3],
3181 Guid->Data4[4],
3182 Guid->Data4[5],
3183 Guid->Data4[6],
3184 Guid->Data4[7]
3185 );
3186
3187 return Buffer;
3188 }
3189
3190
3191 /**
3192 Encapsulate an FFS section file to an FFS file.
3193
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.
3203
3204 @retval EFI_SUCCESS
3205
3206 **/
3207 EFI_STATUS
3208 LibEncapSectionFileToFFS (
3209 IN UINT8 Type,
3210 IN CHAR8* InputFilePath,
3211 IN CHAR8* OutputFilePath,
3212 IN EFI_GUID FileGuid,
3213 IN BOOLEAN Fixed,
3214 IN CHAR8* SectionAlign
3215 )
3216 {
3217 CHAR8* SystemCommandFormatString;
3218 CHAR8* SystemCommand;
3219 CHAR8* GuidStr;
3220
3221
3222 SystemCommandFormatString = NULL;
3223 SystemCommand = NULL;
3224 GuidStr = NULL;
3225
3226 GuidStr = LibFmmtGuidToStr(&FileGuid);
3227
3228 if (GuidStr == NULL) {
3229 return EFI_ABORTED;
3230 }
3231
3232
3233 //
3234 // -t Type
3235 // -i InputFilePath
3236 // -o OutPutFilePath
3237 // -g FileGuid
3238 // -x Fixed
3239 // -n SectionAlign
3240 //
3241
3242 if (Fixed) {
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) +
3248 strlen (GuidStr) +
3249 strlen (OutputFilePath) +
3250 4 +
3251 1
3252 );
3253 if (SystemCommand == NULL) {
3254 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3255 free (GuidStr);
3256 return EFI_ABORTED;
3257 }
3258 sprintf (
3259 SystemCommand,
3260 "GenFfs -t %s -i \"%s\" -g %s -x -o \"%s\" -a %s",
3261 mFfsFileType[Type], // -t
3262 InputFilePath, // -i
3263 GuidStr, // -g
3264 OutputFilePath, // -o
3265 SectionAlign
3266 );
3267
3268 free (GuidStr);
3269 if (system (SystemCommand) != EFI_SUCCESS) {
3270 free(SystemCommand);
3271 return EFI_ABORTED;
3272 }
3273 free(SystemCommand);
3274 } else {
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) +
3280 strlen (GuidStr) +
3281 strlen (OutputFilePath) +
3282 4 +
3283 1
3284 );
3285 if (SystemCommand == NULL) {
3286 free (GuidStr);
3287 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3288 return EFI_ABORTED;
3289 }
3290 sprintf (
3291 SystemCommand,
3292 "GenFfs -t %s -i \"%s\" -g %s -o \"%s\" -a %s",
3293 mFfsFileType[Type], // -t
3294 InputFilePath, // -i
3295 GuidStr, // -g
3296 OutputFilePath, // -o
3297 SectionAlign
3298 );
3299
3300 free (GuidStr);
3301 if (system (SystemCommand) != EFI_SUCCESS) {
3302 free(SystemCommand);
3303 return EFI_ABORTED;
3304 }
3305 free(SystemCommand);
3306 }
3307
3308
3309 return EFI_SUCCESS;
3310 }
3311
3312 EFI_STATUS
3313 LibCreateNewFdCopy(
3314 IN CHAR8* OldFd,
3315 IN CHAR8* NewFd
3316 )
3317 {
3318
3319 FILE* NewFdFile;
3320 FILE* OldFdFile;
3321 CHAR8 *NewFdDir;
3322 CHAR8 *OldFdDir;
3323 UINT64 FdLength;
3324 UINT32 Count;
3325 BOOLEAN UseNewDirFlag;
3326 CHAR8 *Buffer;
3327
3328 NewFdFile = NULL;
3329 OldFdFile = NULL;
3330 NewFdDir = NULL;
3331 OldFdDir = NULL;
3332 Count = 0;
3333 UseNewDirFlag = FALSE;
3334
3335 if (OldFd == NULL ||
3336 NewFd == NULL) {
3337 return EFI_INVALID_PARAMETER;
3338 }
3339
3340
3341 NewFdDir = getcwd (NULL, _MAX_PATH);
3342
3343 Count = strlen(NewFdDir);
3344
3345 if (strlen(NewFd) > Count) {
3346
3347 do {
3348 if (NewFdDir[Count-1] == NewFd[Count-1]) {
3349 Count--;
3350 } else {
3351 if (strlen(NewFdDir) + strlen (OS_SEP_STR) + strlen (NewFd) > _MAX_PATH -1) {
3352 return EFI_ABORTED;
3353 }
3354 strncat (NewFdDir,OS_SEP_STR, _MAX_PATH - strlen (NewFdDir) -1);
3355 strncat (NewFdDir,NewFd, _MAX_PATH - strlen (NewFdDir) -1);
3356 UseNewDirFlag = TRUE;
3357 break;
3358 }
3359
3360 } while (Count != 1);
3361
3362 }else {
3363 if (strlen(NewFdDir) + strlen (OS_SEP_STR) + strlen (NewFd) > _MAX_PATH -1) {
3364 return EFI_ABORTED;
3365 }
3366 strncat (NewFdDir,OS_SEP_STR, _MAX_PATH - strlen (NewFdDir) -1);
3367 strncat (NewFdDir,NewFd, _MAX_PATH - strlen (NewFdDir) -1);
3368 UseNewDirFlag = TRUE;
3369 }
3370
3371 if (UseNewDirFlag) {
3372 NewFdFile = fopen (NewFdDir, "wb+");
3373 if (NewFdFile == NULL) {
3374 NewFdFile = fopen (NewFd, "wb+");
3375 }
3376 } else {
3377 NewFdFile = fopen (NewFd, "wb+");
3378 }
3379 // support network path file
3380 if (OldFd[0] == '\\' && OldFd[1] == '\\') {
3381 OldFdFile = fopen (OldFd, "rb");
3382 } else {
3383 UseNewDirFlag = FALSE;
3384
3385 OldFdDir = getcwd (NULL, _MAX_PATH);
3386
3387 Count = strlen(OldFdDir);
3388
3389 if (strlen(OldFd) > Count) {
3390
3391 do {
3392 if (OldFdDir[Count-1] == OldFd[Count-1]) {
3393 Count--;
3394 } else {
3395 if (strlen(OldFdDir) + strlen (OS_SEP_STR) + strlen (OldFd) > _MAX_PATH -1) {
3396 if (NewFdFile != NULL) {
3397 fclose(NewFdFile);
3398 }
3399 return EFI_ABORTED;
3400 }
3401 strncat (OldFdDir,OS_SEP_STR, _MAX_PATH - strlen (OldFdDir) -1);
3402 strncat (OldFdDir,OldFd, _MAX_PATH - strlen (OldFdDir) -1);
3403 UseNewDirFlag = TRUE;
3404 break;
3405 }
3406
3407 } while (Count != 1);
3408
3409 }else {
3410 if (strlen(OldFdDir) + strlen (OS_SEP_STR) + strlen (OldFd) > _MAX_PATH -1) {
3411 if (NewFdFile != NULL) {
3412 fclose(NewFdFile);
3413 }
3414 return EFI_ABORTED;
3415 }
3416 strncat (OldFdDir,OS_SEP_STR, _MAX_PATH - strlen (OldFdDir) -1);
3417 strncat (OldFdDir,OldFd, _MAX_PATH - strlen (OldFdDir) -1);
3418 UseNewDirFlag = TRUE;
3419 }
3420
3421 if (UseNewDirFlag) {
3422 OldFdFile = fopen (OldFdDir, "rb+");
3423 if (OldFdFile == NULL) {
3424 OldFdFile = fopen (OldFd, "rb+");
3425 }
3426 } else {
3427 OldFdFile = fopen (OldFd, "rb+");
3428 }
3429 }
3430
3431 if (NewFdFile == NULL) {
3432 Error ("FMMT", 0, 0003, "error Open FD file", "cannot Create a new FD file.");
3433 if (OldFdFile != NULL) {
3434 fclose (OldFdFile);
3435 }
3436 return EFI_ABORTED;
3437 }
3438
3439 if (OldFdFile == NULL) {
3440 Error ("FMMT", 0, 0003, "error Open FD file", "cannot Create a new FD file.");
3441 if (NewFdFile != NULL) {
3442 fclose (NewFdFile);
3443 }
3444 return EFI_ABORTED;
3445 }
3446
3447
3448 fseek(OldFdFile,0,SEEK_SET);
3449 fseek(OldFdFile,0,SEEK_END);
3450
3451 FdLength = ftell(OldFdFile);
3452
3453 fseek(OldFdFile,0,SEEK_SET);
3454 fseek(NewFdFile,0,SEEK_SET);
3455
3456 Buffer = malloc ((size_t)FdLength);
3457
3458 if (Buffer == NULL) {
3459 fclose(OldFdFile);
3460 fclose(NewFdFile);
3461 return EFI_ABORTED;
3462 }
3463
3464 if (fread (Buffer, 1, (size_t) FdLength, OldFdFile) != (size_t) FdLength) {
3465 Error ("FMMT", 0, 0003, "error reading FD file %s", OldFd);
3466 free (Buffer);
3467 fclose(OldFdFile);
3468 fclose(NewFdFile);
3469 return EFI_ABORTED;
3470 }
3471
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.");
3474 free (Buffer);
3475 fclose(OldFdFile);
3476 fclose(NewFdFile);
3477 return EFI_ABORTED;
3478 }
3479 free (Buffer);
3480 fclose(OldFdFile);
3481 fclose (NewFdFile);
3482
3483 return EFI_SUCCESS;
3484 }
3485
3486
3487 /**
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:
3490 c:\temp\file1.txt.
3491
3492 @param[in]
3493 @param[in]
3494 @param[in]
3495
3496 @retrun A string contain all the input information.
3497
3498 **/
3499 CHAR8 *
3500 LibFilenameStrExtended (
3501 IN CHAR8 *FileName,
3502 IN CHAR8 *Dir,
3503 IN CHAR8 *Extend
3504 )
3505 {
3506 CHAR8 *RetStr;
3507
3508 RetStr = NULL;
3509
3510 if (FileName == NULL) {
3511 return NULL;
3512 }
3513
3514 if (Dir == NULL || Extend == NULL) {
3515 return FileName;
3516 }
3517
3518 RetStr = (CHAR8 *) malloc (strlen (FileName) +
3519 strlen (Dir) +
3520 strlen (Extend) +
3521 strlen ("%s%s.%s") +
3522 1);
3523 if (RetStr == NULL) {
3524 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3525 return NULL;
3526 }
3527
3528 memset (RetStr, '\0', (strlen (FileName) + strlen (Dir) + strlen (Extend) + strlen ("%s%s.%s") + 1));
3529
3530 sprintf (RetStr, "%s%s.%s", Dir, FileName, Extend);
3531
3532 return RetStr;
3533 }
3534
3535 /**
3536 Delete a directory and files in it.
3537
3538 @param[in] DirName Name of the directory need to be deleted.
3539
3540 @return EFI_INVALID_PARAMETER
3541 @return EFI_SUCCESS
3542 **/
3543 EFI_STATUS
3544 LibRmDir (
3545 IN CHAR8* DirName
3546 )
3547 {
3548 CHAR8* SystemCommand;
3549
3550 SystemCommand = NULL;
3551
3552
3553 if (DirName == NULL) {
3554 return EFI_INVALID_PARAMETER;
3555 }
3556
3557 if (access (DirName, 0) == -1){
3558 return EFI_SUCCESS;
3559 }
3560
3561 //
3562 // Delete a directory and files in it.
3563 //
3564
3565 SystemCommand = malloc (
3566 strlen (RMDIR_STR) +
3567 strlen (DirName) +
3568 1
3569 );
3570 if (SystemCommand == NULL) {
3571 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3572 return EFI_ABORTED;
3573 }
3574
3575 sprintf (
3576 SystemCommand,
3577 RMDIR_STR,
3578 DirName
3579 );
3580
3581 if (system (SystemCommand) != EFI_SUCCESS) {
3582 free(SystemCommand);
3583 return EFI_ABORTED;
3584 }
3585 free(SystemCommand);
3586
3587 return EFI_SUCCESS;
3588 }
3589
3590 EFI_STATUS
3591 LibGenExtFile(
3592 CONST EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtPtr,
3593 FILE *InfFile
3594 )
3595 {
3596 CHAR8 *TempDir;
3597 FILE *ExtFile;
3598 CHAR8 OutputExtFile[_MAX_PATH];
3599 CHAR8 Line[512];
3600 size_t Len;
3601
3602 TempDir = NULL;
3603
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.", "");
3607 return EFI_ABORTED;
3608 }
3609 strncat (TempDir, OS_SEP_STR, _MAX_PATH - strlen (TempDir) -1);
3610 strncat (TempDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TempDir) -1);
3611
3612 mkdir(TempDir, S_IRWXU | S_IRWXG | S_IRWXO);
3613
3614 sprintf(
3615 Line,
3616 "%c%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%d.ext",
3617 OS_SEP,
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
3630 );
3631 if (strlen (TempDir) + strlen (Line) > _MAX_PATH - 1) {
3632 Error("FMMT", 0, 1001, "The directory is too long.", "");
3633 return EFI_ABORTED;
3634 }
3635 strncpy (OutputExtFile, TempDir, _MAX_PATH - 1);
3636 OutputExtFile[_MAX_PATH - 1] = 0;
3637 strncat (OutputExtFile, Line, _MAX_PATH - strlen (OutputExtFile) - 1);
3638
3639
3640 ExtFile = fopen(OutputExtFile, "wb+");
3641 if (ExtFile == NULL) {
3642 return EFI_ABORTED;
3643 }
3644
3645 if (fwrite(ExtPtr, 1, ExtPtr->ExtHeaderSize, ExtFile) != ExtPtr->ExtHeaderSize) {
3646 fclose(ExtFile);
3647 return EFI_ABORTED;
3648 }
3649
3650 fclose(ExtFile);
3651
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.", "");
3655 return EFI_ABORTED;
3656 }
3657 strncat (Line, OutputExtFile, sizeof(Line) / sizeof (CHAR8) - strlen (Line) - 1);
3658 strncat (Line, "\n", sizeof(Line) / sizeof (CHAR8) - strlen (Line) - 1);
3659 Len = strlen(Line);
3660 if (fwrite(Line, 1, Len, InfFile) != Len) {
3661 return EFI_ABORTED;
3662 }
3663
3664 return EFI_SUCCESS;
3665 }
3666
3667 /**
3668 Delete a file.
3669
3670 @param[in] FileName Name of the file need to be deleted.
3671
3672 @return EFI_INVALID_PARAMETER
3673 @return EFI_SUCCESS
3674 **/
3675 EFI_STATUS
3676 LibFmmtDeleteFile(
3677 IN CHAR8 *FileName
3678 )
3679 {
3680 CHAR8* SystemCommand;
3681 CHAR8 *TemDir;
3682
3683 SystemCommand = NULL;
3684 TemDir = NULL;
3685
3686
3687 if (FileName == NULL) {
3688 return EFI_INVALID_PARAMETER;
3689 }
3690
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';
3695 }
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);
3698 return EFI_ABORTED;
3699 }
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) {
3703 return EFI_SUCCESS;
3704 }
3705
3706 //
3707 // Delete a file
3708 //
3709
3710 SystemCommand = malloc (
3711 strlen (DEL_STR) +
3712 strlen (FileName) +
3713 1
3714 );
3715 if (SystemCommand == NULL) {
3716 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
3717 return EFI_ABORTED;
3718 }
3719
3720 sprintf (
3721 SystemCommand,
3722 DEL_STR,
3723 FileName
3724 );
3725
3726 if (system (SystemCommand) != EFI_SUCCESS) {
3727 free(SystemCommand);
3728 return EFI_ABORTED;
3729 }
3730 free(SystemCommand);
3731
3732 return EFI_SUCCESS;
3733
3734 }
3735
3736
3737 /**
3738
3739 Free the whole Fd data structure.
3740
3741 @param[in] Fd The pointer point to the Fd data structure.
3742
3743 **/
3744 VOID
3745 LibFmmtFreeFd (
3746 FIRMWARE_DEVICE *Fd
3747 )
3748 {
3749 FV_INFORMATION *CurrentFv;
3750 FV_INFORMATION *TempFv;
3751 ENCAP_INFO_DATA *EncapData1;
3752 ENCAP_INFO_DATA *EncapData2;
3753
3754 CurrentFv = NULL;
3755 TempFv = NULL;
3756 EncapData1 = NULL;
3757 EncapData2 = NULL;
3758
3759 if (Fd == NULL) {
3760 return;
3761 }
3762
3763 CurrentFv = Fd->Fv;
3764
3765 do {
3766 TempFv = CurrentFv;
3767 CurrentFv = CurrentFv->FvNext;
3768
3769 free (TempFv->FvHeader);
3770
3771 if (TempFv->FvExtHeader != NULL) {
3772 free (TempFv->FvExtHeader);
3773 }
3774 if (TempFv->FvUiName) {
3775 free(TempFv->FvUiName);
3776 }
3777
3778 //
3779 // Free encapsulate data;
3780 //
3781 EncapData1 = TempFv->EncapData;
3782
3783 while (EncapData1 != NULL) {
3784
3785 EncapData2 = EncapData1;
3786 EncapData1 = EncapData1->NextNode;
3787
3788 if (EncapData2->Data != NULL) {
3789 free (EncapData2->Data);
3790 }
3791 if (EncapData2->FvExtHeader != NULL) {
3792 free(EncapData2->FvExtHeader);
3793 }
3794 free (EncapData2);
3795 EncapData2 = NULL;
3796 }
3797
3798 EncapData1 = NULL;
3799
3800 free (TempFv);
3801 TempFv = NULL;
3802
3803 } while (CurrentFv != NULL);
3804
3805 CurrentFv = NULL;
3806 free (Fd);
3807 Fd = NULL;
3808
3809 return;
3810 }
3811
3812 /**
3813 Generate the compressed section with specific type.
3814 Type could be EFI_STANDARD_COMPRESSION or EFI_NOT_COMPRESSED
3815
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.
3819
3820 @return EFI_INVALID_PARAMETER
3821 @return EFI_ABORTED
3822 @return EFI_OUT_OF_RESOURCES
3823 @return EFI_SUCCESS
3824
3825 **/
3826 EFI_STATUS
3827 LibGenCompressedSection (
3828 CHAR8 *InputFileName,
3829 CHAR8 *OutPutFileName,
3830 UINT8 CompressionType
3831 )
3832 {
3833 //FILE *UnCompressFile;
3834 //FILE *CompressedFile;
3835 //VOID *UnCompressedBuffer;
3836 //VOID *CompressedBuffer;
3837 //UINT32 UnCompressedSize;
3838 //UINT32 CompressedSize;
3839 //CHAR8 *TempName;
3840 //CHAR8 *TemDir;
3841 //EFI_STATUS Status;
3842
3843 //UnCompressFile = NULL;
3844 //CompressedFile = NULL;
3845 //UnCompressedBuffer = NULL;
3846 //CompressedBuffer = NULL;
3847 //TempName = NULL;
3848 //TemDir = NULL;
3849 //UnCompressedSize = 0;
3850 //CompressedSize = 0;
3851
3852 if ( InputFileName == NULL ||
3853 OutPutFileName == NULL) {
3854 printf ("Error while generate compressed section!\n");
3855 return EFI_INVALID_PARAMETER;
3856 }
3857
3858 if (CompressionType == EFI_STANDARD_COMPRESSION) {
3859 /*
3860
3861 UnCompressFile = fopen (InputFileName, "rb");
3862 if (UnCompressFile == NULL) {
3863 printf ("Error while open file %s \n", InputFileName);
3864 return EFI_ABORTED;
3865 }
3866
3867 TemDir = _getcwd (NULL, _MAX_PATH);
3868 sprintf(TemDir, "%s\\%s", TemDir, TEMP_DIR_NAME);
3869
3870 TempName= LibFilenameStrExtended (strrchr(CloneString (tmpnam (NULL)),'\\'), TemDir, "comp");
3871
3872 CompressedFile = fopen (TempName, "wb+");
3873 if (CompressedFile == NULL) {
3874 printf ("Error while open file %s \n", TempName);
3875 return EFI_ABORTED;
3876 }
3877
3878 //
3879 // Get the original file size;
3880 //
3881 fseek(UnCompressFile,0,SEEK_SET);
3882 fseek(UnCompressFile,0,SEEK_END);
3883
3884 UnCompressedSize = ftell(UnCompressFile);
3885
3886 fseek(UnCompressFile,0,SEEK_SET);
3887
3888 UnCompressedBuffer = malloc (UnCompressedSize);
3889
3890 if (UnCompressedBuffer == NULL) {
3891 printf("Error while allocate memory! \n");
3892 return EFI_OUT_OF_RESOURCES;
3893 }
3894
3895 CompressedBuffer = malloc (UnCompressedSize);
3896
3897 if (CompressedBuffer == NULL) {
3898 printf("Error while allocate memory! \n");
3899 return EFI_OUT_OF_RESOURCES;
3900 }
3901
3902 if (fread (UnCompressedBuffer, 1, (size_t) UnCompressedSize, UnCompressFile) == (size_t) UnCompressedSize) {
3903 CompressedSize = UnCompressedSize;
3904
3905 Status = EfiCompress ( UnCompressedBuffer,
3906 UnCompressedSize,
3907 CompressedBuffer,
3908 &CompressedSize);
3909
3910 if (EFI_ERROR(Status)) {
3911 printf("Error while do compress operation! \n");
3912 return EFI_ABORTED;
3913 }
3914
3915 if (CompressedSize > UnCompressedSize) {
3916 printf("Error while do compress operation! \n");
3917 return EFI_ABORTED;
3918 }
3919 } else {
3920 printf("Error while reading file %s! \n", InputFileName);
3921 return EFI_ABORTED;
3922 }
3923
3924 //
3925 // Write the compressed data into output file
3926 //
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);
3931 return EFI_ABORTED;
3932 }
3933
3934 fclose(UnCompressFile);
3935 fclose (CompressedFile);
3936 */
3937
3938 //
3939 // Call GenSec tool to generate the compressed section.
3940 //
3941 LibCreateFfsSection(NULL, InputFileName, NULL, EFI_SECTION_COMPRESSION, OutPutFileName, NULL, NULL, NULL, 0, 0, "PI_STD");
3942
3943 } else if (CompressionType == EFI_NOT_COMPRESSED) {
3944
3945 LibCreateFfsSection(NULL, InputFileName, NULL, EFI_SECTION_COMPRESSION, OutPutFileName, NULL, NULL, NULL, 0, 0, "PI_NONE");
3946
3947 } else {
3948 printf ("Error while generate compressed section, unknown compression type! \n");
3949 return EFI_INVALID_PARAMETER;
3950 }
3951
3952
3953 return EFI_SUCCESS;
3954 }
3955
3956 EFI_STATUS
3957 LibEncapNewFvFile(
3958 IN FV_INFORMATION *FvInFd,
3959 IN CHAR8 *TemDir,
3960 IN ENCAP_INFO_DATA *CurrentEncapData,
3961 IN UINT32 Level_Break,
3962 OUT FFS_INFORMATION **OutputFile
3963 )
3964 {
3965 EFI_STATUS Status;
3966 UINT32 ParentType;
3967 UINT8 ParentLevel;
3968 UINT32 Type;
3969 UINT8 Level;
3970 CHAR8 *InfFileName;
3971 FILE *InfFile;
3972 ENCAP_INFO_DATA *LocalEncapData;
3973 ENCAP_INFO_DATA *LocalEncapDataTemp;
3974 ENCAP_INFO_DATA *LocalEncapDataNext;
3975 BOOLEAN FfsFoundFlag;
3976 UINT32 Index;
3977 UINT32 OuterIndex;
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;
3988 CHAR8 *FvGuidName;
3989 UINT16 GuidAttributes;
3990 UINT16 GuidDataOffset;
3991 BOOLEAN IsRootFv;
3992 BOOLEAN IsLargeFile;
3993 UINT32 EncapFvStart;
3994 UINT32 EncapFvIndex;
3995 CHAR8 *TmpFileName;
3996 FILE *TmpFile;
3997 FILE *InputFile;
3998 FILE *OutFile;
3999 UINT32 InputFileSize;
4000 UINT32 OutputFileSize;
4001 UINT32 LargeFileSize;
4002 UINT8 *Buffer = NULL;
4003 UINT8 SectionHeader[4] = { 0x00, 0x00, 0x00, 0x00 };
4004 UINT32 Id;
4005 UINT32 SubFvId;
4006 UINT32 header;
4007 UINT8 AlignN;
4008 UINT8 AlignV[1] = {0xFF};
4009 AlignN = 0;
4010 Id = 0;
4011 InputFileSize = 0;
4012 EncapFvIndex = 0;
4013 Index = 0;
4014 OuterIndex = 0;
4015 ParentType = 0;
4016 ParentLevel = 0;
4017 Type = 0;
4018 Level = 0;
4019 SubFvId = 0;
4020 FfsFoundFlag = FALSE;
4021 LocalEncapDataTemp = NULL;
4022 LocalEncapDataNext = NULL;
4023 ExtractionTool = NULL;
4024 InputFileName = NULL;
4025 OutputFileName = NULL;
4026 IsLastLevelFfs = TRUE;
4027 IsLeafFlagIgnore = FALSE;
4028 FirstInFlag = TRUE;
4029 FvGuidName = NULL;
4030 OutputFileNameListFlag = TRUE;
4031 IsLargeFile = FALSE;
4032 OutputFileSize = 0;
4033 LargeFileSize = 0x1000000;
4034
4035
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;
4040 }
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;
4050
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;
4055 }
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;
4065 //
4066 // Encapsulate from the lowest FFS file level.
4067 //
4068 LocalEncapData = CurrentEncapData;
4069 if (LocalEncapData == NULL) {
4070 LocalEncapData = FvInFd->EncapData;
4071 }
4072 Level = LocalEncapData->Level;
4073 Type = LocalEncapData->Type;
4074
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) {
4083
4084 LibEncapNewFvFile(FvInFd, TemDir, LocalEncapDataTemp, 1, &ChildFileNameList);
4085 ChildFileNameList->ParentLevel = LocalEncapDataTemp->Level -1;
4086 if (FvInFd->ChildFvFFS == NULL) {
4087 FvInFd->ChildFvFFS = ChildFileNameList;
4088 } else {
4089 NewFileNameList = FvInFd->ChildFvFFS;
4090 while (NewFileNameList->Next != NULL) {
4091 NewFileNameList = NewFileNameList->Next;
4092 }
4093 NewFileNameList->Next = ChildFileNameList;
4094 }
4095 }
4096 LocalEncapDataTemp = LocalEncapDataTemp->RightNode;
4097 }
4098 }
4099
4100 if (LocalEncapData->Level > Level) {
4101 if (LocalEncapData->Type == FMMT_ENCAP_TREE_FFS) {
4102 ParentLevel = Level;
4103 ParentType = Type;
4104 }
4105 Level = LocalEncapData->Level;
4106 Type = LocalEncapData->Type;
4107 }
4108 LocalEncapData = LocalEncapData->NextNode;
4109 }
4110 } else {
4111 LocalEncapData = CurrentEncapData;
4112 while (LocalEncapData != NULL) {
4113 if (LocalEncapData->Level > Level) {
4114 if (LocalEncapData->Type == FMMT_ENCAP_TREE_FFS) {
4115 ParentLevel = Level;
4116 ParentType = Type;
4117 }
4118 Level = LocalEncapData->Level;
4119 Type = LocalEncapData->Type;
4120 }
4121 LocalEncapData = LocalEncapData->NextNode;
4122 }
4123 }
4124
4125 do {
4126 switch (ParentType) {
4127 case FMMT_ENCAP_TREE_FV:
4128 OutputFileNameListFlag = TRUE;
4129 EncapFvStart = 0;
4130 for(OuterIndex=0;OutputFileNameListFlag;OuterIndex++){
4131 //
4132 // Generate FV.inf attributes.
4133 //
4134 InfFileName = LibFilenameStrExtended (strrchr(GenTempFile (),OS_SEP), TemDir, "inf");
4135 FirstInFlag = TRUE;
4136
4137 InfFile = fopen (InfFileName, "wt+");
4138
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);
4143 return EFI_ABORTED;
4144 }
4145
4146 if (CurrentEncapData == NULL) {
4147 LocalEncapData = FvInFd->EncapData;
4148 } else {
4149 LocalEncapData = CurrentEncapData;
4150 }
4151
4152 while (LocalEncapData->NextNode != NULL) {
4153 if (LocalEncapData->Level == ParentLevel) {
4154 break;
4155 }
4156 LocalEncapData = LocalEncapData->NextNode;
4157 }
4158
4159 if (((EFI_FIRMWARE_VOLUME_HEADER *)(LocalEncapData->Data))->ExtHeaderOffset != 0) {
4160 //
4161 // FV GUID Name memory allocation
4162 //
4163 FvGuidName = (CHAR8 *) malloc (255);
4164
4165 if (FvGuidName == NULL) {
4166 Error ("FMMT", 0, 0004, "Out of resource, memory allocation failed! \n", "");
4167 fclose (InfFile);
4168 free (OutputFileNameList);
4169 free (ChildFileNameList);
4170 return EFI_ABORTED;
4171 }
4172
4173 memset(FvGuidName, '\0', 255);
4174
4175 sprintf(
4176 FvGuidName,
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]
4189 );
4190
4191 } else {
4192 FvGuidName = NULL;
4193 }
4194
4195
4196 if (ParentLevel == 1) {
4197 Status = LibFvHeaderOptionToStr((EFI_FIRMWARE_VOLUME_HEADER *)LocalEncapData->Data, InfFile, TRUE);
4198 } else {
4199 Status = LibFvHeaderOptionToStr((EFI_FIRMWARE_VOLUME_HEADER *)LocalEncapData->Data, InfFile, FALSE);
4200 }
4201
4202
4203 if (EFI_ERROR (Status)) {
4204 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "generate FV INF file [Options] section failed.");
4205 fclose (InfFile);
4206 free (OutputFileNameList);
4207 free (ChildFileNameList);
4208 return Status;
4209 }
4210
4211 Status = LibFvHeaderAttributeToStr(((EFI_FIRMWARE_VOLUME_HEADER *)LocalEncapData->Data)->Attributes, InfFile);
4212
4213 if (EFI_ERROR (Status)) {
4214 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV header attribute failed");
4215 fclose (InfFile);
4216 free (OutputFileNameList);
4217 free (ChildFileNameList);
4218 return Status;
4219 }
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");
4224 fclose (InfFile);
4225 free (OutputFileNameList);
4226 free (ChildFileNameList);
4227 return Status;
4228 }
4229 FvGuidName = NULL;
4230 }
4231
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)) {
4235 SubFvId = Index;
4236 break;
4237 }
4238 }
4239 }
4240 //
4241 // Found FFSs from Fv structure.
4242 //
4243 FfsFoundFlag = FALSE;
4244 IsRootFv = FALSE;
4245 for (Index=0; Index <= FvInFd->FfsNumbers; Index++) {
4246 if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == FALSE){
4247 break;
4248 }
4249 if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == TRUE){
4250 if (Index == EncapFvIndex) {
4251 if (FirstInFlag) {
4252 Status = LibAddFfsFileToFvInf (OutputFileNameList->FFSName, InfFile, TRUE);
4253 FirstInFlag = FALSE;
4254 } else {
4255 Status = LibAddFfsFileToFvInf (OutputFileNameList->FFSName, InfFile, FALSE);
4256 }
4257 if (EFI_ERROR (Status)) {
4258 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4259 fclose (InfFile);
4260 free (OutputFileNameList);
4261 free (ChildFileNameList);
4262 return Status;
4263 }
4264 }
4265 }
4266
4267 NewFileNameList = FvInFd->ChildFvFFS;
4268 while (NewFileNameList != NULL && NewFileNameList -> FFSName != NULL) {
4269 if (NewFileNameList -> ParentLevel == ParentLevel && Index == NewFileNameList->InFvId && NewFileNameList->FfsFoundFlag==TRUE) {
4270 if (FirstInFlag) {
4271 Status = LibAddFfsFileToFvInf (NewFileNameList->FFSName, InfFile, TRUE);
4272 FirstInFlag = FALSE;
4273 } else {
4274 Status = LibAddFfsFileToFvInf (NewFileNameList->FFSName, InfFile, FALSE);
4275 }
4276 if (EFI_ERROR (Status)) {
4277 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4278 fclose (InfFile);
4279 free (OutputFileNameList);
4280 free (ChildFileNameList);
4281 return Status;
4282 }
4283 }
4284 NewFileNameList = NewFileNameList->Next;
4285 }
4286
4287 if (FvInFd->FfsAttuibutes[Index].IsHandle==TRUE) {
4288 continue;
4289 }
4290 if (SubFvId > 0 && Index < SubFvId) {
4291 continue;
4292 }
4293
4294 //
4295 // For the last level FFS, the level below FFSs we should not care the IsLeaf Flag.
4296 //
4297 if (IsLastLevelFfs) {
4298 IsLeafFlagIgnore = TRUE;
4299 } else {
4300 IsLeafFlagIgnore = FvInFd->FfsAttuibutes[Index].IsLeaf;
4301 }
4302
4303 if (FvInFd->FfsAttuibutes[Index].Level >= ParentLevel + 1 && IsLeafFlagIgnore) {
4304 if (FirstInFlag) {
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;
4311 }
4312
4313 if (EFI_ERROR (Status)) {
4314 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4315 fclose (InfFile);
4316 free (OutputFileNameList);
4317 free (ChildFileNameList);
4318 return Status;
4319 }
4320 if (Index == 0) {
4321 // Root FV need to include all FFS files.
4322 IsRootFv = TRUE;
4323 }
4324 } else {
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;
4329 }
4330
4331 if (EFI_ERROR (Status)) {
4332 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV inf file [files] section failed!");
4333 fclose (InfFile);
4334 free (OutputFileNameList);
4335 free (ChildFileNameList);
4336 return Status;
4337 }
4338 if (Index == 0) {
4339 // Root FV need to include all FFS files.
4340 IsRootFv = TRUE;
4341 }
4342 }
4343
4344
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;
4350 break;
4351 }else{
4352 if (FvInFd->FfsAttuibutes[Index].Level != 0xFF){
4353 FvInFd->FfsAttuibutes[Index].Level = 0;
4354 }
4355 }
4356
4357 }
4358 }
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;
4363 }
4364 }
4365 if (!FfsFoundFlag){
4366 OutputFileNameListFlag = FALSE;
4367 if (OuterIndex > 0){
4368 fclose (InfFile);
4369 break;
4370 }
4371 }
4372 //
4373 // Create FV
4374 //
4375 fclose (InfFile);
4376
4377 EncapFvIndex = EncapFvStart;
4378
4379 OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "FV");
4380
4381 Status = LibEncapsulateFfsToFv (InfFileName, NULL, OutputFileName, FvGuidName, IsLargeFile);
4382
4383 if (EFI_ERROR (Status)) {
4384 Error ("FMMT", 0, 0004, "error while encapsulate FD Image", "Generate FV failed!");
4385 free (OutputFileNameList);
4386 free (ChildFileNameList);
4387 return Status;
4388 }
4389
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;
4394 }
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;
4404 }
4405 }
4406 }
4407 break;
4408 case FMMT_ENCAP_TREE_FFS:
4409
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;
4416 }
4417 while (LocalEncapData->NextNode != NULL) {
4418 if (LocalEncapData->Level == ParentLevel) {
4419 for(;LocalEncapData->NextNode != NULL;) {
4420 if(LocalEncapData->FvExtHeader != NULL) {
4421 break;
4422 }
4423 LocalEncapData = LocalEncapData->NextNode;
4424 }
4425 break;
4426 }
4427 LocalEncapData = LocalEncapData->NextNode;
4428 }
4429
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);
4434 return EFI_ABORTED;
4435 }
4436
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);
4444 return EFI_ABORTED;
4445 }
4446 header = (OutputFileNameList->UiNameSize+4) | (EFI_SECTION_USER_INTERFACE << 24);
4447 Index = 0;
4448 while (header) {
4449 SectionHeader[Index] = header % 0x100;
4450 header /= 0x100;
4451 Index ++;
4452 }
4453 InputFile = fopen(InputFileName, "rb+");
4454 if (InputFile == NULL) {
4455 Error("FMMT", 0, 0004, "Could not open input file %s! \n", "");
4456 fclose(TmpFile);
4457 free (OutputFileNameList);
4458 free (ChildFileNameList);
4459 return EFI_ABORTED;
4460 }
4461 fseek(InputFile, 0, SEEK_SET);
4462 fseek(InputFile, 0, SEEK_END);
4463 InputFileSize = ftell(InputFile);
4464 fseek(InputFile, 0, SEEK_SET);
4465
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", "");
4471 fclose(TmpFile);
4472 fclose(InputFile);
4473 free(Buffer);
4474 free (OutputFileNameList);
4475 free (ChildFileNameList);
4476 return EFI_ABORTED;
4477 }
4478 fwrite(Buffer, 1, InputFileSize + OutputFileNameList->UiNameSize + 4, TmpFile);
4479 free(Buffer);
4480 fclose(TmpFile);
4481 fclose(InputFile);
4482 InputFileName = TmpFileName;
4483 }
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);
4491 return EFI_ABORTED;
4492 }
4493 InputFile = fopen(InputFileName, "rb+");
4494 if (InputFile == NULL) {
4495 Error("FMMT", 0, 0004, "Could not open input file %s! \n", "");
4496 fclose(TmpFile);
4497 free (OutputFileNameList);
4498 free (ChildFileNameList);
4499 return EFI_ABORTED;
4500 }
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;
4508 }
4509 Buffer = malloc(InputFileSize + OutputFileNameList->DepexLen + AlignN);
4510 memcpy(Buffer, OutputFileNameList->Depex, OutputFileNameList->DepexLen);
4511 if (AlignN != 0) {
4512 for (Index = 0; Index < AlignN; Index ++) {
4513 memcpy(Buffer + OutputFileNameList->DepexLen + Index, AlignV, 1);
4514 }
4515 }
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", "");
4518 fclose(TmpFile);
4519 fclose(InputFile);
4520 free(Buffer);
4521 free (OutputFileNameList);
4522 free (ChildFileNameList);
4523 return EFI_ABORTED;
4524 }
4525 fwrite(Buffer, 1, InputFileSize + OutputFileNameList->DepexLen + AlignN, TmpFile);
4526 free(Buffer);
4527 fclose(TmpFile);
4528 fclose(InputFile);
4529 InputFileName = TmpFileName;
4530 }
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);
4539 return Status;
4540 }
4541 memset(FvInFd->FfsAttuibutes[Id].FfsName, '\0', _MAX_PATH);
4542 FvInFd->FfsAttuibutes[Id].Level = 0xFF;
4543 break;
4544 }
4545 }
4546 }
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");
4551 }
4552 else{
4553 Status = LibEncapSectionFileToFFS(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, InputFileName, OutputFileName, LocalEncapData->FvExtHeader->FvName, FALSE, FvInFd->AlignmentStr);
4554 }
4555 }
4556 else{
4557 Status = LibEncapSectionFileToFFS(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, InputFileName, OutputFileName, LocalEncapData->FvExtHeader->FvName, FALSE, FvInFd->AlignmentStr);
4558 }
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);
4563 return Status;
4564 }
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;
4571 }
4572 memcpy((char *)OutputFileNameList->FFSName, (char *)OutputFileName, strlen(OutputFileName)+1);
4573 OutputFileNameList->IsFFS = TRUE;
4574 if (OutputFileNameList->Next == NULL){
4575 break;
4576 }
4577 OutputFileNameList = OutputFileNameList->Next;
4578 }
4579 break;
4580 case FMMT_ENCAP_TREE_GUIDED_SECTION:
4581 while(OutputFileNameList!= NULL && OutputFileNameList->FFSName != NULL){
4582 //
4583 // Create the guided section original data, do compress operation.
4584 //
4585 InputFileName = OutputFileNameList->FFSName;
4586 OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "compressed");
4587
4588 //
4589 // Use the guided section header guid to find out compress application name.
4590 //
4591 LocalEncapData = CurrentEncapData;
4592 if (LocalEncapData == NULL) {
4593 LocalEncapData = FvInFd->EncapData;
4594 }
4595 while (LocalEncapData->NextNode != NULL) {
4596 if (LocalEncapData->Level == ParentLevel) {
4597 break;
4598 }
4599 LocalEncapData = LocalEncapData->NextNode;
4600 }
4601
4602 ExtractionTool =
4603 LookupGuidedSectionToolPath (
4604 mParsedGuidedSectionTools,
4605 (EFI_GUID *)LocalEncapData->Data
4606 );
4607 GuidDataOffset = *(UINT16 *) ((UINT8 *) LocalEncapData->Data + sizeof (EFI_GUID));
4608 GuidAttributes = *(UINT16 *) ((UINT8 *) LocalEncapData->Data + sizeof (EFI_GUID) + sizeof (UINT16));
4609
4610 Status = LibCreateGuidedSectionOriginalData (InputFileName, ExtractionTool, OutputFileName);
4611
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);
4616 return Status;
4617 }
4618
4619 GuidDataOffset = GuidDataOffset - sizeof (EFI_GUID_DEFINED_SECTION);
4620 InputFileName = OutputFileName;
4621 OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "guided");
4622
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);
4629 return EFI_ABORTED;
4630 }
4631 fseek(OutFile, 0, SEEK_SET);
4632 fseek(OutFile, 0, SEEK_END);
4633 OutputFileSize = ftell(OutFile);
4634 fclose(OutFile);
4635 if (OutputFileSize > LargeFileSize) {
4636 IsLargeFile = TRUE;
4637 }
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;
4642 }
4643 memcpy((char *)OutputFileNameList->FFSName, (char *)OutputFileName, strlen(OutputFileName)+1);
4644
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);
4649 return Status;
4650 }
4651 if (OutputFileNameList->Next == NULL){
4652 break;
4653 }
4654 OutputFileNameList = OutputFileNameList->Next;
4655 }
4656 break;
4657 case FMMT_ENCAP_TREE_COMPRESS_SECTION:
4658 while(OutputFileNameList!= NULL && OutputFileNameList->FFSName != NULL){
4659 InputFileName = OutputFileNameList->FFSName;
4660
4661 OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "comsec");
4662 LocalEncapData = CurrentEncapData;
4663 if (LocalEncapData == NULL) {
4664 LocalEncapData = FvInFd->EncapData;
4665 }
4666 while (LocalEncapData->NextNode != NULL) {
4667 if (LocalEncapData->Level == ParentLevel) {
4668 break;
4669 }
4670 LocalEncapData = LocalEncapData->NextNode;
4671 }
4672
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;
4678 }
4679 memcpy((char *)OutputFileNameList->FFSName, (char *)OutputFileName, strlen(OutputFileName)+1);
4680
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);
4685 return Status;
4686 }
4687 if (OutputFileNameList->Next == NULL){
4688 break;
4689 }
4690 OutputFileNameList = OutputFileNameList->Next;
4691 }
4692 break;
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");
4697
4698 Status = LibCreateFfsSection(NULL, InputFileName, NULL, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, OutputFileName, NULL, NULL, NULL, 0, 0, NULL);
4699
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);
4704 return Status;
4705 }
4706
4707 InputFileName = OutputFileName;
4708 OutputFileName= LibFilenameStrExtended (strrchr(GenTempFile (), OS_SEP), TemDir, "sec");
4709
4710 //
4711 // Make it alignment.
4712 //
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);
4719 return EFI_ABORTED;
4720 }
4721 fseek(OutFile, 0, SEEK_SET);
4722 fseek(OutFile, 0, SEEK_END);
4723 OutputFileSize = ftell(OutFile);
4724 fclose(OutFile);
4725 if (OutputFileSize > LargeFileSize) {
4726 IsLargeFile = TRUE;
4727 }
4728
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;
4733 }
4734 memcpy((char *)OutputFileNameList->FFSName, (char *)OutputFileName, strlen(OutputFileName)+1);
4735
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);
4740 return Status;
4741 }
4742 if (OutputFileNameList->Next == NULL){
4743 break;
4744 }
4745 OutputFileNameList = OutputFileNameList->Next;
4746 }
4747 break;
4748 default:
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;
4761 return EFI_SUCCESS;
4762 }
4763 }
4764 }
4765
4766 if (CurrentEncapData == NULL) {
4767 LocalEncapData = FvInFd->EncapData;
4768 } else {
4769 if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == TRUE) {
4770 *OutputFile = OutputFileNameList;
4771 return EFI_SUCCESS;
4772 }
4773 LocalEncapData = CurrentEncapData;
4774 }
4775 ParentLevel -= 1;
4776
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;
4782 break;
4783 }
4784 ParentType = LocalEncapData->Type;
4785 break;
4786 }
4787 LocalEncapData = LocalEncapData->NextNode;
4788 }
4789 } while (ParentLevel != Level_Break);
4790
4791 *OutputFile = OutputFileNameList;
4792 return EFI_SUCCESS;
4793
4794 }
4795
4796 EFI_STATUS
4797 LibFindFvInEncapData (
4798 ENCAP_INFO_DATA *EncapData,
4799 UINT8 *Index
4800 )
4801 {
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;
4807 }
4808 while (LocalEncapData != NULL) {
4809 if (LocalEncapData->RightNode != NULL) {
4810 LibFindFvInEncapData (LocalEncapData->RightNode, Index);
4811 }
4812 if (LocalEncapData->Type == FMMT_ENCAP_TREE_FV) {
4813 (*Index)++;
4814 }
4815 LocalEncapData = LocalEncapData->NextNode;
4816 }
4817 return EFI_SUCCESS;
4818 }
4819
4820 EFI_STATUS
4821 LibLocateFvViaFvId (
4822 IN FIRMWARE_DEVICE *FdData,
4823 IN CHAR8 *FvId,
4824 IN OUT FV_INFORMATION **FvInFd
4825 )
4826 {
4827 UINT8 FvIndex1;
4828 UINT8 FvIndex2;
4829 BOOLEAN FvFoundFlag;
4830 CHAR8* FvGuidName;
4831 ENCAP_INFO_DATA *LocalEncapData;
4832 ENCAP_INFO_DATA *LocalEncapDataRight;
4833 ENCAP_INFO_DATA *LocalEncapDataNext;
4834 FvIndex1 = 0;
4835 FvIndex2 = 0;
4836 FvFoundFlag = FALSE;
4837 FvGuidName = NULL;
4838 LocalEncapDataNext = NULL;
4839 LocalEncapDataRight = NULL;
4840
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;
4844 }
4845
4846 *FvInFd = FdData->Fv;
4847
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!");
4850 return EFI_ABORTED;
4851 }
4852
4853 FvGuidName = (CHAR8 *) malloc (255);
4854 if (FvGuidName == NULL) {
4855 Error ("FMMT", 0, 0005, "Resource: Memory can't be allocated", NULL);
4856 return EFI_ABORTED;
4857 }
4858 memset(FvGuidName, '\0', 255);
4859 LocalEncapData = NULL;
4860
4861 if (strlen(FvId) == 36) {
4862 while (FvInFd != NULL) {
4863 if (((*FvInFd)->FvExtHeader) != NULL) {
4864 sprintf(
4865 FvGuidName,
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;
4880 break;
4881 }
4882 }
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) {
4895 sprintf(
4896 FvGuidName,
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)
4910 {
4911 sprintf(FvId, "%s%d", "FV", LocalEncapDataNext->FvId - 1);
4912 break;
4913 }
4914
4915 }
4916 }
4917 LocalEncapDataNext = LocalEncapDataNext->NextNode;
4918 }
4919 }
4920 LocalEncapDataRight = LocalEncapDataRight->RightNode;
4921 }
4922 }
4923 if (LocalEncapData->Type == FMMT_ENCAP_TREE_FV) {
4924 if (LocalEncapData->FvExtHeader != NULL) {
4925 sprintf(
4926 FvGuidName,
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]);
4939
4940 if (strcmp(FvGuidName, FvId) == 0) {
4941 sprintf(FvId, "%s%d", "FV", LocalEncapData->FvId - 1);
4942 break;
4943 }
4944 }
4945 }
4946 LocalEncapData = LocalEncapData->NextNode;
4947 }
4948 }
4949 if ((*FvInFd)->FvNext == 0) {
4950 break;
4951 }
4952 *FvInFd = (*FvInFd)->FvNext;
4953 }
4954 }
4955 *FvInFd = FdData->Fv;
4956 FvIndex1 = (UINT8) atoi (FvId + 2);
4957
4958 while (FvInFd != NULL) {
4959 if (((*FvInFd)->FvName) != NULL) {
4960 FvIndex2 = (UINT8) atoi ((*FvInFd)->FvName + 2);
4961 LocalEncapData = (*FvInFd)->EncapData;
4962 LibFindFvInEncapData (LocalEncapData, &FvIndex2);
4963
4964 if ((FvIndex2 - 1 >= FvIndex1)) {
4965 FvFoundFlag = TRUE;
4966 break;
4967 }
4968 if ((*FvInFd)->FvNext == 0) {
4969 break;
4970 }
4971 }
4972 *FvInFd = (*FvInFd)->FvNext;
4973 }
4974 if (FvGuidName != NULL) {
4975 free (FvGuidName);
4976 }
4977 //
4978 // The specified FV id has issue, can not find the FV in FD.
4979 //
4980 if (!FvFoundFlag) {
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!");
4982 return EFI_ABORTED;
4983 }
4984
4985 return EFI_SUCCESS;
4986
4987 }
4988
4989 #define BUILD_IN_TOOL_COUNT 4
4990
4991 EFI_HANDLE
4992 LibPreDefinedGuidedTools (
4993 VOID
4994 )
4995 {
4996 EFI_GUID Guid;
4997 STRING_LIST *Tool;
4998 GUID_SEC_TOOL_ENTRY *FirstGuidTool;
4999 GUID_SEC_TOOL_ENTRY *LastGuidTool;
5000 GUID_SEC_TOOL_ENTRY *NewGuidTool;
5001 UINT8 Index;
5002 EFI_STATUS Status;
5003
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"
5009 };
5010
5011 Tool = NULL;
5012 FirstGuidTool = NULL;
5013 LastGuidTool = NULL;
5014 NewGuidTool = NULL;
5015 Index = 0;
5016
5017 for (Index = 0; Index < BUILD_IN_TOOL_COUNT; Index++) {
5018 Tool = SplitStringByWhitespace (PreDefinedGuidedTool[Index]);
5019 if ((Tool != NULL) &&
5020 (Tool->Count == 3)
5021 ) {
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;
5030 } else {
5031 printf ("Error while allocate resource! \n");
5032 FreeStringList (Tool);
5033 return NULL;
5034 }
5035 if (FirstGuidTool == NULL) {
5036 FirstGuidTool = NewGuidTool;
5037 } else {
5038 LastGuidTool->Next = NewGuidTool;
5039 }
5040 LastGuidTool = NewGuidTool;
5041 }
5042 } else {
5043 fprintf (stdout, "Error");
5044 }
5045 if (Tool != NULL) {
5046 FreeStringList (Tool);
5047 Tool = NULL;
5048 }
5049 }
5050 return FirstGuidTool;
5051 }