]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/CCode/Source/GenCRC32Section/GenCRC32Section.c
- Fixed PVCS tracker 484 by merging the GenDll and GenEfi macro in BuildMacro.xml...
[mirror_edk2.git] / Tools / CCode / Source / GenCRC32Section / GenCRC32Section.c
CommitLineData
878ddf1f 1/*++\r
2\r
52be9a3b 3Copyright (c) 2004-2007, Intel Corporation \r
878ddf1f 4All rights reserved. This program and the accompanying materials \r
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 "GenCRC32Section.h"\r
24\r
52be9a3b 25#define UTILITY_NAME "GenCrc32Section"\r
26#define UTILITY_MAJOR_VERSION 0\r
27#define UTILITY_MINOR_VERSION 2\r
878ddf1f 28\r
29EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
30\r
31EFI_STATUS\r
32SignSectionWithCrc32 (\r
33 IN OUT UINT8 *FileBuffer,\r
34 IN OUT UINT32 *BufferSize,\r
35 IN UINT32 DataSize\r
36 )\r
37/*++\r
38 \r
39Routine Description:\r
40 \r
41 Signs the section with CRC32 and add GUIDed section header for the \r
42 signed data. data stays in same location (overwrites source data).\r
43 \r
44Arguments:\r
45 \r
46 FileBuffer - Buffer containing data to sign\r
47 \r
48 BufferSize - On input, the size of FileBuffer. On output, the size of \r
49 actual section data (including added section header). \r
50\r
51 DataSize - Length of data to Sign\r
52\r
53 Key - Key to use when signing. Currently only CRC32 is supported.\r
54 \r
55Returns:\r
56 \r
57 EFI_SUCCESS - Successful\r
58 EFI_OUT_OF_RESOURCES - Not enough resource to complete the operation.\r
59 \r
60--*/\r
61{\r
62\r
63 UINT32 Crc32Checksum;\r
64 EFI_STATUS Status;\r
65 UINT32 TotalSize;\r
66 CRC32_SECTION_HEADER Crc32Header;\r
67 UINT8 *SwapBuffer;\r
68\r
69 Crc32Checksum = 0;\r
70 SwapBuffer = NULL;\r
71\r
72 if (DataSize == 0) {\r
73 *BufferSize = 0;\r
74\r
75 return EFI_SUCCESS;\r
76 }\r
77\r
78 Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum);\r
79 if (EFI_ERROR (Status)) {\r
80 return Status;\r
81 }\r
82\r
83 TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE;\r
84 Crc32Header.GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
85 Crc32Header.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff);\r
86 Crc32Header.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8);\r
87 Crc32Header.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16);\r
88 memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
89 Crc32Header.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
90 Crc32Header.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE;\r
91 Crc32Header.CRC32Checksum = Crc32Checksum;\r
92\r
93 SwapBuffer = (UINT8 *) malloc (DataSize);\r
94 if (SwapBuffer == NULL) {\r
95 return EFI_OUT_OF_RESOURCES;\r
96 }\r
97\r
98 memcpy (SwapBuffer, FileBuffer, DataSize);\r
99 memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE);\r
100 memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize);\r
101\r
102 //\r
103 // Make sure section ends on a DWORD boundary\r
104 //\r
105 while ((TotalSize & 0x03) != 0) {\r
106 FileBuffer[TotalSize] = 0;\r
107 TotalSize++;\r
108 }\r
109\r
110 *BufferSize = TotalSize;\r
111\r
112 if (SwapBuffer != NULL) {\r
113 free (SwapBuffer);\r
114 }\r
115\r
116 return EFI_SUCCESS;\r
117}\r
118\r
119VOID\r
52be9a3b 120Version (\r
878ddf1f 121 VOID\r
122 )\r
52be9a3b 123/*++\r
124\r
125Routine Description:\r
126\r
127 Displays the standard utility information to SDTOUT\r
128\r
129Arguments:\r
130\r
131 None\r
132\r
133Returns:\r
134\r
135 None\r
136\r
137--*/\r
878ddf1f 138{\r
52be9a3b 139 printf (\r
140 "%s v%d.%d -Utility for generating Firmware File System files.\n",\r
141 UTILITY_NAME,\r
142 UTILITY_MAJOR_VERSION,\r
143 UTILITY_MINOR_VERSION\r
144 );\r
145}\r
146\r
147\r
148VOID\r
149Usage (\r
150 VOID\r
151 )\r
152{\r
153 Version();\r
154 \r
155 printf ("\nUsage:\n");\r
156 printf (UTILITY_NAME " -i Inputfile1 Inputfile2 -o Outputfile\n");\r
157 printf (" -i Inputfile: specifies the input files signed to CRC32 Guided section.\n");\r
158 printf (" -o Outputfile: specifies the output file that is a CRC32 Guided section.\n");\r
878ddf1f 159}\r
160\r
161INT32\r
162ReadFilesContentsIntoBuffer (\r
163 IN CHAR8 *argv[],\r
164 IN INT32 Start,\r
165 IN OUT UINT8 **FileBuffer,\r
166 IN OUT UINT32 *BufferSize,\r
167 OUT UINT32 *ContentSize,\r
168 IN INT32 MaximumArguments\r
169 )\r
170{\r
171 INT32 Index;\r
172 CHAR8 *FileName;\r
173 FILE *InputFile;\r
174 UINT8 Temp;\r
175 UINT32 Size;\r
176\r
177 FileName = NULL;\r
178 InputFile = NULL;\r
179 Size = 0;\r
180 Index = 0;\r
181\r
182 //\r
183 // read all input files into one file buffer\r
184 //\r
185 while (argv[Start + Index][0] != '-') {\r
186\r
187 FileName = argv[Start + Index];\r
188 InputFile = fopen (FileName, "rb");\r
189 if (InputFile == NULL) {\r
190 Error (NULL, 0, 0, FileName, "failed to open input binary file");\r
191 return -1;\r
192 }\r
193\r
194 fread (&Temp, sizeof (UINT8), 1, InputFile);\r
195 while (!feof (InputFile)) {\r
196 (*FileBuffer)[Size++] = Temp;\r
197 fread (&Temp, sizeof (UINT8), 1, InputFile);\r
198 }\r
199\r
200 fclose (InputFile);\r
201 InputFile = NULL;\r
202\r
203 //\r
204 // Make sure section ends on a DWORD boundary\r
205 //\r
206 while ((Size & 0x03) != 0) {\r
207 (*FileBuffer)[Size] = 0;\r
208 Size++;\r
209 }\r
210\r
211 Index++;\r
212 if (Index == MaximumArguments) {\r
213 break;\r
214 }\r
215 }\r
216\r
217 *ContentSize = Size;\r
218 return Index;\r
219}\r
220\r
221int\r
222main (\r
223 INT32 argc,\r
224 CHAR8 *argv[]\r
225 )\r
226{\r
227 FILE *OutputFile;\r
228 UINT8 *FileBuffer;\r
229 UINT32 BufferSize;\r
230 EFI_STATUS Status;\r
231 UINT32 ContentSize;\r
232 CHAR8 *OutputFileName;\r
233 INT32 ReturnValue;\r
234 INT32 Index;\r
235\r
236 OutputFile = NULL;\r
237 FileBuffer = NULL;\r
238 ContentSize = 0;\r
239 OutputFileName = NULL;\r
240\r
241 SetUtilityName (UTILITY_NAME);\r
db608e6b 242 \r
243 if (argc == 1) {\r
244 Usage ();\r
245 return -1;\r
246 }\r
878ddf1f 247\r
52be9a3b 248 if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
249 (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
250 Usage();\r
251 return -1;\r
252 }\r
253 \r
254 if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
255 Version();\r
256 return -1;\r
257 }\r
878ddf1f 258\r
259 BufferSize = 1024 * 1024 * 16;\r
260 FileBuffer = (UINT8 *) malloc (BufferSize * sizeof (UINT8));\r
261 if (FileBuffer == NULL) {\r
262 Error (NULL, 0, 0, "memory allocation failed", NULL);\r
263 return -1;\r
264 }\r
265\r
266 ZeroMem (FileBuffer, BufferSize);\r
267\r
268 for (Index = 0; Index < argc; Index++) {\r
269 if (strcmpi (argv[Index], "-i") == 0) {\r
270 ReturnValue = ReadFilesContentsIntoBuffer (\r
271 argv,\r
272 (Index + 1),\r
273 &FileBuffer,\r
274 &BufferSize,\r
275 &ContentSize,\r
276 (argc - (Index + 1))\r
277 );\r
278 if (ReturnValue == -1) {\r
279 Error (NULL, 0, 0, "failed to read file contents", NULL);\r
280 return -1;\r
281 }\r
282\r
283 Index += ReturnValue;\r
284 }\r
285\r
286 if (strcmpi (argv[Index], "-o") == 0) {\r
287 OutputFileName = argv[Index + 1];\r
288 }\r
289 }\r
290\r
291 OutputFile = fopen (OutputFileName, "wb");\r
292 if (OutputFile == NULL) {\r
293 Error (NULL, 0, 0, OutputFileName, "failed to open output binary file");\r
294 free (FileBuffer);\r
295 return -1;\r
296 }\r
297\r
298 /* \r
299 //\r
300 // make sure section ends on a DWORD boundary ??\r
301 //\r
302 while ( (Size & 0x03) != 0 ) {\r
303 FileBuffer[Size] = 0;\r
304 Size ++;\r
305 }\r
306*/\r
307 Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize);\r
308 if (EFI_ERROR (Status)) {\r
309 Error (NULL, 0, 0, "failed to sign section", NULL);\r
310 free (FileBuffer);\r
311 fclose (OutputFile);\r
312 return -1;\r
313 }\r
314\r
315 ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile);\r
316 if (ContentSize != BufferSize) {\r
317 Error (NULL, 0, 0, "failed to write output buffer", NULL);\r
318 ReturnValue = -1;\r
319 } else {\r
320 ReturnValue = 0;\r
321 }\r
322\r
323 free (FileBuffer);\r
324 fclose (OutputFile);\r
325 return ReturnValue;\r
326}\r