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