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