Added or modified utility version and usage display.
[people/mcb30/edk2.git] / edk2 / Tools / CCode / Source / GenCRC32Section / GenCRC32Section.c
1 /*++\r
2 \r
3 Copyright (c) 2004-2007, Intel Corporation                                                         \r
4 All rights reserved. This program and the accompanying materials                          \r
5 are licensed and made available under the terms and conditions of the BSD License         \r
6 which accompanies this distribution.  The full text of the license may be found at        \r
7 http://opensource.org/licenses/bsd-license.php                                            \r
8                                                                                           \r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
11 \r
12 Module Name:\r
13   \r
14     GenCRC32Section.c\r
15 \r
16 Abstract:\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
25 #define UTILITY_NAME           "GenCrc32Section"\r
26 #define UTILITY_MAJOR_VERSION  0\r
27 #define UTILITY_MINOR_VERSION  2\r
28 \r
29 EFI_GUID  gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
30 \r
31 EFI_STATUS\r
32 SignSectionWithCrc32 (\r
33   IN OUT UINT8  *FileBuffer,\r
34   IN OUT UINT32 *BufferSize,\r
35   IN UINT32     DataSize\r
36   )\r
37 /*++\r
38         \r
39 Routine 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
44 Arguments:\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
55 Returns:\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
119 VOID\r
120 Version (\r
121   VOID\r
122   )\r
123 /*++\r
124 \r
125 Routine Description:\r
126 \r
127   Displays the standard utility information to SDTOUT\r
128 \r
129 Arguments:\r
130 \r
131   None\r
132 \r
133 Returns:\r
134 \r
135   None\r
136 \r
137 --*/\r
138 {\r
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
148 VOID\r
149 Usage (\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
159 }\r
160 \r
161 INT32\r
162 ReadFilesContentsIntoBuffer (\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
221 int\r
222 main (\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
242 \r
243   if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
244       (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
245     Usage();\r
246     return -1;\r
247   }\r
248   \r
249   if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
250     Version();\r
251     return -1;\r
252   }\r
253   \r
254   if (argc == 1) {\r
255     Usage ();\r
256     return -1;\r
257   }\r
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