]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
Removed #ifdef NT32 as we don't need them for tools
[mirror_edk2.git] / Tools / Source / TianoTools / GenFdImage / GenFdImageDll.c
CommitLineData
d25c4bf0 1/*++\r
2Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved\r
3This software and associated documentation (if any) is furnished\r
4under a license and may only be used or copied in accordance\r
5with the terms of the license. Except as permitted by such\r
6license, no part of this software or documentation may be\r
7reproduced, stored in a retrieval system, or transmitted in any\r
8form or by any means without the express written consent of\r
9Intel Corporation.\r
10\r
11\r
12 Module Name: \r
13 GenFdImageDll.C\r
14\r
15 Abstarct:\r
16 This file contains the relevant functions required to complete\r
17 the API to generate Firmware Device\r
18--*/\r
19\r
20// GC_TODO: fix comment to add: Abstract:\r
21//\r
22// This tells the compiler to export the DLL functions\r
23//\r
24#define GEN_FD_IMAGE_EXPORTS\r
25\r
26#include <stdio.h>\r
27#include <stdlib.h>\r
28#include <string.h>\r
51d48c26 29// #include <io.h>\r
d25c4bf0 30#include <assert.h>\r
51d48c26 31#include "UefiBaseTypes.h"\r
32#include "Base.h"\r
d25c4bf0 33#include "GenFdImage.h"\r
51d48c26 34// #include "GenFvImage.h"\r
d25c4bf0 35#include "ParseInf.h"\r
36\r
37//\r
38// Global declaration\r
39//\r
40UINTN ValidLineNum = 0;\r
41\r
42UINTN NumFvFiles = 0;\r
43static UINT64 LastAddress = 0;\r
44\r
45CHAR8 **TokenStr;\r
46CHAR8 **OrgStrTokPtr;\r
47\r
48FDINFO *FdInfo;\r
49FDINFO *OrgFdInfoPtr;\r
50\r
51FVINFO **FvInfo;\r
52FVINFO **OrgFvInfoPtr;\r
53\r
54//\r
55// Global function declarations\r
56//\r
57EFI_STATUS\r
58BuildFirmwareDeviceBinaryFromFwVolumes (\r
59 IN UINT64 FvBaseAddress,\r
60 IN CHAR8 *FvFileName,\r
61 IN CHAR8 *FdFileName\r
62 );\r
63\r
64INTN\r
65CompareItems (\r
66 IN const VOID *Arg1,\r
67 IN const VOID *Arg2\r
68 )\r
69/*++\r
70Description:\r
71\r
72 This function is used by qsort to sort the Fv list based on FvBaseAddress\r
73\r
74Input:\r
75 Arg1\r
76 Arg2\r
77\r
78Return:\r
79\r
80 None\r
81--*/\r
82// GC_TODO: function comment is missing 'Routine Description:'\r
83// GC_TODO: function comment is missing 'Arguments:'\r
84// GC_TODO: function comment is missing 'Returns:'\r
85// GC_TODO: Arg1 - add argument and description to function comment\r
86// GC_TODO: Arg2 - add argument and description to function comment\r
87{\r
88 if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {\r
89 return 1;\r
90 } else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {\r
91 return -1;\r
92 } else {\r
93 return 0;\r
94 }\r
95}\r
96\r
97VOID\r
98BuildTokenList (\r
99 IN CHAR8 *Token\r
100 )\r
101/*++\r
102Description:\r
103\r
104 This function builds the token list in an array which will be parsed later\r
105\r
106Input:\r
107 Token String,\r
108\r
109Return:\r
110\r
111 None\r
112--*/\r
113// GC_TODO: function comment is missing 'Routine Description:'\r
114// GC_TODO: function comment is missing 'Arguments:'\r
115// GC_TODO: function comment is missing 'Returns:'\r
116// GC_TODO: Token - add argument and description to function comment\r
117{\r
118\r
119 strcpy (*TokenStr, Token);\r
120 TokenStr++;\r
121}\r
122\r
123VOID\r
124TrimLine (\r
125 IN CHAR8 *Line\r
126 )\r
127/*++\r
128Description:\r
129\r
130 This function cleans up the line by removing all whitespace and \r
131 comments\r
132\r
133Input:\r
134\r
135 Line String,\r
136\r
137Return:\r
138 None\r
139--*/\r
140// GC_TODO: function comment is missing 'Routine Description:'\r
141// GC_TODO: function comment is missing 'Arguments:'\r
142// GC_TODO: function comment is missing 'Returns:'\r
143// GC_TODO: Line - add argument and description to function comment\r
144{\r
145 CHAR8 TmpLine[FILE_NAME_SIZE];\r
146 CHAR8 c;\r
147 CHAR8 *Ptr0;\r
148 UINTN i;\r
149 UINTN j;\r
150\r
151 //\r
152 // Change '#' to '//' for Comment style\r
153 //\r
154 // if((Ptr0=strchr(Line, '#')) != NULL) {\r
155 //\r
156 if ((Ptr0 = strstr (Line, "//")) != NULL) {\r
157 Line[Ptr0 - Line] = 0;\r
158 }\r
159\r
160 i = j = 0;\r
161\r
162 while ((c = Line[i]) != 0) {\r
163 if ((c != ' ') && (c != '\t') && (c != '\n')) {\r
164 TmpLine[j++] = c;\r
165 }\r
166\r
167 i++;\r
168 }\r
169\r
170 TmpLine[j] = 0;\r
171 strcpy (Line, TmpLine);\r
172}\r
173\r
174VOID\r
175ValidLineCount (\r
176 IN FILE *Fp\r
177 )\r
178/*++\r
179\r
180Description:\r
181\r
182 This function calculated number of valid lines in a input file.\r
183 \r
184Input:\r
185\r
186 Fp Pointer to a file handle which has been opened.\r
187\r
188Return:\r
189\r
190 None\r
191--*/\r
192// GC_TODO: function comment is missing 'Routine Description:'\r
193// GC_TODO: function comment is missing 'Arguments:'\r
194// GC_TODO: function comment is missing 'Returns:'\r
195// GC_TODO: Fp - add argument and description to function comment\r
196{\r
197 CHAR8 Buff[FILE_NAME_SIZE];\r
198\r
199 while (fgets (Buff, sizeof (Buff), Fp)) {\r
200 TrimLine (Buff);\r
201 if (Buff[0] == 0) {\r
202 continue;\r
203 }\r
204\r
205 ValidLineNum++;\r
206 }\r
207}\r
208\r
209VOID\r
210ParseInputFile (\r
211 IN FILE *Fp\r
212 )\r
213/*++\r
214 \r
215Description:\r
216\r
217 This function parses the input file and tokenize the string\r
218 \r
219Input:\r
220\r
221 Fp Pointer to a file handle which has been opened.\r
222 \r
223Return:\r
224\r
225 None\r
226--*/\r
227// GC_TODO: function comment is missing 'Routine Description:'\r
228// GC_TODO: function comment is missing 'Arguments:'\r
229// GC_TODO: function comment is missing 'Returns:'\r
230// GC_TODO: Fp - add argument and description to function comment\r
231{\r
232 CHAR8 *Token;\r
233 CHAR8 Buff[FILE_NAME_SIZE];\r
234 CHAR8 OrgLine[FILE_NAME_SIZE];\r
235 CHAR8 Str[FILE_NAME_SIZE];\r
236 CHAR8 Delimit[] = "=";\r
237\r
238 while (fgets (Buff, sizeof (Buff), Fp) != NULL) {\r
239 strcpy (OrgLine, Buff);\r
240 TrimLine (Buff);\r
241\r
242 if (Buff[0] == 0) {\r
243 continue;\r
244 }\r
245\r
246 Token = strtok (Buff, Delimit);\r
247\r
248 while (Token != NULL) {\r
249 strcpy (Str, Token);\r
250 BuildTokenList (Str);\r
251 Token = strtok (NULL, Delimit);\r
252 }\r
253 }\r
254}\r
255\r
256EFI_STATUS\r
257InitializeComps (\r
258 VOID\r
259 )\r
260/*++\r
261\r
262Description:\r
263\r
264 This function intializes the relevant global variable which is being\r
265 used to store the information retrieved from INF file.\r
266 \r
267Input:\r
268\r
269 None\r
270\r
271Return:\r
272\r
273 EFI_STATUS\r
274--*/\r
275// GC_TODO: function comment is missing 'Routine Description:'\r
276// GC_TODO: function comment is missing 'Arguments:'\r
277// GC_TODO: function comment is missing 'Returns:'\r
278// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
279// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
280// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
281// GC_TODO: EFI_SUCCESS - add return value to function comment\r
282{\r
283 UINTN Index;\r
284\r
285 FdInfo = malloc (sizeof (FDINFO));\r
286\r
287 if (FdInfo == NULL) {\r
288 return EFI_OUT_OF_RESOURCES;\r
289 }\r
290\r
291 OrgFdInfoPtr = FdInfo;\r
292\r
293 FvInfo = malloc (sizeof (int) * NumFvFiles);\r
294\r
295 if (FvInfo == NULL) {\r
296 return EFI_OUT_OF_RESOURCES;\r
297 }\r
298\r
299 OrgFvInfoPtr = FvInfo;\r
300\r
301 for (Index = 0; Index < NumFvFiles; Index++) {\r
302 *FvInfo = malloc (sizeof (FVINFO));\r
303\r
304 if (*FvInfo == NULL) {\r
305 return EFI_OUT_OF_RESOURCES;\r
306 }\r
307\r
308 memset (*FvInfo, 0, sizeof (FVINFO));\r
309 FvInfo++;\r
310 }\r
311\r
312 FvInfo = OrgFvInfoPtr;\r
313\r
314 return EFI_SUCCESS;\r
315}\r
316\r
317VOID\r
318InitializeInFileInfo (\r
319 VOID\r
320 )\r
321/*++\r
322\r
323Description:\r
324\r
325 This function intializes the relevant global variable which is being\r
326 used to store the information retrieved from INF file.\r
327\r
328Input:\r
329\r
330 NONE\r
331\r
332Return:\r
333\r
334 NONE\r
335--*/\r
336// GC_TODO: function comment is missing 'Routine Description:'\r
337// GC_TODO: function comment is missing 'Arguments:'\r
338// GC_TODO: function comment is missing 'Returns:'\r
339{\r
340 UINTN OptionFlag;\r
341 UINT64 StringValue;\r
342\r
343 OptionFlag = 0;\r
344 TokenStr = OrgStrTokPtr;\r
345\r
346 while (*TokenStr != NULL) {\r
347 if (stricmp (*TokenStr, "[options]") == 0) {\r
348 OptionFlag = 1;\r
349 }\r
350\r
351 if (OptionFlag) {\r
352 if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {\r
353 *TokenStr++;\r
354 if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
355 printf ("\nERROR: Cannot determine the FV base address.");\r
356 return ;\r
357 }\r
358 (*FvInfo)->FvBaseAddress = StringValue;\r
359 } else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {\r
360 *TokenStr++;\r
361 strcpy ((*FvInfo)->FvFile, *TokenStr);\r
362 }\r
363 }\r
364\r
365 TokenStr++;\r
366 }\r
367}\r
368\r
369EFI_STATUS\r
370GetFvRelatedInfoFromInfFile (\r
371 IN CHAR8 *FileName\r
372 )\r
373/*++\r
374 \r
375Description:\r
376\r
377 This function reads the input file, parse it and create a list of tokens\r
378 which is parsed and used, to intialize the data related to Firmware Volume.\r
379 \r
380Input:\r
381\r
382 FileName FileName which needed to be read to parse data\r
383\r
384Return:\r
385\r
386 EFI_STATUS\r
387 \r
388--*/\r
389// GC_TODO: function comment is missing 'Routine Description:'\r
390// GC_TODO: function comment is missing 'Arguments:'\r
391// GC_TODO: function comment is missing 'Returns:'\r
392// GC_TODO: FileName - add argument and description to function comment\r
393// GC_TODO: EFI_ABORTED - add return value to function comment\r
394// GC_TODO: EFI_ABORTED - add return value to function comment\r
395// GC_TODO: EFI_SUCCESS - add return value to function comment\r
396{\r
397 FILE *Fp;\r
398 UINTN Index;\r
399\r
400 Fp = fopen (FileName, "r");\r
401\r
402 if (Fp == NULL) {\r
403 printf ("Error in opening %s file\n", FileName);\r
404 return EFI_ABORTED;\r
405 }\r
406\r
407 ValidLineCount (Fp);\r
408\r
409 if (ValidLineNum == 0) {\r
410 printf ("\nFile doesn't contain any valid informations");\r
411 return EFI_ABORTED;\r
412 }\r
413\r
414 TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));\r
415 memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));\r
416 OrgStrTokPtr = TokenStr;\r
417\r
418 for (Index = 0; Index < (2 * ValidLineNum); Index++) {\r
419 *TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);\r
420 memset (*TokenStr, 0, FILE_NAME_SIZE);\r
421 TokenStr++;\r
422 }\r
423\r
424 *TokenStr = NULL;\r
425 TokenStr = OrgStrTokPtr;\r
426 fseek (Fp, 0L, SEEK_SET);\r
427\r
428 ParseInputFile (Fp);\r
429 InitializeInFileInfo ();\r
430\r
431 if (Fp) {\r
432 fclose (Fp);\r
433 }\r
434\r
435 return EFI_SUCCESS;\r
436}\r
437\r
438EFI_STATUS\r
439WriteFwBinary (\r
440 IN CHAR8 *FileName,\r
441 IN UINT64 StartAddress,\r
442 IN UINT64 Size,\r
443 IN UINT8 *Buffer\r
444 )\r
445/*++\r
446 \r
447Description:\r
448\r
449 This function reads the input file, parse it and create a list of tokens\r
450 which is parsed and used, to intialize the data related to Firmware Volume.\r
451 \r
452Input:\r
453\r
454 FileName FileName which needed to be read to parse data\r
455 StartAddress This will set the file position.\r
456 Size Size in bytes needed to be written\r
457 Buffer Buffer needed to e written\r
458\r
459Return:\r
460\r
461 EFI_STATUS\r
462 \r
463--*/\r
464// GC_TODO: function comment is missing 'Routine Description:'\r
465// GC_TODO: function comment is missing 'Arguments:'\r
466// GC_TODO: function comment is missing 'Returns:'\r
467// GC_TODO: FileName - add argument and description to function comment\r
468// GC_TODO: StartAddress - add argument and description to function comment\r
469// GC_TODO: Size - add argument and description to function comment\r
470// GC_TODO: Buffer - add argument and description to function comment\r
471// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
472// GC_TODO: EFI_ABORTED - add return value to function comment\r
473// GC_TODO: EFI_SUCCESS - add return value to function comment\r
474{\r
475 FILE *Fp;\r
476 UINTN NumByte;\r
477\r
478 Fp = fopen (FileName, "a+b");\r
479\r
480 if (Fp == NULL) {\r
481 printf ("\nERROR:Error in opening file %s ", FileName);\r
482 return EFI_INVALID_PARAMETER;\r
483 }\r
484\r
485 fseek (Fp, (UINTN) StartAddress, SEEK_SET);\r
486 NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);\r
487\r
488 //\r
489 // Check to ensure that buffer has been copied successfully\r
490 //\r
491 if (NumByte != Size) {\r
492 printf ("\nERROR: Error in copying the buffer into file");\r
493 return EFI_ABORTED;\r
494 }\r
495\r
496 if (Fp) {\r
497 fclose (Fp);\r
498 }\r
499\r
500 return EFI_SUCCESS;\r
501}\r
502\r
503EFI_STATUS\r
504BuildFirmwareDeviceBinaryFromFwVolumes (\r
505 IN UINT64 FvBaseAddress,\r
506 IN CHAR8 *FvFileName,\r
507 IN CHAR8 *FdFileName\r
508 )\r
509/*++\r
510 \r
511Description:\r
512\r
513 This function reads the input file, parse it and create a list of tokens\r
514 which is parsed and used, to intialize the data related to Firmware Volume.\r
515 \r
516Input:\r
517\r
518 FvBaseAddress Base Address. This info is retrieved from INF file\r
519 FvFileName InputFileName\r
520 FdFileName Output File Name\r
521\r
522Return:\r
523\r
524 EFI_STATUS\r
525 \r
526--*/\r
527// GC_TODO: function comment is missing 'Routine Description:'\r
528// GC_TODO: function comment is missing 'Arguments:'\r
529// GC_TODO: function comment is missing 'Returns:'\r
530// GC_TODO: FvBaseAddress - add argument and description to function comment\r
531// GC_TODO: FvFileName - add argument and description to function comment\r
532// GC_TODO: FdFileName - add argument and description to function comment\r
533// GC_TODO: EFI_ABORTED - add return value to function comment\r
534// GC_TODO: EFI_ABORTED - add return value to function comment\r
535// GC_TODO: EFI_ABORTED - add return value to function comment\r
536// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
537// GC_TODO: EFI_SUCCESS - add return value to function comment\r
538{\r
539 FILE *Fp;\r
540 UINT64 FileSize;\r
541 UINT64 NumByteRead;\r
542 UINT64 PadByteSize;\r
543 UINTN Index;\r
544 UINT64 BaseAddress;\r
545 UINT8 *Buffer;\r
546 EFI_STATUS Status;\r
547 static UINT64 StartAddress = 0;\r
548\r
549 Fp = fopen (FvFileName, "r+b");\r
550\r
551 if (Fp == NULL) {\r
552 printf ("\nERROR:Error in opening file %s", FvFileName);\r
553 return EFI_ABORTED;\r
554 }\r
555\r
556 BaseAddress = FdInfo->FdBaseAddress;\r
557\r
558 //\r
559 // Check if Base Address of Firmware Volume falls below the Base Address\r
560 // Firmware Device, if yes, then abort this process.\r
561 //\r
562 if (FvBaseAddress < BaseAddress) {\r
563 printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");\r
564 return EFI_ABORTED;\r
565 }\r
566 //\r
567 // Check if there are any hole between two Firmware Volumes. If any hole\r
568 // exists, fill the hole with PadByte data.\r
569 //\r
570 if (FvBaseAddress > LastAddress) {\r
571 PadByteSize = (FvBaseAddress - LastAddress);\r
572 Buffer = malloc ((UINTN) PadByteSize);\r
573\r
574 for (Index = 0; Index < PadByteSize; Index++) {\r
575 *Buffer = FdInfo->PadValue;\r
576 Buffer++;\r
577 }\r
578\r
579 Buffer -= PadByteSize;\r
580 Status = WriteFwBinary (FdFileName, StartAddress, (UINT64) PadByteSize, Buffer);\r
581\r
582 if (Buffer) {\r
583 free (Buffer);\r
584 }\r
585\r
586 if (Status != EFI_SUCCESS) {\r
587 printf ("\nERROR: Error in writing the binary image to file");\r
588 return Status;\r
589 }\r
590\r
591 StartAddress += PadByteSize;\r
592 LastAddress += PadByteSize;\r
593 }\r
594 //\r
595 // Proceed with next Firmware Volume updates\r
596 //\r
597 FileSize = _filelength (fileno (Fp));\r
598\r
599 if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {\r
600 printf (\r
601 "\nERROR:Unable to update Firmware Device. File %s is larger than \\r
602 available space.",\r
603 FvFileName\r
604 );\r
605 if (Fp) {\r
606 fclose (Fp);\r
607 }\r
608\r
609 return EFI_ABORTED;\r
610 }\r
611\r
612 Buffer = malloc ((UINTN) FileSize);\r
613\r
614 if (Buffer == NULL) {\r
615 printf ("Error in allocating buffer to read specific file\n");\r
616 return EFI_OUT_OF_RESOURCES;\r
617 }\r
618\r
619 NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
620\r
621 Status = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);\r
622\r
623 if (Buffer) {\r
624 free ((VOID *) Buffer);\r
625 }\r
626\r
627 if (Fp) {\r
628 fclose (Fp);\r
629 }\r
630\r
631 if (Status != EFI_SUCCESS) {\r
632 printf ("\nERROR: Error in writing the binary image to file");\r
633 return Status;\r
634 }\r
635\r
636 StartAddress += NumByteRead;\r
637 LastAddress += FileSize;\r
638\r
639 return EFI_SUCCESS;\r
640}\r
641\r
642VOID\r
643CleanUpMemory (\r
644 VOID\r
645 )\r
646/*++\r
647\r
648Description:\r
649\r
650 This function cleans up any allocated buffer\r
651 \r
652Input:\r
653\r
654 NONE\r
655\r
656Return:\r
657 \r
658 NONE\r
659--*/\r
660// GC_TODO: function comment is missing 'Routine Description:'\r
661// GC_TODO: function comment is missing 'Arguments:'\r
662// GC_TODO: function comment is missing 'Returns:'\r
663{\r
664 UINTN Index;\r
665\r
666 if (FdInfo) {\r
667 free (FdInfo);\r
668 }\r
669\r
670 FvInfo = OrgFvInfoPtr;\r
671\r
672 if (FvInfo) {\r
673 for (Index = 0; Index < NumFvFiles; Index++) {\r
674 if (*FvInfo) {\r
675 free (*FvInfo);\r
676 }\r
677\r
678 FvInfo++;\r
679 }\r
680\r
681 FvInfo = OrgFvInfoPtr;\r
682 free (FvInfo);\r
683 }\r
684}\r
685\r
686GEN_FD_IMAGE_API\r
687EFI_STATUS\r
688GenerateFdImage (\r
689 IN UINT64 BaseAddress,\r
690 IN UINT64 Size,\r
691 IN UINT8 PadByte,\r
692 IN CHAR8 *OutFile,\r
693 IN CHAR8 **FileList\r
694 )\r
695/*++\r
696 \r
697Description:\r
698\r
699 This function reads the input file, parse it and create a list of tokens\r
700 which is parsed and used, to intialize the data related to Firmware Volume.\r
701 \r
702Input:\r
703\r
704 BaseAddress Base Address for this Firmware Device\r
705 Size, Total Size of the Firmware Device\r
706 PadByte Pad byte data\r
707 OutFile Output File Name\r
708 FileList File List pointer to INF file names.\r
709\r
710Return:\r
711\r
712 EFI_STATUS\r
713 \r
714--*/\r
715// GC_TODO: function comment is missing 'Routine Description:'\r
716// GC_TODO: function comment is missing 'Arguments:'\r
717// GC_TODO: function comment is missing 'Returns:'\r
718// GC_TODO: BaseAddress - add argument and description to function comment\r
719// GC_TODO: Size - add argument and description to function comment\r
720// GC_TODO: PadByte - add argument and description to function comment\r
721// GC_TODO: OutFile - add argument and description to function comment\r
722// GC_TODO: FileList - add argument and description to function comment\r
723// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
724// GC_TODO: EFI_ABORTED - add return value to function comment\r
725// GC_TODO: EFI_ABORTED - add return value to function comment\r
726// GC_TODO: EFI_SUCCESS - add return value to function comment\r
727{\r
728 EFI_STATUS Status;\r
729 UINTN Index;\r
730 UINTN PadSize;\r
731 UINTN FileSize;\r
732 CHAR8 **InFile;\r
733 FILE *Fp;\r
734 UINT8 *Buffer;\r
735 UINTN NumByte;\r
736\r
737 //\r
738 // Ensure, if there are any previous Firmware Device exists,\r
739 // If yes, make it to 0 bytes\r
740 //\r
741 if ((Fp = fopen (OutFile, "w")) != NULL) {\r
742 fclose (Fp);\r
743 }\r
744\r
745 InFile = FileList;\r
746\r
747 while (*InFile != NULL) {\r
748 NumFvFiles++;\r
749 InFile++;\r
750 }\r
751\r
752 InitializeComps ();\r
753\r
754 //\r
755 // Restore the orginal pointers\r
756 //\r
757 FvInfo = OrgFvInfoPtr;\r
758 InFile = FileList;\r
759\r
760 while (*InFile != NULL) {\r
761 strcpy ((*FvInfo)->FvInfoFile, *InFile);\r
762 Status = GetFvRelatedInfoFromInfFile (*InFile);\r
763\r
764 if (Status != EFI_SUCCESS) {\r
765 printf ("\nERROR: Error occurred in processsing INF file");\r
766 CleanUpMemory ();\r
767 return Status;\r
768 }\r
769\r
770 InFile++;\r
771 FvInfo++;\r
772 }\r
773\r
774 FdInfo->FdSize = Size;\r
775 FdInfo->FdBaseAddress = BaseAddress;\r
776 FdInfo->PadValue = PadByte;\r
777 FvInfo = OrgFvInfoPtr;\r
778 strcpy (FdInfo->OutFileName, OutFile);\r
779\r
780 for (Index = 0; Index < NumFvFiles; Index++) {\r
781 Status = GenerateFvImage ((*FvInfo)->FvInfoFile);\r
782\r
783 if (Status != EFI_SUCCESS) {\r
784 CleanUpMemory ();\r
785 return Status;\r
786 }\r
787\r
788 FvInfo++;\r
789 }\r
790\r
791 FvInfo = OrgFvInfoPtr;\r
792\r
793 //\r
794 // Sort the Firmware Volume informations. Firmware Volume with lower\r
795 // base addresses will be processed first and hiher base address one\r
796 // will be processed later.\r
797 //\r
798 qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);\r
799\r
800 LastAddress = (*FvInfo)->FvBaseAddress;\r
801\r
802 for (Index = 0; Index < NumFvFiles; Index++) {\r
803 Status = BuildFirmwareDeviceBinaryFromFwVolumes (\r
804 (*FvInfo)->FvBaseAddress,\r
805 (*FvInfo)->FvFile,\r
806 FdInfo->OutFileName\r
807 );\r
808 if (Status != EFI_SUCCESS) {\r
809 CleanUpMemory ();\r
810 return Status;\r
811 }\r
812\r
813 FvInfo++;\r
814 }\r
815 //\r
816 // Check if any space left after copying data from all Firmware Volumes\r
817 // If yes, then fill those location with PadValue.\r
818 //\r
819 if ((FdInfo->FdBaseAddress + Size) > LastAddress) {\r
820\r
821 PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);\r
822 Buffer = malloc (PadSize);\r
823\r
824 if (Buffer == NULL) {\r
825 CleanUpMemory ();\r
826 return EFI_OUT_OF_RESOURCES;\r
827 }\r
828\r
829 for (Index = 0; Index < PadSize; Index++) {\r
830 *Buffer = FdInfo->PadValue;\r
831 Buffer++;\r
832 }\r
833\r
834 Buffer -= PadSize;\r
835\r
836 Fp = fopen (OutFile, "a+b");\r
837\r
838 if (Fp == NULL) {\r
839 printf ("\nERROR:Opening file %s", OutFile);\r
840 CleanUpMemory ();\r
841 return EFI_ABORTED;\r
842 }\r
843\r
844 FileSize = _filelength (fileno (Fp));\r
845 fseek (Fp, FileSize, SEEK_SET);\r
846 NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);\r
847\r
848 if (Buffer) {\r
849 free (Buffer);\r
850 }\r
851\r
852 fclose (Fp);\r
853\r
854 if (NumByte != (sizeof (UINT8) * PadSize)) {\r
855 printf ("\nERROR: Copying data from buffer to File %s ", OutFile);\r
856 CleanUpMemory ();\r
857 return EFI_ABORTED;\r
858 }\r
859 }\r
860 //\r
861 // Clean up all the memory which has been allocated so far.\r
862 //\r
863 CleanUpMemory ();\r
864 return EFI_SUCCESS;\r
865}\r