]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/GenCrc32/GenCrc32.c
369f4affa917ba52905556199a2591998c6aef8a
[mirror_edk2.git] / BaseTools / Source / C / GenCrc32 / GenCrc32.c
1 /** @file
2 Calculate Crc32 value and Verify Crc32 value for input data.
3
4 Copyright (c) 2007 - 2018, 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 - 2018, 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 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 if (FileSize < sizeof (UINT32)) {
330 Error (NULL, 0, 3000, "Invalid", "Input file is invalid!");
331 goto Finish;
332 }
333 Status = CalculateCrc32 (FileBuffer + sizeof (UINT32), FileSize - sizeof (UINT32), &Crc32Value);
334 if (Status != EFI_SUCCESS) {
335 Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!");
336 goto Finish;
337 }
338 VerboseMsg ("The calculated CRC32 value is 0x%08x and File Crc32 value is 0x%08x", (unsigned) Crc32Value, (unsigned) (*(UINT32 *)FileBuffer));
339 if (Crc32Value != *(UINT32 *)FileBuffer) {
340 Error (NULL, 0, 3000, "Invalid", "CRC32 value of input file is not correct!");
341 Status = STATUS_ERROR;
342 goto Finish;
343 }
344 //
345 // Done, write output file.
346 //
347 fwrite (FileBuffer + sizeof (UINT32), 1, FileSize - sizeof (UINT32), OutFile);
348 VerboseMsg ("the size of the decoded file is %u bytes", (unsigned) FileSize - sizeof (UINT32));
349 }
350
351 Finish:
352 if (FileBuffer != NULL) {
353 free (FileBuffer);
354 }
355
356 if (OutFile != NULL) {
357 fclose (OutFile);
358 }
359
360 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
361
362 return GetUtilityStatus ();
363 }
364
365
366
367