1/** @file 2Calculate Crc32 value and Verify Crc32 value for input data. 3 4Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR> 5This program and the accompanying materials 6are licensed and made available under the terms and conditions of the BSD License 7which accompanies this distribution. The full text of the license may be found at 8http://opensource.org/licenses/bsd-license.php 9 10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11WITHOUT 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 32VOID 33Version ( 34 VOID 35 ) 36/*++ 37 38Routine Description: 39 40 Displays the standard utility information to SDTOUT 41 42Arguments: 43 44 None 45 46Returns: 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 55VOID 56Usage ( 57 VOID 58 ) 59/*++ 60 61Routine Description: 62 63 Displays the utility usage syntax to STDOUT 64 65Arguments: 66 67 None 68 69Returns: 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 106int 107main ( 108 int argc, 109 CHAR8 *argv[] 110 ) 111/*++ 112 113Routine Description: 114 115 Main function. 116 117Arguments: 118 119 argc - Number of command line parameters. 120 argv - Array of pointers to parameter strings. 121 122Returns: 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 parameters 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 fclose (InFile); 293 goto Finish; 294 } 295 296 fread (FileBuffer, 1, FileSize, InFile); 297 fclose (InFile); 298 VerboseMsg ("the size of the input file is %u bytes", (unsigned) FileSize); 299 300 // 301 // Open output file 302 // 303 OutFile = fopen (LongFilePath (OutputFileName), "wb"); 304 if (OutFile == NULL) { 305 Error (NULL, 0, 0001, "Error opening file", OutputFileName); 306 goto Finish; 307 } 308 309 // 310 // Calculate Crc32 value 311 // 312 if (FileAction == CRC32_ENCODE) { 313 Status = CalculateCrc32 (FileBuffer, FileSize, &Crc32Value); 314 if (Status != EFI_SUCCESS) { 315 Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!"); 316 goto Finish; 317 } 318 // 319 // Done, write output file. 320 // 321 fwrite (&Crc32Value, 1, sizeof (Crc32Value), OutFile); 322 VerboseMsg ("The calculated CRC32 value is 0x%08x", (unsigned) Crc32Value); 323 fwrite (FileBuffer, 1, FileSize, OutFile); 324 VerboseMsg ("the size of the encoded file is %u bytes", (unsigned) FileSize + sizeof (UINT32)); 325 } else { 326 // 327 // Verify Crc32 Value 328 // 329 Status = CalculateCrc32 (FileBuffer + sizeof (UINT32), FileSize - sizeof (UINT32), &Crc32Value); 330 if (Status != EFI_SUCCESS) { 331 Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!"); 332 goto Finish; 333 } 334 VerboseMsg ("The calculated CRC32 value is 0x%08x and File Crc32 value is 0x%08x", (unsigned) Crc32Value, (unsigned) (*(UINT32 *)FileBuffer)); 335 if (Crc32Value != *(UINT32 *)FileBuffer) { 336 Error (NULL, 0, 3000, "Invalid", "CRC32 value of input file is not correct!"); 337 Status = STATUS_ERROR; 338 goto Finish; 339 } 340 // 341 // Done, write output file. 342 // 343 fwrite (FileBuffer + sizeof (UINT32), 1, FileSize - sizeof (UINT32), OutFile); 344 VerboseMsg ("the size of the decoded file is %u bytes", (unsigned) FileSize - sizeof (UINT32)); 345 } 346 347Finish: 348 if (FileBuffer != NULL) { 349 free (FileBuffer); 350 } 351 352 if (OutFile != NULL) { 353 fclose (OutFile); 354 } 355 356 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ()); 357 358 return GetUtilityStatus (); 359} 360 361 362 363 364