VOID CVfrCompiler::GenRecordListFile ( VOID ) { CHAR8 *InFileName = NULL; FILE *pInFile = NULL; FILE *pOutFile = NULL; CHAR8 LineBuf[MAX_VFR_LINE_LEN]; UINT32 LineNo; InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName; if (mOptions.CreateRecordListFile == TRUE) { if ((InFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) { return; } if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) { DebugError (NULL, 0, 0001, "Error opening the input VFR preprocessor output file", InFileName); return; } if ((pOutFile = fopen (LongFilePath (mOptions.RecordListFile), "w")) == NULL) { DebugError (NULL, 0, 0001, "Error opening the record list file", mOptions.RecordListFile); goto Err1; } fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION __BUILD_VERSION "\n//\n"); LineNo = 0; while (!feof (pInFile)) { if (fgets (LineBuf, MAX_VFR_LINE_LEN, pInFile) != NULL) { fprintf (pOutFile, "%s", LineBuf); LineNo++; gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo); } } fprintf (pOutFile, "\n//\n// All Opcode Record List \n//\n"); gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, 0); gCVfrVarDataTypeDB.Dump(pOutFile); fclose (pOutFile); fclose (pInFile); } return; Err1: fclose (pInFile); }
VOID CVfrCompiler::GenBinary ( VOID ) { FILE *pFile = NULL; if (!IS_RUN_STATUS(STATUS_COMPILEED)) { goto Fail; } if (mOptions.CreateIfrPkgFile == TRUE) { if ((pFile = fopen (LongFilePath (mOptions.PkgOutputFileName), "wb")) == NULL) { DebugError (NULL, 0, 0001, "Error opening file", mOptions.PkgOutputFileName); goto Fail; } if (gCFormPkg.BuildPkg (pFile, &gRBuffer) != VFR_RETURN_SUCCESS) { fclose (pFile); goto Fail; } fclose (pFile); } SET_RUN_STATUS (STATUS_GENBINARY); return; Fail: if (!IS_RUN_STATUS(STATUS_DEAD)) { SET_RUN_STATUS (STATUS_FAILED); } }
BOOLEAN OsPathExists ( IN CHAR8 *InputFileName ) /*++ Routine Description: Checks if a file exists Arguments: InputFileName The name of the file to check for existence Returns: TRUE The file exists FALSE The file does not exist --*/ { FILE *InputFile; InputFile = fopen (LongFilePath (InputFileName), "rb"); if (InputFile == NULL) { return FALSE; } else { fclose (InputFile); return TRUE; } }
VOID CVfrCompiler::Compile ( VOID ) { FILE *pInFile = NULL; CHAR8 *InFileName = NULL; INPUT_INFO_TO_SYNTAX InputInfo; if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) { goto Fail; } InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName; gCVfrErrorHandle.SetInputFile (InFileName); gCVfrErrorHandle.SetWarningAsError(mOptions.WarningAsError); if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) { DebugError (NULL, 0, 0001, "Error opening the input file", "%s", InFileName); goto Fail; } InputInfo.CompatibleMode = mOptions.CompatibleMode; if (mOptions.HasOverrideClassGuid) { InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid; } else { InputInfo.OverrideClassGuid = NULL; } if (VfrParserStart (pInFile, &InputInfo) != 0) { goto Fail; } fclose (pInFile); pInFile = NULL; if (gCFormPkg.HavePendingUnassigned () == TRUE) { gCFormPkg.PendingAssignPrintAll (); goto Fail; } SET_RUN_STATUS (STATUS_COMPILEED); return; Fail: if (!IS_RUN_STATUS(STATUS_DEAD)) { DebugError (NULL, 0, 0003, "Error parsing", "compile error in file %s", InFileName); SET_RUN_STATUS (STATUS_FAILED); } if (pInFile != NULL) { fclose (pInFile); } }
VOID CVfrCompiler::GenCFile ( VOID ) { FILE *pFile; UINT32 Index; if (!IS_RUN_STATUS(STATUS_GENBINARY)) { goto Fail; } if (!mOptions.CreateIfrPkgFile || mOptions.CompatibleMode) { if ((pFile = fopen (LongFilePath (mOptions.COutputFileName), "w")) == NULL) { DebugError (NULL, 0, 0001, "Error opening output C file", mOptions.COutputFileName); goto Fail; } for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) { fprintf (pFile, "%s\n", gSourceFileHeader[Index]); } if (mOptions.CompatibleMode) { gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName); } if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile, &gRBuffer) != VFR_RETURN_SUCCESS) { fclose (pFile); goto Fail; } fclose (pFile); } SET_RUN_STATUS (STATUS_FINISHED); return; Fail: if (!IS_RUN_STATUS(STATUS_DEAD)) { SET_RUN_STATUS (STATUS_FAILED); } }
INT32 GenBinPage ( void *BaseMemory, char *NoPageFileName, char *PageFileName ) /*++ Routine Description: Write the buffer containing page table to file at a specified offset. Here the offset is defined as EFI_PAGE_BASE_OFFSET_IN_LDR. Arguments: BaseMemory - buffer containing page table NoPageFileName - file to write page table PageFileName - file save to after writing return: 0 : successful -1 : failed --*/ { FILE *PageFile; FILE *NoPageFile; UINT8 Data; unsigned long FileSize; // // Open files // PageFile = fopen (LongFilePath (PageFileName), "w+b"); if (PageFile == NULL) { Error (NoPageFileName, 0, 0x4002, "Invalid parameter option", "Output File %s open failure", PageFileName); return -1; } NoPageFile = fopen (LongFilePath (NoPageFileName), "r+b"); if (NoPageFile == NULL) { Error (NoPageFileName, 0, 0x4002, "Invalid parameter option", "Input File %s open failure", NoPageFileName); fclose (PageFile); return -1; } // // Check size - should not be great than EFI_PAGE_BASE_OFFSET_IN_LDR // fseek (NoPageFile, 0, SEEK_END); FileSize = ftell (NoPageFile); fseek (NoPageFile, 0, SEEK_SET); if (FileSize > gPageTableOffsetInFile) { Error (NoPageFileName, 0, 0x4002, "Invalid parameter option", "Input file size (0x%lx) exceeds the Page Table Offset (0x%x)", FileSize, (unsigned) gPageTableOffsetInFile); fclose (PageFile); fclose (NoPageFile); return -1; } // // Write data // while (fread (&Data, sizeof(UINT8), 1, NoPageFile)) { fwrite (&Data, sizeof(UINT8), 1, PageFile); } // // Write PageTable // fseek (PageFile, gPageTableOffsetInFile, SEEK_SET); fwrite (BaseMemory, (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE), 1, PageFile); // // Close files // fclose (PageFile); fclose (NoPageFile); return 0; }
int main ( int argc, char *argv[] ) /*++ Routine Description: Arguments: Returns: --*/ { UINT64 i; UINT64 filesize; FILE *fpIn, *fpOut; EFILDR_HEADER EfiLdrHeader; EFILDR_IMAGE EfiLdrImage[MAX_PE_IMAGES]; CHAR8* OutputFileName = NULL; CHAR8* InputFileNames[MAX_PE_IMAGES + 1]; UINT8 InputFileCount = 0; UINT64 DebugLevel = 0; UINT64 VerboseLevel = 0; EFI_STATUS Status = EFI_SUCCESS; SetUtilityName (UTILITY_NAME); if (argc == 1) { Usage(); return STATUS_ERROR; } argc --; argv ++; if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) { Usage(); return STATUS_SUCCESS; } if (stricmp (argv[0], "--version") == 0) { Version(); return STATUS_SUCCESS; } while (argc > 0) { if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) { OutputFileName = argv[1]; if (OutputFileName == NULL) { Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null"); return STATUS_ERROR; } argc -= 2; argv += 2; continue; } if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) { argc --; argv ++; continue; } if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (stricmp (argv[0], "--verbose") == 0)) { VerboseLevel = 1; if (strlen(argv[0]) > 2) { Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel); if (EFI_ERROR (Status)) { Error (NULL, 0, 1003, "Invalid option value", argv[0]); return STATUS_ERROR; } } argc --; argv ++; continue; } if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) { Status = AsciiStringToUint64 (argv[1], FALSE, &DebugLevel); if (EFI_ERROR (Status)) { Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); return STATUS_ERROR; } argc -= 2; argv += 2; continue; } // // Don't recognize the parameter, should be regarded as the input file name. // InputFileNames[InputFileCount] = argv[0]; InputFileCount++; argc--; argv++; } if (InputFileCount == 0) { Error (NULL, 0, 1001, "Missing option", "No input file"); return STATUS_ERROR; } // // Open output file for write // if (OutputFileName == NULL) { Error (NULL, 0, 1001, "Missing option", "No output file"); return STATUS_ERROR; } fpOut = fopen (LongFilePath (OutputFileName), "w+b"); if (!fpOut) { Error (NULL, 0, 0001, "Could not open output file", OutputFileName); return STATUS_ERROR; } memset (&EfiLdrHeader, 0, sizeof (EfiLdrHeader)); memset (&EfiLdrImage, 0, sizeof (EFILDR_IMAGE) * (InputFileCount)); memcpy (&EfiLdrHeader.Signature, "EFIL", 4); EfiLdrHeader.FileLength = sizeof(EFILDR_HEADER) + sizeof(EFILDR_IMAGE)*(InputFileCount); // // Skip the file header first // fseek (fpOut, EfiLdrHeader.FileLength, SEEK_SET); // // copy all the input files to the output file // for(i=0;i<InputFileCount;i++) { // // Copy the content of PeImage file to output file // fpIn = fopen (LongFilePath (InputFileNames[i]), "rb"); if (!fpIn) { Error (NULL, 0, 0001, "Could not open input file", InputFileNames[i]); fclose (fpOut); return STATUS_ERROR; } filesize = FCopyFile (fpIn, fpOut); fclose(fpIn); // // And in the same time update the EfiLdrHeader and EfiLdrImage array // EfiLdrImage[i].Offset = EfiLdrHeader.FileLength; EfiLdrImage[i].Length = (UINT32) filesize; strncpy ((CHAR8*) EfiLdrImage[i].FileName, InputFileNames[i], sizeof (EfiLdrImage[i].FileName) - 1); EfiLdrHeader.FileLength += (UINT32) filesize; EfiLdrHeader.NumberOfImages++; } // // Write the image header to the output file finally // fseek (fpOut, 0, SEEK_SET); fwrite (&EfiLdrHeader, sizeof(EFILDR_HEADER) , 1, fpOut); fwrite (&EfiLdrImage , sizeof(EFILDR_IMAGE)*(InputFileCount), 1, fpOut); fclose (fpOut); printf ("Created %s\n", OutputFileName); return 0; }
VOID CVfrCompiler::PreProcess ( VOID ) { FILE *pVfrFile = NULL; UINT32 CmdLen = 0; CHAR8 *PreProcessCmd = NULL; if (!IS_RUN_STATUS(STATUS_INITIALIZED)) { goto Fail; } if (mOptions.SkipCPreprocessor == TRUE) { goto Out; } if ((pVfrFile = fopen (LongFilePath (mOptions.VfrFileName), "r")) == NULL) { DebugError (NULL, 0, 0001, "Error opening the input VFR file", mOptions.VfrFileName); goto Fail; } fclose (pVfrFile); CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName); if (mOptions.CPreprocessorOptions != NULL) { CmdLen += strlen (mOptions.CPreprocessorOptions); } if (mOptions.IncludePaths != NULL) { CmdLen += strlen (mOptions.IncludePaths); } PreProcessCmd = new CHAR8[CmdLen + 10]; if (PreProcessCmd == NULL) { DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL); goto Fail; } strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " "); strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " "); if (mOptions.IncludePaths != NULL) { strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " "); } if (mOptions.CPreprocessorOptions != NULL) { strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " "); } strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > "); strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName); if (system (PreProcessCmd) != 0) { DebugError (NULL, 0, 0003, "Error parsing file", "failed to spawn C preprocessor on VFR file %s\n", PreProcessCmd); goto Fail; } delete PreProcessCmd; Out: SET_RUN_STATUS (STATUS_PREPROCESSED); return; Fail: if (!IS_RUN_STATUS(STATUS_DEAD)) { SET_RUN_STATUS (STATUS_FAILED); } delete PreProcessCmd; }
EFI_STATUS PutFileImage ( IN CHAR8 *OutputFileName, IN CHAR8 *OutputFileImage, IN UINT32 BytesToWrite ) /*++ Routine Description: This function opens a file and writes OutputFileImage into the file. Arguments: OutputFileName The name of the file to write. OutputFileImage A pointer to the memory buffer. BytesToWrite The size of the memory buffer. Returns: EFI_SUCCESS The function completed successfully. EFI_INVALID_PARAMETER One of the input parameters was invalid. EFI_ABORTED An error occurred. EFI_OUT_OF_RESOURCES No resource to complete operations. --*/ { FILE *OutputFile; UINT32 BytesWrote; // // Verify input parameters. // if (OutputFileName == NULL || strlen (OutputFileName) == 0 || OutputFileImage == NULL) { return EFI_INVALID_PARAMETER; } // // Open the file and copy contents into a memory buffer. // // // Open the file // OutputFile = fopen (LongFilePath (OutputFileName), "wb"); if (OutputFile == NULL) { Error (NULL, 0, 0001, "Error opening the output file", OutputFileName); return EFI_ABORTED; } // // Write all of the file contents. // BytesWrote = fwrite (OutputFileImage, sizeof (UINT8), BytesToWrite, OutputFile); if (BytesWrote != sizeof (UINT8) * BytesToWrite) { Error (NULL, 0, 0002, "Error writing the output file", OutputFileName); fclose (OutputFile); return EFI_ABORTED; } // // Close the file // fclose (OutputFile); return EFI_SUCCESS; }
EFI_STATUS GetFileImage ( IN CHAR8 *InputFileName, OUT CHAR8 **InputFileImage, OUT UINT32 *BytesRead ) /*++ Routine Description: This function opens a file and reads it into a memory buffer. The function will allocate the memory buffer and returns the size of the buffer. Arguments: InputFileName The name of the file to read. InputFileImage A pointer to the memory buffer. BytesRead The size of the memory buffer. Returns: EFI_SUCCESS The function completed successfully. EFI_INVALID_PARAMETER One of the input parameters was invalid. EFI_ABORTED An error occurred. EFI_OUT_OF_RESOURCES No resource to complete operations. --*/ { FILE *InputFile; UINT32 FileSize; // // Verify input parameters. // if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) { return EFI_INVALID_PARAMETER; } // // Open the file and copy contents into a memory buffer. // // // Open the file // InputFile = fopen (LongFilePath (InputFileName), "rb"); if (InputFile == NULL) { Error (NULL, 0, 0001, "Error opening the input file", InputFileName); return EFI_ABORTED; } // // Go to the end so that we can determine the file size // if (fseek (InputFile, 0, SEEK_END)) { Error (NULL, 0, 0004, "Error reading the input file", InputFileName); fclose (InputFile); return EFI_ABORTED; } // // Get the file size // FileSize = ftell (InputFile); if (FileSize == -1) { Error (NULL, 0, 0003, "Error parsing the input file", InputFileName); fclose (InputFile); return EFI_ABORTED; } // // Allocate a buffer // *InputFileImage = malloc (FileSize); if (*InputFileImage == NULL) { fclose (InputFile); return EFI_OUT_OF_RESOURCES; } // // Reset to the beginning of the file // if (fseek (InputFile, 0, SEEK_SET)) { Error (NULL, 0, 0004, "Error reading the input file", InputFileName); fclose (InputFile); free (*InputFileImage); *InputFileImage = NULL; return EFI_ABORTED; } // // Read all of the file contents. // *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile); if (*BytesRead != sizeof (UINT8) * FileSize) { Error (NULL, 0, 0004, "Error reading the input file", InputFileName); fclose (InputFile); free (*InputFileImage); *InputFileImage = NULL; return EFI_ABORTED; } // // Close the file // fclose (InputFile); return EFI_SUCCESS; }