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