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