]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/GenCRC32Section.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / GenCRC32Section / GenCRC32Section.c
CommitLineData
3eb9473e 1/*++\r
2\r
3e99020d 3Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
4b1e1121 4This program and the accompanying materials \r
3eb9473e 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 \r
14 GenCRC32Section.c\r
15\r
16Abstract:\r
17\r
18 This file contains functions required to generate a Firmware File System \r
19 file. The code is compliant with the Tiano C Coding standards.\r
20\r
21--*/\r
22\r
23#include "TianoCommon.h"\r
24#include "EfiFirmwareFileSystem.h"\r
25#include "EfiFirmwareVolumeHeader.h"\r
26#include "ParseInf.h"\r
27#include "crc32.h"\r
28#include "EfiUtilityMsgs.h"\r
29#include "GenCRC32Section.h"\r
30#include <stdio.h>\r
31#include <stdlib.h>\r
32#include <string.h>\r
33#include <assert.h>\r
34#include "CommonLib.h"\r
35\r
36#include EFI_PROTOCOL_DEFINITION (GuidedSectionExtraction)\r
37\r
3e99020d 38#define UTILITY_VERSION "v1.0"\r
3eb9473e 39\r
3e99020d 40#define UTILITY_NAME "GenCrc32Section"\r
3eb9473e 41\r
42EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
43\r
44EFI_STATUS\r
45SignSectionWithCrc32 (\r
46 IN OUT UINT8 *FileBuffer,\r
47 IN OUT UINT32 *BufferSize,\r
48 IN UINT32 DataSize\r
49 )\r
50/*++\r
51 \r
52Routine Description:\r
53 \r
54 Signs the section with CRC32 and add GUIDed section header for the \r
55 signed data. data stays in same location (overwrites source data).\r
56 \r
57Arguments:\r
58 \r
59 FileBuffer - Buffer containing data to sign\r
60 \r
61 BufferSize - On input, the size of FileBuffer. On output, the size of \r
62 actual section data (including added section header). \r
63\r
64 DataSize - Length of data to Sign\r
65\r
66 Key - Key to use when signing. Currently only CRC32 is supported.\r
67 \r
68Returns:\r
69 \r
70 EFI_SUCCESS - Successful\r
71 EFI_OUT_OF_RESOURCES - Not enough resource to complete the operation.\r
72 \r
73--*/\r
74{\r
75\r
76 UINT32 Crc32Checksum;\r
77 EFI_STATUS Status;\r
78 UINT32 TotalSize;\r
79 CRC32_SECTION_HEADER Crc32Header;\r
80 UINT8 *SwapBuffer;\r
81\r
82 Crc32Checksum = 0;\r
83 SwapBuffer = NULL;\r
84\r
85 if (DataSize == 0) {\r
86 *BufferSize = 0;\r
87\r
88 return EFI_SUCCESS;\r
89 }\r
90\r
91 Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum);\r
92 if (EFI_ERROR (Status)) {\r
93 return Status;\r
94 }\r
95\r
96 TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE;\r
97 Crc32Header.GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
98 Crc32Header.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff);\r
99 Crc32Header.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8);\r
100 Crc32Header.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16);\r
101 memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
102 Crc32Header.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
103 Crc32Header.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE;\r
104 Crc32Header.CRC32Checksum = Crc32Checksum;\r
105\r
106 SwapBuffer = (UINT8 *) malloc (DataSize);\r
107 if (SwapBuffer == NULL) {\r
108 return EFI_OUT_OF_RESOURCES;\r
109 }\r
110\r
111 memcpy (SwapBuffer, FileBuffer, DataSize);\r
112 memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE);\r
113 memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize);\r
114\r
115 //\r
116 // Make sure section ends on a DWORD boundary\r
117 //\r
118 while ((TotalSize & 0x03) != 0) {\r
119 FileBuffer[TotalSize] = 0;\r
120 TotalSize++;\r
121 }\r
122\r
123 *BufferSize = TotalSize;\r
124\r
125 if (SwapBuffer != NULL) {\r
126 free (SwapBuffer);\r
127 }\r
128\r
129 return EFI_SUCCESS;\r
130}\r
131\r
132VOID\r
133PrintUsage (\r
134 VOID\r
135 )\r
136{\r
3e99020d
LG
137 int Index;\r
138 const char *Str[] = {\r
139 UTILITY_NAME" "UTILITY_VERSION" - Intel Generate CRC32 Section Utility",\r
140 " Copyright (C), 2004 - 2008 Intel Corporation",\r
141 \r
142#if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )\r
143 " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,\r
144#endif\r
145 "",\r
146 "Usage:",\r
147 " "UTILITY_NAME" [OPTION]",\r
148 "Options:",\r
149 " -i Input1 ... specifies the input file(s) that would be signed to CRC32",\r
150 " Guided section.",\r
151 " -o Output specifies the output file that is a CRC32 Guided section",\r
152 NULL\r
153 };\r
154 for (Index = 0; Str[Index] != NULL; Index++) {\r
155 fprintf (stdout, "%s\n", Str[Index]);\r
156 }\r
3eb9473e 157}\r
158\r
159INT32\r
160ReadFilesContentsIntoBuffer (\r
161 IN CHAR8 *argv[],\r
162 IN INT32 Start,\r
163 IN OUT UINT8 **FileBuffer,\r
164 IN OUT UINT32 *BufferSize,\r
165 OUT UINT32 *ContentSize,\r
166 IN INT32 MaximumArguments\r
167 )\r
168{\r
169 INT32 Index;\r
170 CHAR8 *FileName;\r
171 FILE *InputFile;\r
172 UINT8 Temp;\r
173 UINT32 Size;\r
174\r
175 FileName = NULL;\r
176 InputFile = NULL;\r
177 Size = 0;\r
178 Index = 0;\r
179\r
180 //\r
181 // read all input files into one file buffer\r
182 //\r
183 while (argv[Start + Index][0] != '-') {\r
184\r
185 FileName = argv[Start + Index];\r
186 InputFile = fopen (FileName, "rb");\r
187 if (InputFile == NULL) {\r
188 Error (NULL, 0, 0, FileName, "failed to open input binary file");\r
189 return -1;\r
190 }\r
191\r
192 fread (&Temp, sizeof (UINT8), 1, InputFile);\r
193 while (!feof (InputFile)) {\r
194 (*FileBuffer)[Size++] = Temp;\r
195 fread (&Temp, sizeof (UINT8), 1, InputFile);\r
196 }\r
197\r
198 fclose (InputFile);\r
199 InputFile = NULL;\r
200\r
201 //\r
202 // Make sure section ends on a DWORD boundary\r
203 //\r
204 while ((Size & 0x03) != 0) {\r
205 (*FileBuffer)[Size] = 0;\r
206 Size++;\r
207 }\r
208\r
209 Index++;\r
210 if (Index == MaximumArguments) {\r
211 break;\r
212 }\r
213 }\r
214\r
215 *ContentSize = Size;\r
216 return Index;\r
217}\r
218\r
219INT32\r
220main (\r
221 INT32 argc,\r
222 CHAR8 *argv[]\r
223 )\r
224{\r
225 FILE *OutputFile;\r
226 UINT8 *FileBuffer;\r
227 UINT32 BufferSize;\r
228 EFI_STATUS Status;\r
229 UINT32 ContentSize;\r
230 CHAR8 *OutputFileName;\r
231 INT32 ReturnValue;\r
232 INT32 Index;\r
233\r
234 OutputFile = NULL;\r
235 FileBuffer = NULL;\r
236 ContentSize = 0;\r
237 OutputFileName = NULL;\r
238\r
239 SetUtilityName (UTILITY_NAME);\r
240\r
241 if (argc == 1) {\r
242 PrintUsage ();\r
243 return -1;\r
244 }\r
245\r
246 BufferSize = 1024 * 1024 * 16;\r
247 FileBuffer = (UINT8 *) malloc (BufferSize * sizeof (UINT8));\r
248 if (FileBuffer == NULL) {\r
249 Error (NULL, 0, 0, "memory allocation failed", NULL);\r
250 return -1;\r
251 }\r
252\r
253 ZeroMem (FileBuffer, BufferSize);\r
254\r
255 for (Index = 0; Index < argc; Index++) {\r
256 if (_strcmpi (argv[Index], "-i") == 0) {\r
257 ReturnValue = ReadFilesContentsIntoBuffer (\r
258 argv,\r
259 (Index + 1),\r
260 &FileBuffer,\r
261 &BufferSize,\r
262 &ContentSize,\r
263 (argc - (Index + 1))\r
264 );\r
265 if (ReturnValue == -1) {\r
266 Error (NULL, 0, 0, "failed to read file contents", NULL);\r
267 return -1;\r
268 }\r
269\r
270 Index += ReturnValue;\r
271 }\r
272\r
273 if (_strcmpi (argv[Index], "-o") == 0) {\r
274 OutputFileName = argv[Index + 1];\r
275 }\r
276 }\r
277\r
278 OutputFile = fopen (OutputFileName, "wb");\r
279 if (OutputFile == NULL) {\r
280 Error (NULL, 0, 0, OutputFileName, "failed to open output binary file");\r
281 free (FileBuffer);\r
282 return -1;\r
283 }\r
284\r
285 /* \r
286 //\r
287 // make sure section ends on a DWORD boundary ??\r
288 //\r
289 while ( (Size & 0x03) != 0 ) {\r
290 FileBuffer[Size] = 0;\r
291 Size ++;\r
292 }\r
293*/\r
294 Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize);\r
295 if (EFI_ERROR (Status)) {\r
296 Error (NULL, 0, 0, "failed to sign section", NULL);\r
297 free (FileBuffer);\r
298 fclose (OutputFile);\r
299 return -1;\r
300 }\r
301\r
302 ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile);\r
303 if (ContentSize != BufferSize) {\r
304 Error (NULL, 0, 0, "failed to write output buffer", NULL);\r
305 ReturnValue = -1;\r
306 } else {\r
307 ReturnValue = 0;\r
308 }\r
309\r
310 free (FileBuffer);\r
311 fclose (OutputFile);\r
312 return ReturnValue;\r
313}\r