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