-/*++\r
-Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved\r
-This software and associated documentation (if any) is furnished\r
-under a license and may only be used or copied in accordance\r
-with the terms of the license. Except as permitted by such\r
-license, no part of this software or documentation may be\r
-reproduced, stored in a retrieval system, or transmitted in any\r
-form or by any means without the express written consent of\r
-Intel Corporation.\r
-\r
-\r
- Module Name: \r
- GenFdImageDll.C\r
-\r
- Abstarct:\r
- This file contains the relevant functions required to complete\r
- the API to generate Firmware Device\r
---*/\r
-\r
-// GC_TODO: fix comment to add: Abstract:\r
-//\r
-// This tells the compiler to export the DLL functions\r
-//\r
-#define GEN_FD_IMAGE_EXPORTS\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <assert.h>\r
-\r
-#include <Common/UefiBaseTypes.h>\r
-\r
-#include "GenFdImage.h"\r
-#include "ParseInf.h"\r
-\r
-//\r
-// Global declaration\r
-//\r
-UINTN ValidLineNum = 0;\r
-\r
-UINTN NumFvFiles = 0;\r
-static UINT64 LastAddress = 0;\r
-\r
-CHAR8 **TokenStr;\r
-CHAR8 **OrgStrTokPtr;\r
-\r
-FDINFO *FdInfo;\r
-FDINFO *OrgFdInfoPtr;\r
-\r
-FVINFO **FvInfo;\r
-FVINFO **OrgFvInfoPtr;\r
-\r
-//\r
-// Global function declarations\r
-//\r
-EFI_STATUS\r
-BuildFirmwareDeviceBinaryFromFwVolumes (\r
- IN UINT64 FvBaseAddress,\r
- IN CHAR8 *FvFileName,\r
- IN CHAR8 *FdFileName\r
- );\r
-\r
-INTN\r
-CompareItems (\r
- IN const VOID *Arg1,\r
- IN const VOID *Arg2\r
- )\r
-/*++\r
-Description:\r
-\r
- This function is used by qsort to sort the Fv list based on FvBaseAddress\r
-\r
-Input:\r
- Arg1\r
- Arg2\r
-\r
-Return:\r
-\r
- None\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: Arg1 - add argument and description to function comment\r
-// GC_TODO: Arg2 - add argument and description to function comment\r
-{\r
- if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {\r
- return 1;\r
- } else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {\r
- return -1;\r
- } else {\r
- return 0;\r
- }\r
-}\r
-\r
-VOID\r
-BuildTokenList (\r
- IN CHAR8 *Token\r
- )\r
-/*++\r
-Description:\r
-\r
- This function builds the token list in an array which will be parsed later\r
-\r
-Input:\r
- Token String,\r
-\r
-Return:\r
-\r
- None\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: Token - add argument and description to function comment\r
-{\r
-\r
- strcpy (*TokenStr, Token);\r
- TokenStr++;\r
-}\r
-\r
-VOID\r
-TrimLine (\r
- IN CHAR8 *Line\r
- )\r
-/*++\r
-Description:\r
-\r
- This function cleans up the line by removing all whitespace and \r
- comments\r
-\r
-Input:\r
-\r
- Line String,\r
-\r
-Return:\r
- None\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: Line - add argument and description to function comment\r
-{\r
- CHAR8 TmpLine[FILE_NAME_SIZE];\r
- CHAR8 c;\r
- CHAR8 *Ptr0;\r
- UINTN i;\r
- UINTN j;\r
-\r
- //\r
- // Change '#' to '//' for Comment style\r
- //\r
- // if((Ptr0=strchr(Line, '#')) != NULL) {\r
- //\r
- if ((Ptr0 = strstr (Line, "//")) != NULL) {\r
- Line[Ptr0 - Line] = 0;\r
- }\r
-\r
- i = j = 0;\r
-\r
- while ((c = Line[i]) != 0) {\r
- if ((c != ' ') && (c != '\t') && (c != '\n')) {\r
- TmpLine[j++] = c;\r
- }\r
-\r
- i++;\r
- }\r
-\r
- TmpLine[j] = 0;\r
- strcpy (Line, TmpLine);\r
-}\r
-\r
-VOID\r
-ValidLineCount (\r
- IN FILE *Fp\r
- )\r
-/*++\r
-\r
-Description:\r
-\r
- This function calculated number of valid lines in a input file.\r
- \r
-Input:\r
-\r
- Fp Pointer to a file handle which has been opened.\r
-\r
-Return:\r
-\r
- None\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: Fp - add argument and description to function comment\r
-{\r
- CHAR8 Buff[FILE_NAME_SIZE];\r
-\r
- while (fgets (Buff, sizeof (Buff), Fp)) {\r
- TrimLine (Buff);\r
- if (Buff[0] == 0) {\r
- continue;\r
- }\r
-\r
- ValidLineNum++;\r
- }\r
-}\r
-\r
-VOID\r
-ParseInputFile (\r
- IN FILE *Fp\r
- )\r
-/*++\r
- \r
-Description:\r
-\r
- This function parses the input file and tokenize the string\r
- \r
-Input:\r
-\r
- Fp Pointer to a file handle which has been opened.\r
- \r
-Return:\r
-\r
- None\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: Fp - add argument and description to function comment\r
-{\r
- CHAR8 *Token;\r
- CHAR8 Buff[FILE_NAME_SIZE];\r
- CHAR8 OrgLine[FILE_NAME_SIZE];\r
- CHAR8 Str[FILE_NAME_SIZE];\r
- CHAR8 Delimit[] = "=";\r
-\r
- while (fgets (Buff, sizeof (Buff), Fp) != NULL) {\r
- strcpy (OrgLine, Buff);\r
- TrimLine (Buff);\r
-\r
- if (Buff[0] == 0) {\r
- continue;\r
- }\r
-\r
- Token = strtok (Buff, Delimit);\r
-\r
- while (Token != NULL) {\r
- strcpy (Str, Token);\r
- BuildTokenList (Str);\r
- Token = strtok (NULL, Delimit);\r
- }\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-InitializeComps (\r
- VOID\r
- )\r
-/*++\r
-\r
-Description:\r
-\r
- This function intializes the relevant global variable which is being\r
- used to store the information retrieved from INF file.\r
- \r
-Input:\r
-\r
- None\r
-\r
-Return:\r
-\r
- EFI_STATUS\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// GC_TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINTN Index;\r
-\r
- FdInfo = malloc (sizeof (FDINFO));\r
-\r
- if (FdInfo == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- OrgFdInfoPtr = FdInfo;\r
-\r
- FvInfo = malloc (sizeof (int) * NumFvFiles);\r
-\r
- if (FvInfo == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- OrgFvInfoPtr = FvInfo;\r
-\r
- for (Index = 0; Index < NumFvFiles; Index++) {\r
- *FvInfo = malloc (sizeof (FVINFO));\r
-\r
- if (*FvInfo == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (*FvInfo, 0, sizeof (FVINFO));\r
- FvInfo++;\r
- }\r
-\r
- FvInfo = OrgFvInfoPtr;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-InitializeInFileInfo (\r
- VOID\r
- )\r
-/*++\r
-\r
-Description:\r
-\r
- This function intializes the relevant global variable which is being\r
- used to store the information retrieved from INF file.\r
-\r
-Input:\r
-\r
- NONE\r
-\r
-Return:\r
-\r
- NONE\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-{\r
- UINTN OptionFlag;\r
- UINT64 StringValue;\r
-\r
- OptionFlag = 0;\r
- TokenStr = OrgStrTokPtr;\r
-\r
- while (*TokenStr != NULL) {\r
- if (stricmp (*TokenStr, "[options]") == 0) {\r
- OptionFlag = 1;\r
- }\r
-\r
- if (OptionFlag) {\r
- if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {\r
- *TokenStr++;\r
- if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
- printf ("\nERROR: Cannot determine the FV base address.");\r
- return ;\r
- }\r
- (*FvInfo)->FvBaseAddress = StringValue;\r
- } else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {\r
- *TokenStr++;\r
- strcpy ((*FvInfo)->FvFile, *TokenStr);\r
- }\r
- }\r
-\r
- TokenStr++;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-GetFvRelatedInfoFromInfFile (\r
- IN CHAR8 *FileName\r
- )\r
-/*++\r
- \r
-Description:\r
-\r
- This function reads the input file, parse it and create a list of tokens\r
- which is parsed and used, to intialize the data related to Firmware Volume.\r
- \r
-Input:\r
-\r
- FileName FileName which needed to be read to parse data\r
-\r
-Return:\r
-\r
- EFI_STATUS\r
- \r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: FileName - add argument and description to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- FILE *Fp;\r
- UINTN Index;\r
-\r
- Fp = fopen (FileName, "r");\r
-\r
- if (Fp == NULL) {\r
- printf ("Error in opening %s file\n", FileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- ValidLineCount (Fp);\r
-\r
- if (ValidLineNum == 0) {\r
- printf ("\nFile doesn't contain any valid informations");\r
- return EFI_ABORTED;\r
- }\r
-\r
- TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));\r
- memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));\r
- OrgStrTokPtr = TokenStr;\r
-\r
- for (Index = 0; Index < (2 * ValidLineNum); Index++) {\r
- *TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);\r
- memset (*TokenStr, 0, FILE_NAME_SIZE);\r
- TokenStr++;\r
- }\r
-\r
- *TokenStr = NULL;\r
- TokenStr = OrgStrTokPtr;\r
- fseek (Fp, 0L, SEEK_SET);\r
-\r
- ParseInputFile (Fp);\r
- InitializeInFileInfo ();\r
-\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-WriteFwBinary (\r
- IN CHAR8 *FileName,\r
- IN UINT64 StartAddress,\r
- IN UINT64 Size,\r
- IN UINT8 *Buffer\r
- )\r
-/*++\r
- \r
-Description:\r
-\r
- This function reads the input file, parse it and create a list of tokens\r
- which is parsed and used, to intialize the data related to Firmware Volume.\r
- \r
-Input:\r
-\r
- FileName FileName which needed to be read to parse data\r
- StartAddress This will set the file position.\r
- Size Size in bytes needed to be written\r
- Buffer Buffer needed to e written\r
-\r
-Return:\r
-\r
- EFI_STATUS\r
- \r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: FileName - add argument and description to function comment\r
-// GC_TODO: StartAddress - add argument and description to function comment\r
-// GC_TODO: Size - add argument and description to function comment\r
-// GC_TODO: Buffer - add argument and description to function comment\r
-// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- FILE *Fp;\r
- UINTN NumByte;\r
-\r
- Fp = fopen (FileName, "a+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR:Error in opening file %s ", FileName);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- fseek (Fp, (UINTN) StartAddress, SEEK_SET);\r
- NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);\r
-\r
- //\r
- // Check to ensure that buffer has been copied successfully\r
- //\r
- if (NumByte != Size) {\r
- printf ("\nERROR: Error in copying the buffer into file");\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BuildFirmwareDeviceBinaryFromFwVolumes (\r
- IN UINT64 FvBaseAddress,\r
- IN CHAR8 *FvFileName,\r
- IN CHAR8 *FdFileName\r
- )\r
-/*++\r
- \r
-Description:\r
-\r
- This function reads the input file, parse it and create a list of tokens\r
- which is parsed and used, to intialize the data related to Firmware Volume.\r
- \r
-Input:\r
-\r
- FvBaseAddress Base Address. This info is retrieved from INF file\r
- FvFileName InputFileName\r
- FdFileName Output File Name\r
-\r
-Return:\r
-\r
- EFI_STATUS\r
- \r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: FvBaseAddress - add argument and description to function comment\r
-// GC_TODO: FvFileName - add argument and description to function comment\r
-// GC_TODO: FdFileName - add argument and description to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// GC_TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- FILE *Fp;\r
- UINT64 FileSize;\r
- UINT64 NumByteRead;\r
- UINT64 PadByteSize;\r
- UINTN Index;\r
- UINT64 BaseAddress;\r
- UINT8 *Buffer;\r
- EFI_STATUS Status;\r
- static UINT64 StartAddress = 0;\r
-\r
- Fp = fopen (FvFileName, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR:Error in opening file %s", FvFileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- BaseAddress = FdInfo->FdBaseAddress;\r
-\r
- //\r
- // Check if Base Address of Firmware Volume falls below the Base Address\r
- // Firmware Device, if yes, then abort this process.\r
- //\r
- if (FvBaseAddress < BaseAddress) {\r
- printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Check if there are any hole between two Firmware Volumes. If any hole\r
- // exists, fill the hole with PadByte data.\r
- //\r
- if (FvBaseAddress > LastAddress) {\r
- PadByteSize = (FvBaseAddress - LastAddress);\r
- Buffer = malloc ((UINTN) PadByteSize);\r
-\r
- for (Index = 0; Index < PadByteSize; Index++) {\r
- *Buffer = FdInfo->PadValue;\r
- Buffer++;\r
- }\r
-\r
- Buffer -= PadByteSize;\r
- Status = WriteFwBinary (FdFileName, StartAddress, (UINT64) PadByteSize, Buffer);\r
-\r
- if (Buffer) {\r
- free (Buffer);\r
- }\r
-\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Error in writing the binary image to file");\r
- return Status;\r
- }\r
-\r
- StartAddress += PadByteSize;\r
- LastAddress += PadByteSize;\r
- }\r
- //\r
- // Proceed with next Firmware Volume updates\r
- //\r
- FileSize = _filelength (fileno (Fp));\r
-\r
- if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {\r
- printf (\r
- "\nERROR:Unable to update Firmware Device. File %s is larger than \\r
- available space.",\r
- FvFileName\r
- );\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
-\r
- return EFI_ABORTED;\r
- }\r
-\r
- Buffer = malloc ((UINTN) FileSize);\r
-\r
- if (Buffer == NULL) {\r
- printf ("Error in allocating buffer to read specific file\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
-\r
- Status = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);\r
-\r
- if (Buffer) {\r
- free ((VOID *) Buffer);\r
- }\r
-\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
-\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Error in writing the binary image to file");\r
- return Status;\r
- }\r
-\r
- StartAddress += NumByteRead;\r
- LastAddress += FileSize;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-CleanUpMemory (\r
- VOID\r
- )\r
-/*++\r
-\r
-Description:\r
-\r
- This function cleans up any allocated buffer\r
- \r
-Input:\r
-\r
- NONE\r
-\r
-Return:\r
- \r
- NONE\r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-{\r
- UINTN Index;\r
-\r
- if (FdInfo) {\r
- free (FdInfo);\r
- }\r
-\r
- FvInfo = OrgFvInfoPtr;\r
-\r
- if (FvInfo) {\r
- for (Index = 0; Index < NumFvFiles; Index++) {\r
- if (*FvInfo) {\r
- free (*FvInfo);\r
- }\r
-\r
- FvInfo++;\r
- }\r
-\r
- FvInfo = OrgFvInfoPtr;\r
- free (FvInfo);\r
- }\r
-}\r
-\r
-GEN_FD_IMAGE_API\r
-EFI_STATUS\r
-GenerateFdImage (\r
- IN UINT64 BaseAddress,\r
- IN UINT64 Size,\r
- IN UINT8 PadByte,\r
- IN CHAR8 *OutFile,\r
- IN CHAR8 **FileList\r
- )\r
-/*++\r
- \r
-Description:\r
-\r
- This function reads the input file, parse it and create a list of tokens\r
- which is parsed and used, to intialize the data related to Firmware Volume.\r
- \r
-Input:\r
-\r
- BaseAddress Base Address for this Firmware Device\r
- Size, Total Size of the Firmware Device\r
- PadByte Pad byte data\r
- OutFile Output File Name\r
- FileList File List pointer to INF file names.\r
-\r
-Return:\r
-\r
- EFI_STATUS\r
- \r
---*/\r
-// GC_TODO: function comment is missing 'Routine Description:'\r
-// GC_TODO: function comment is missing 'Arguments:'\r
-// GC_TODO: function comment is missing 'Returns:'\r
-// GC_TODO: BaseAddress - add argument and description to function comment\r
-// GC_TODO: Size - add argument and description to function comment\r
-// GC_TODO: PadByte - add argument and description to function comment\r
-// GC_TODO: OutFile - add argument and description to function comment\r
-// GC_TODO: FileList - add argument and description to function comment\r
-// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_ABORTED - add return value to function comment\r
-// GC_TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN PadSize;\r
- UINTN FileSize;\r
- CHAR8 **InFile;\r
- FILE *Fp;\r
- UINT8 *Buffer;\r
- UINTN NumByte;\r
-\r
- //\r
- // Ensure, if there are any previous Firmware Device exists,\r
- // If yes, make it to 0 bytes\r
- //\r
- if ((Fp = fopen (OutFile, "w")) != NULL) {\r
- fclose (Fp);\r
- }\r
-\r
- InFile = FileList;\r
-\r
- while (*InFile != NULL) {\r
- NumFvFiles++;\r
- InFile++;\r
- }\r
-\r
- InitializeComps ();\r
-\r
- //\r
- // Restore the orginal pointers\r
- //\r
- FvInfo = OrgFvInfoPtr;\r
- InFile = FileList;\r
-\r
- while (*InFile != NULL) {\r
- strcpy ((*FvInfo)->FvInfoFile, *InFile);\r
- Status = GetFvRelatedInfoFromInfFile (*InFile);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Error occurred in processsing INF file");\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
-\r
- InFile++;\r
- FvInfo++;\r
- }\r
-\r
- FdInfo->FdSize = Size;\r
- FdInfo->FdBaseAddress = BaseAddress;\r
- FdInfo->PadValue = PadByte;\r
- FvInfo = OrgFvInfoPtr;\r
- strcpy (FdInfo->OutFileName, OutFile);\r
-\r
- for (Index = 0; Index < NumFvFiles; Index++) {\r
- Status = GenerateFvImage ((*FvInfo)->FvInfoFile);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
-\r
- FvInfo++;\r
- }\r
-\r
- FvInfo = OrgFvInfoPtr;\r
-\r
- //\r
- // Sort the Firmware Volume informations. Firmware Volume with lower\r
- // base addresses will be processed first and hiher base address one\r
- // will be processed later.\r
- //\r
- qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);\r
-\r
- LastAddress = (*FvInfo)->FvBaseAddress;\r
-\r
- for (Index = 0; Index < NumFvFiles; Index++) {\r
- Status = BuildFirmwareDeviceBinaryFromFwVolumes (\r
- (*FvInfo)->FvBaseAddress,\r
- (*FvInfo)->FvFile,\r
- FdInfo->OutFileName\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
-\r
- FvInfo++;\r
- }\r
- //\r
- // Check if any space left after copying data from all Firmware Volumes\r
- // If yes, then fill those location with PadValue.\r
- //\r
- if ((FdInfo->FdBaseAddress + Size) > LastAddress) {\r
-\r
- PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);\r
- Buffer = malloc (PadSize);\r
-\r
- if (Buffer == NULL) {\r
- CleanUpMemory ();\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- for (Index = 0; Index < PadSize; Index++) {\r
- *Buffer = FdInfo->PadValue;\r
- Buffer++;\r
- }\r
-\r
- Buffer -= PadSize;\r
-\r
- Fp = fopen (OutFile, "a+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR:Opening file %s", OutFile);\r
- CleanUpMemory ();\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = _filelength (fileno (Fp));\r
- fseek (Fp, FileSize, SEEK_SET);\r
- NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);\r
-\r
- if (Buffer) {\r
- free (Buffer);\r
- }\r
-\r
- fclose (Fp);\r
-\r
- if (NumByte != (sizeof (UINT8) * PadSize)) {\r
- printf ("\nERROR: Copying data from buffer to File %s ", OutFile);\r
- CleanUpMemory ();\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Clean up all the memory which has been allocated so far.\r
- //\r
- CleanUpMemory ();\r
- return EFI_SUCCESS;\r
-}\r