• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
Version(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
Usage(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
main(int argc,CHAR8 * argv[])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