EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

BaseTools/Source/C/EfiLdrImage/EfiLdrImage.c

Go to the documentation of this file.
00001 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include "ParseInf.h"
00034 #include "CommonLib.h"
00035 #include "EfiUtilityMsgs.h"
00036 
00037 #define MAX_PE_IMAGES                  63
00038 #define FILE_TYPE_FIXED_LOADER         0
00039 #define FILE_TYPE_RELOCATABLE_PE_IMAGE 1
00040 
00041 typedef struct {
00042   UINT32 CheckSum;
00043   UINT32 Offset;
00044   UINT32 Length;
00045   UINT8  FileName[52];
00046 } EFILDR_IMAGE;
00047 
00048 typedef struct {          
00049   UINT32       Signature;     
00050   UINT32       HeaderCheckSum;
00051   UINT32       FileLength;
00052   UINT32       NumberOfImages;
00053 } EFILDR_HEADER;
00054 
00055 //
00056 // Utility Name
00057 //
00058 #define UTILITY_NAME  "EfiLdrImage"
00059 
00060 //
00061 // Utility version information
00062 //
00063 #define UTILITY_MAJOR_VERSION 0
00064 #define UTILITY_MINOR_VERSION 1
00065 
00066 void
00067 Version (
00068   void
00069   )
00070 /*++
00071 
00072 Routine Description:
00073 
00074   Displays the standard utility information to SDTOUT
00075 
00076 Arguments:
00077 
00078   None
00079 
00080 Returns:
00081 
00082   None
00083 
00084 --*/
00085 {
00086   printf ("%s v%d.%d %s -Utility to break a file into two pieces at the request offset.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
00087   printf ("Copyright (c) 1999-2010 Intel Corporation. All rights reserved.\n");
00088 }
00089 
00090 VOID
00091 Usage (
00092   VOID
00093   )
00094 {
00095   printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");
00096   exit (1);
00097 }
00098 
00099 EFI_STATUS
00100 CountVerboseLevel (
00101   IN CONST CHAR8* VerboseLevelString,
00102   IN CONST UINT64 Length,
00103   OUT UINT64 *ReturnValue
00104 )
00105 {
00106   UINT64 i = 0;
00107   for (;i < Length; ++i) {
00108     if (VerboseLevelString[i] != 'v' && VerboseLevelString[i] != 'V') {
00109       return EFI_ABORTED;
00110     }
00111     ++(*ReturnValue);
00112   }
00113   
00114   return EFI_SUCCESS;
00115 }
00116 
00117 UINT64
00118 FCopyFile (
00119   FILE    *in,
00120   FILE    *out
00121   )
00122 /*++
00123 Routine Description:
00124   Write all the content of input file to output file.
00125 
00126 Arguments:
00127   in  - input file pointer
00128   out - output file pointer
00129 
00130 Return:
00131   UINT64 : file size of input file
00132 --*/
00133 {
00134   UINT32          filesize, offset, length;
00135   CHAR8           Buffer[8*1024];
00136 
00137   fseek (in, 0, SEEK_END);
00138   filesize = ftell(in);
00139 
00140   fseek (in, 0, SEEK_SET);
00141 
00142   offset = 0;
00143   while (offset < filesize)  {
00144     length = sizeof(Buffer);
00145     if (filesize-offset < length) {
00146       length = filesize-offset;
00147     }
00148 
00149     fread (Buffer, length, 1, in);
00150     fwrite (Buffer, length, 1, out);
00151     offset += length;
00152   }
00153 
00154   return filesize;
00155 }
00156 
00157 
00158 int
00159 main (
00160   int argc,
00161   char *argv[]
00162   )
00163 /*++
00164 
00165 Routine Description:
00166 
00167 
00168 Arguments:
00169 
00170 
00171 Returns:
00172 
00173 
00174 --*/
00175 {
00176   UINT64         i;
00177   UINT64         filesize;
00178   FILE          *fpIn, *fpOut;
00179   EFILDR_HEADER EfiLdrHeader;
00180   EFILDR_IMAGE  EfiLdrImage[MAX_PE_IMAGES];
00181   CHAR8* OutputFileName = NULL;
00182   CHAR8* InputFileNames[MAX_PE_IMAGES + 1];
00183   UINT8 InputFileCount = 0;
00184   UINT64        DebugLevel = 0;
00185   UINT64        VerboseLevel = 0;
00186   EFI_STATUS Status = EFI_SUCCESS;
00187   
00188   SetUtilityName (UTILITY_NAME);
00189 
00190   if (argc == 1) {
00191     Usage();
00192     return STATUS_ERROR;
00193   }
00194   
00195   argc --;
00196   argv ++;
00197 
00198   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
00199     Usage();
00200     return STATUS_SUCCESS;    
00201   }
00202 
00203   if (stricmp (argv[0], "--version") == 0) {
00204     Version();
00205     return STATUS_SUCCESS;    
00206   }
00207 
00208   while (argc > 0) {
00209    
00210     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
00211       OutputFileName = argv[1];
00212       if (OutputFileName == NULL) {
00213         Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");
00214         return STATUS_ERROR;
00215       }
00216       argc -= 2;
00217       argv += 2;
00218       continue; 
00219     }
00220     
00221     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
00222       argc --;
00223       argv ++;
00224       continue; 
00225     }
00226     
00227     if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (stricmp (argv[0], "--verbose") == 0)) {
00228       VerboseLevel = 1;
00229       if (strlen(argv[0]) > 2) {
00230         Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel);
00231         if (EFI_ERROR (Status)) {
00232           Error (NULL, 0, 1003, "Invalid option value", argv[0]);
00233           return STATUS_ERROR;        
00234         }
00235       }
00236       
00237       argc --;
00238       argv ++;
00239       continue; 
00240     }
00241     
00242     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
00243       Status = AsciiStringToUint64 (argv[1], FALSE, &DebugLevel);
00244       if (EFI_ERROR (Status)) {
00245         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
00246         return STATUS_ERROR;        
00247       }
00248       argc -= 2;
00249       argv += 2;
00250       continue; 
00251     }
00252     //
00253     // Don't recognize the parameter, should be regarded as the input file name.
00254     //
00255     InputFileNames[InputFileCount] = argv[0];
00256     InputFileCount++;
00257     argc--;
00258     argv++;
00259   }
00260 
00261   if (InputFileCount == 0) {
00262     Error (NULL, 0, 1001, "Missing option", "No input file");
00263     return STATUS_ERROR;
00264   }
00265   //
00266   // Open output file for write
00267   //
00268   if (OutputFileName == NULL) {
00269     Error (NULL, 0, 1001, "Missing option", "No output file");
00270     return STATUS_ERROR;
00271   }
00272 
00273   fpOut = fopen(OutputFileName, "w+b");
00274   if (!fpOut) {
00275     Error (NULL, 0, 0001, "Could not open output file", OutputFileName);
00276     return STATUS_ERROR;
00277   }
00278 
00279   memset (&EfiLdrHeader, 0, sizeof (EfiLdrHeader));
00280   memset (&EfiLdrImage, 0, sizeof (EFILDR_IMAGE) * (InputFileCount));
00281 
00282   memcpy (&EfiLdrHeader.Signature, "EFIL", 4);
00283   EfiLdrHeader.FileLength = sizeof(EFILDR_HEADER) + sizeof(EFILDR_IMAGE)*(InputFileCount);
00284 
00285   //
00286   // Skip the file header first
00287   //
00288   fseek (fpOut, EfiLdrHeader.FileLength, SEEK_SET);
00289 
00290   //
00291   // copy all the input files to the output file
00292   //
00293   for(i=0;i<InputFileCount;i++) {
00294     //
00295     // Copy the content of PeImage file to output file
00296     //
00297     fpIn = fopen (InputFileNames[i], "rb");
00298     if (!fpIn) {
00299       Error (NULL, 0, 0001, "Could not open input file", InputFileNames[i]);
00300       fclose (fpOut);
00301       return STATUS_ERROR;
00302     }
00303     filesize = FCopyFile (fpIn, fpOut);
00304     fclose(fpIn);
00305 
00306     //
00307     //  And in the same time update the EfiLdrHeader and EfiLdrImage array
00308     //
00309     EfiLdrImage[i].Offset = EfiLdrHeader.FileLength;
00310     EfiLdrImage[i].Length = (UINT32) filesize;
00311     strncpy ((CHAR8*) EfiLdrImage[i].FileName, InputFileNames[i], sizeof (EfiLdrImage[i].FileName) - 1);
00312     EfiLdrHeader.FileLength += (UINT32) filesize;
00313     EfiLdrHeader.NumberOfImages++;
00314   }
00315 
00316   //
00317   // Write the image header to the output file finally
00318   //
00319   fseek (fpOut, 0, SEEK_SET);
00320   fwrite (&EfiLdrHeader, sizeof(EFILDR_HEADER)        , 1, fpOut);
00321   fwrite (&EfiLdrImage , sizeof(EFILDR_IMAGE)*(InputFileCount), 1, fpOut);
00322 
00323   fclose (fpOut);
00324   printf ("Created %s\n", OutputFileName);
00325   return 0;
00326 }
00327 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines