Home | History | Annotate | Download | only in GenCrc32
      1 /** @file
      2 Calculate Crc32 value and Verify Crc32 value for input data.
      3 
      4 Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <string.h>
     18 
     19 #include "ParseInf.h"
     20 #include "EfiUtilityMsgs.h"
     21 #include "CommonLib.h"
     22 #include "Crc32.h"
     23 
     24 #define UTILITY_NAME            "GenCrc32"
     25 #define UTILITY_MAJOR_VERSION   0
     26 #define UTILITY_MINOR_VERSION   2
     27 
     28 #define CRC32_NULL              0
     29 #define CRC32_ENCODE            1
     30 #define CRC32_DECODE            2
     31 
     32 VOID
     33 Version (
     34   VOID
     35   )
     36 /*++
     37 
     38 Routine Description:
     39 
     40   Displays the standard utility information to SDTOUT
     41 
     42 Arguments:
     43 
     44   None
     45 
     46 Returns:
     47 
     48   None
     49 
     50 --*/
     51 {
     52   fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
     53 }
     54 
     55 VOID
     56 Usage (
     57   VOID
     58   )
     59 /*++
     60 
     61 Routine Description:
     62 
     63   Displays the utility usage syntax to STDOUT
     64 
     65 Arguments:
     66 
     67   None
     68 
     69 Returns:
     70 
     71   None
     72 
     73 --*/
     74 {
     75   //
     76   // Summary usage
     77   //
     78   fprintf (stdout, "Usage: GenCrc32 -e|-d [options] <input_file>\n\n");
     79 
     80   //
     81   // Copyright declaration
     82   //
     83   fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
     84 
     85   //
     86   // Details Option
     87   //
     88   fprintf (stdout, "optional arguments:\n");
     89   fprintf (stdout, "  -h, --help            Show this help message and exit\n");
     90   fprintf (stdout, "  --version             Show program's version number and exit\n");
     91   fprintf (stdout, "  --debug [DEBUG]       Output DEBUG statements, where DEBUG_LEVEL is 0 (min)\n\
     92                         - 9 (max)\n");
     93   fprintf (stdout, "  -v, --verbose         Print informational statements\n");
     94   fprintf (stdout, "  -q, --quiet           Returns the exit code, error messages will be\n\
     95                         displayed\n");
     96   fprintf (stdout, "  -s, --silent          Returns only the exit code; informational and error\n\
     97                         messages are not displayed\n");
     98   fprintf (stdout, "  -e, --encode          Calculate CRC32 value for the input file\n");
     99   fprintf (stdout, "  -d, --decode          Verify CRC32 value for the input file\n");
    100   fprintf (stdout, "  -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\
    101                         Output file name\n");
    102   fprintf (stdout, "  --sfo                 Reserved for future use\n");
    103 
    104 }
    105 
    106 int
    107 main (
    108   int   argc,
    109   CHAR8 *argv[]
    110   )
    111 /*++
    112 
    113 Routine Description:
    114 
    115   Main function.
    116 
    117 Arguments:
    118 
    119   argc - Number of command line parameters.
    120   argv - Array of pointers to parameter strings.
    121 
    122 Returns:
    123   STATUS_SUCCESS - Utility exits successfully.
    124   STATUS_ERROR   - Some error occurred during execution.
    125 
    126 --*/
    127 {
    128   EFI_STATUS              Status;
    129   CHAR8                   *OutputFileName;
    130   CHAR8                   *InputFileName;
    131   UINT8                   *FileBuffer;
    132   UINT32                  FileSize;
    133   UINT64                  LogLevel;
    134   UINT8                   FileAction;
    135   UINT32                  Crc32Value;
    136   FILE                    *InFile;
    137   FILE                    *OutFile;
    138 
    139   //
    140   // Init local variables
    141   //
    142   LogLevel       = 0;
    143   Status         = EFI_SUCCESS;
    144   InputFileName  = NULL;
    145   OutputFileName = NULL;
    146   FileAction     = CRC32_NULL;
    147   InFile         = NULL;
    148   OutFile        = NULL;
    149   Crc32Value     = 0;
    150   FileBuffer     = NULL;
    151 
    152   SetUtilityName (UTILITY_NAME);
    153 
    154   if (argc == 1) {
    155     Error (NULL, 0, 1001, "Missing options", "no options input");
    156     Usage ();
    157     return STATUS_ERROR;
    158   }
    159 
    160   //
    161   // Parse command line
    162   //
    163   argc --;
    164   argv ++;
    165 
    166   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
    167     Usage ();
    168     return STATUS_SUCCESS;
    169   }
    170 
    171   if (stricmp (argv[0], "--version") == 0) {
    172     Version ();
    173     return STATUS_SUCCESS;
    174   }
    175 
    176   while (argc > 0) {
    177     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
    178       if (argv[1] == NULL || argv[1][0] == '-') {
    179         Error (NULL, 0, 1003, "Invalid option value", "Output File name is missing for -o option");
    180         goto Finish;
    181       }
    182       OutputFileName = argv[1];
    183       argc -= 2;
    184       argv += 2;
    185       continue;
    186     }
    187 
    188     if ((stricmp (argv[0], "-e") == 0) || (stricmp (argv[0], "--encode") == 0)) {
    189       FileAction     = CRC32_ENCODE;
    190       argc --;
    191       argv ++;
    192       continue;
    193     }
    194 
    195     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--decode") == 0)) {
    196       FileAction     = CRC32_DECODE;
    197       argc --;
    198       argv ++;
    199       continue;
    200     }
    201 
    202     if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
    203       SetPrintLevel (VERBOSE_LOG_LEVEL);
    204       VerboseMsg ("Verbose output Mode Set!");
    205       argc --;
    206       argv ++;
    207       continue;
    208     }
    209 
    210     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
    211       SetPrintLevel (KEY_LOG_LEVEL);
    212       KeyMsg ("Quiet output Mode Set!");
    213       argc --;
    214       argv ++;
    215       continue;
    216     }
    217 
    218     if (stricmp (argv[0], "--debug") == 0) {
    219       Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
    220       if (EFI_ERROR (Status)) {
    221         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    222         goto Finish;
    223       }
    224       if (LogLevel > 9) {
    225         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
    226         goto Finish;
    227       }
    228       SetPrintLevel (LogLevel);
    229       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
    230       argc -= 2;
    231       argv += 2;
    232       continue;
    233     }
    234 
    235     if (argv[0][0] == '-') {
    236       Error (NULL, 0, 1000, "Unknown option", argv[0]);
    237       goto Finish;
    238     }
    239 
    240     //
    241     // Get Input file file name.
    242     //
    243     InputFileName = argv[0];
    244     argc --;
    245     argv ++;
    246   }
    247 
    248   VerboseMsg ("%s tool start.", UTILITY_NAME);
    249 
    250   //
    251   // Check Input paramters
    252   //
    253   if (FileAction == CRC32_NULL) {
    254     Error (NULL, 0, 1001, "Missing option", "either the encode or the decode option must be specified!");
    255     return STATUS_ERROR;
    256   } else if (FileAction == CRC32_ENCODE) {
    257     VerboseMsg ("File will be encoded by Crc32");
    258   } else if (FileAction == CRC32_DECODE) {
    259     VerboseMsg ("File will be decoded by Crc32");
    260   }
    261 
    262   if (InputFileName == NULL) {
    263     Error (NULL, 0, 1001, "Missing option", "Input files are not specified");
    264     goto Finish;
    265   } else {
    266     VerboseMsg ("Input file name is %s", InputFileName);
    267   }
    268 
    269   if (OutputFileName == NULL) {
    270     Error (NULL, 0, 1001, "Missing option", "Output file are not specified");
    271     goto Finish;
    272   } else {
    273     VerboseMsg ("Output file name is %s", OutputFileName);
    274   }
    275 
    276   //
    277   // Open Input file and read file data.
    278   //
    279   InFile = fopen (LongFilePath (InputFileName), "rb");
    280   if (InFile == NULL) {
    281     Error (NULL, 0, 0001, "Error opening file", InputFileName);
    282     return STATUS_ERROR;
    283   }
    284 
    285   fseek (InFile, 0, SEEK_END);
    286   FileSize = ftell (InFile);
    287   fseek (InFile, 0, SEEK_SET);
    288 
    289   FileBuffer = (UINT8 *) malloc (FileSize);
    290   if (FileBuffer == NULL) {
    291     Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated!");
    292     goto Finish;
    293   }
    294 
    295   fread (FileBuffer, 1, FileSize, InFile);
    296   fclose (InFile);
    297   VerboseMsg ("the size of the input file is %u bytes", (unsigned) FileSize);
    298 
    299   //
    300   // Open output file
    301   //
    302   OutFile = fopen (LongFilePath (OutputFileName), "wb");
    303   if (OutFile == NULL) {
    304     Error (NULL, 0, 0001, "Error opening file", OutputFileName);
    305     goto Finish;
    306   }
    307 
    308   //
    309   // Calculate Crc32 value
    310   //
    311   if (FileAction == CRC32_ENCODE) {
    312     Status = CalculateCrc32 (FileBuffer, FileSize, &Crc32Value);
    313     if (Status != EFI_SUCCESS) {
    314       Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!");
    315       goto Finish;
    316     }
    317     //
    318     // Done, write output file.
    319     //
    320     fwrite (&Crc32Value, 1, sizeof (Crc32Value), OutFile);
    321     VerboseMsg ("The calculated CRC32 value is 0x%08x", (unsigned) Crc32Value);
    322     fwrite (FileBuffer, 1, FileSize, OutFile);
    323     VerboseMsg ("the size of the encoded file is %u bytes", (unsigned) FileSize + sizeof (UINT32));
    324   } else {
    325     //
    326     // Verify Crc32 Value
    327     //
    328     Status = CalculateCrc32 (FileBuffer + sizeof (UINT32), FileSize - sizeof (UINT32), &Crc32Value);
    329     if (Status != EFI_SUCCESS) {
    330       Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!");
    331       goto Finish;
    332     }
    333     VerboseMsg ("The calculated CRC32 value is 0x%08x and File Crc32 value is 0x%08x", (unsigned) Crc32Value, (unsigned) (*(UINT32 *)FileBuffer));
    334     if (Crc32Value != *(UINT32 *)FileBuffer) {
    335       Error (NULL, 0, 3000, "Invalid", "CRC32 value of input file is not correct!");
    336       Status = STATUS_ERROR;
    337       goto Finish;
    338     }
    339     //
    340     // Done, write output file.
    341     //
    342     fwrite (FileBuffer + sizeof (UINT32), 1, FileSize - sizeof (UINT32), OutFile);
    343     VerboseMsg ("the size of the decoded file is %u bytes", (unsigned) FileSize - sizeof (UINT32));
    344   }
    345 
    346 Finish:
    347   if (FileBuffer != NULL) {
    348     free (FileBuffer);
    349   }
    350 
    351   if (OutFile != NULL) {
    352     fclose (OutFile);
    353   }
    354 
    355   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
    356 
    357   return GetUtilityStatus ();
    358 }
    359 
    360 
    361 
    362 
    363