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