]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/FwImage/fwimage.c
1. Removed the unnecessary #include statements and include files
[mirror_edk2.git] / Tools / Source / TianoTools / FwImage / fwimage.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2004, Intel Corporation \r
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 fwimage.c\r
15\r
16Abstract:\r
17\r
18 Converts a pe32+ image to an FW image type\r
19\r
20--*/\r
21\r
ce53a8c3 22#include "WinNtInclude.h"\r
23\r
878ddf1f 24#ifndef __GNUC__\r
25#include <windows.h>\r
26#endif\r
27#include <stdio.h>\r
28#include <stdlib.h>\r
29#include <string.h>\r
30#include <time.h>\r
31\r
ce53a8c3 32#include <Common/UefiBaseTypes.h>\r
33#include <Common/EfiImage.h>\r
34\r
35#include "CommonLib.h"\r
36#include "EfiUtilityMsgs.c"\r
878ddf1f 37\r
38#define UTILITY_NAME "FwImage"\r
39\r
40#ifdef __GNUC__\r
41typedef unsigned long ULONG;\r
42typedef unsigned char UCHAR;\r
43typedef unsigned char *PUCHAR;\r
44typedef unsigned short USHORT;\r
45#endif\r
46\r
47VOID\r
48Usage (\r
49 VOID\r
50 )\r
51{\r
52 printf ("Usage: " UTILITY_NAME " {-t time-date} [APPLICATION|BS_DRIVER|RT_DRIVER|SAL_RT_DRIVER|COMBINED_PEIM_DRIVER|SECURITY_CORE|PEI_CORE|PE32_PEIM|RELOCATABLE_PEIM] peimage [outimage]");\r
53}\r
54\r
55static\r
56STATUS\r
57FCopyFile (\r
58 FILE *in,\r
59 FILE *out\r
60 )\r
61{\r
62 ULONG filesize;\r
63 ULONG offset;\r
64 ULONG length;\r
65 UCHAR Buffer[8 * 1024];\r
66\r
67 fseek (in, 0, SEEK_END);\r
68 filesize = ftell (in);\r
69\r
70 fseek (in, 0, SEEK_SET);\r
71 fseek (out, 0, SEEK_SET);\r
72\r
73 offset = 0;\r
74 while (offset < filesize) {\r
75 length = sizeof (Buffer);\r
76 if (filesize - offset < length) {\r
77 length = filesize - offset;\r
78 }\r
79\r
80 fread (Buffer, length, 1, in);\r
81 fwrite (Buffer, length, 1, out);\r
82 offset += length;\r
83 }\r
84\r
85 if ((ULONG) ftell (out) != filesize) {\r
86 Error (NULL, 0, 0, "write error", NULL);\r
87 return STATUS_ERROR;\r
88 }\r
89\r
90 return STATUS_SUCCESS;\r
91}\r
92\r
93int\r
94main (\r
95 int argc,\r
96 char *argv[]\r
97 )\r
98/*++\r
99\r
100Routine Description:\r
101\r
102 Main function.\r
103\r
104Arguments:\r
105\r
106 argc - Number of command line parameters.\r
107 argv - Array of pointers to command line parameter strings.\r
108\r
109Returns:\r
110 STATUS_SUCCESS - Utility exits successfully.\r
111 STATUS_ERROR - Some error occurred during execution.\r
112\r
113--*/\r
114{\r
115 ULONG Type;\r
116 PUCHAR Ext;\r
117 PUCHAR p;\r
118 PUCHAR pe;\r
119 PUCHAR OutImageName;\r
120 UCHAR outname[500];\r
121 FILE *fpIn;\r
122 FILE *fpOut;\r
123 EFI_IMAGE_DOS_HEADER DosHdr;\r
124 EFI_IMAGE_NT_HEADERS PeHdr;\r
125 time_t TimeStamp;\r
126 struct tm TimeStruct;\r
127 EFI_IMAGE_DOS_HEADER BackupDosHdr;\r
128 ULONG Index;\r
129 BOOLEAN TimeStampPresent;\r
130\r
131 SetUtilityName (UTILITY_NAME);\r
132 //\r
133 // Assign to fix compile warning\r
134 //\r
135 OutImageName = NULL;\r
136 Type = 0;\r
137 Ext = 0;\r
138 TimeStamp = 0;\r
139 TimeStampPresent = FALSE;\r
140\r
141 //\r
142 // Look for -t time-date option first. If the time is "0", then\r
143 // skip it.\r
144 //\r
145 if ((argc > 2) && !strcmp (argv[1], "-t")) {\r
146 TimeStampPresent = TRUE;\r
147 if (strcmp (argv[2], "0") != 0) {\r
148 //\r
149 // Convert the string to a value\r
150 //\r
151 memset ((char *) &TimeStruct, 0, sizeof (TimeStruct));\r
152 if (sscanf(\r
153 argv[2], "%d/%d/%d,%d:%d:%d",\r
154 &TimeStruct.tm_mon, /* months since January - [0,11] */\r
155 &TimeStruct.tm_mday, /* day of the month - [1,31] */\r
156 &TimeStruct.tm_year, /* years since 1900 */\r
157 &TimeStruct.tm_hour, /* hours since midnight - [0,23] */\r
158 &TimeStruct.tm_min, /* minutes after the hour - [0,59] */\r
159 &TimeStruct.tm_sec /* seconds after the minute - [0,59] */\r
160 ) != 6) {\r
161 Error (NULL, 0, 0, argv[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format");\r
162 return STATUS_ERROR;\r
163 }\r
164 //\r
165 // Now fixup some of the fields\r
166 //\r
167 TimeStruct.tm_mon--;\r
168 TimeStruct.tm_year -= 1900;\r
169 //\r
170 // Sanity-check values?\r
171 // Convert\r
172 //\r
173 TimeStamp = mktime (&TimeStruct);\r
174 if (TimeStamp == (time_t) - 1) {\r
175 Error (NULL, 0, 0, argv[2], "failed to convert time");\r
176 return STATUS_ERROR;\r
177 }\r
178 }\r
179 //\r
180 // Skip over the args\r
181 //\r
182 argc -= 2;\r
183 argv += 2;\r
184 }\r
185 //\r
186 // Check for enough args\r
187 //\r
188 if (argc < 3) {\r
189 Usage ();\r
190 return STATUS_ERROR;\r
191 }\r
192\r
193 if (argc == 4) {\r
194 OutImageName = argv[3];\r
195 }\r
196 //\r
197 // Get new image type\r
198 //\r
199 p = argv[1];\r
200 if (*p == '/' || *p == '\\') {\r
201 p += 1;\r
202 }\r
203\r
204 if (stricmp (p, "app") == 0 || stricmp (p, "APPLICATION") == 0) {\r
205 Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
206 Ext = ".efi";\r
207\r
208 } else if (stricmp (p, "bsdrv") == 0 || stricmp (p, "BS_DRIVER") == 0) {\r
209 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
210 Ext = ".efi";\r
211\r
212 } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "RT_DRIVER") == 0) {\r
213 Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;\r
214 Ext = ".efi";\r
215\r
216 } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "SAL_RT_DRIVER") == 0) {\r
217 Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;\r
218 Ext = ".efi";\r
219 } else if (stricmp (p, "SECURITY_CORE") == 0) {\r
220 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
221 Ext = ".sec";\r
222 } else if (stricmp (p, "peim") == 0 ||\r
223 stricmp (p, "PEI_CORE") == 0 ||\r
224 stricmp (p, "PE32_PEIM") == 0 ||\r
225 stricmp (p, "RELOCATABLE_PEIM") == 0 ||\r
226 stricmp (p, "combined_peim_driver") == 0\r
227 ) {\r
228 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
229 Ext = ".pei";\r
230 } else {\r
231 Usage ();\r
232 return STATUS_ERROR;\r
233 }\r
234 //\r
235 // open source file\r
236 //\r
237 fpIn = fopen (argv[2], "rb");\r
238 if (!fpIn) {\r
239 Error (NULL, 0, 0, argv[2], "failed to open input file for reading");\r
240 return STATUS_ERROR;\r
241 }\r
242 //\r
243 // Read the dos & pe hdrs of the image\r
244 //\r
245 fseek (fpIn, 0, SEEK_SET);\r
246 fread (&DosHdr, sizeof (DosHdr), 1, fpIn);\r
247 if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
248 Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image");\r
249 fclose (fpIn);\r
250 return STATUS_ERROR;\r
251 }\r
252\r
253 fseek (fpIn, DosHdr.e_lfanew, SEEK_SET);\r
254 fread (&PeHdr, sizeof (PeHdr), 1, fpIn);\r
255 if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
256 Error (NULL, 0, 0, argv[2], "PE header signature not found in source image");\r
257 fclose (fpIn);\r
258 return STATUS_ERROR;\r
259 }\r
260 //\r
261 // open output file\r
262 //\r
263 strcpy (outname, argv[2]);\r
264 pe = NULL;\r
265 for (p = outname; *p; p++) {\r
266 if (*p == '.') {\r
267 pe = p;\r
268 }\r
269 }\r
270\r
271 if (!pe) {\r
272 pe = p;\r
273 }\r
274\r
275 strcpy (pe, Ext);\r
276\r
277 if (!OutImageName) {\r
278 OutImageName = outname;\r
279 }\r
280\r
281 fpOut = fopen (OutImageName, "w+b");\r
282 if (!fpOut) {\r
283 Error (NULL, 0, 0, OutImageName, "could not open output file for writing");\r
284 fclose (fpIn);\r
285 return STATUS_ERROR;\r
286 }\r
287 //\r
288 // Copy the file\r
289 //\r
290 if (FCopyFile (fpIn, fpOut) != STATUS_SUCCESS) {\r
291 fclose (fpIn);\r
292 fclose (fpOut);\r
293 return STATUS_ERROR;\r
294 }\r
295 //\r
296 // Zero all unused fields of the DOS header\r
297 //\r
298 memcpy (&BackupDosHdr, &DosHdr, sizeof (DosHdr));\r
299 memset (&DosHdr, 0, sizeof (DosHdr));\r
300 DosHdr.e_magic = BackupDosHdr.e_magic;\r
301 DosHdr.e_lfanew = BackupDosHdr.e_lfanew;\r
302 fseek (fpOut, 0, SEEK_SET);\r
303 fwrite (&DosHdr, sizeof (DosHdr), 1, fpOut);\r
304\r
305 fseek (fpOut, sizeof (DosHdr), SEEK_SET);\r
306 for (Index = sizeof (DosHdr); Index < (ULONG) DosHdr.e_lfanew; Index++) {\r
307 fwrite (&DosHdr.e_cp, 1, 1, fpOut);\r
308 }\r
309 //\r
310 // Path the PE header\r
311 //\r
312 PeHdr.OptionalHeader.Subsystem = (USHORT) Type;\r
313 if (TimeStampPresent) {\r
314 PeHdr.FileHeader.TimeDateStamp = (UINT32) TimeStamp;\r
315 }\r
316\r
317 PeHdr.OptionalHeader.SizeOfStackReserve = 0;\r
318 PeHdr.OptionalHeader.SizeOfStackCommit = 0;\r
319 PeHdr.OptionalHeader.SizeOfHeapReserve = 0;\r
320 PeHdr.OptionalHeader.SizeOfHeapCommit = 0;\r
321 fseek (fpOut, DosHdr.e_lfanew, SEEK_SET);\r
322 fwrite (&PeHdr, sizeof (PeHdr), 1, fpOut);\r
323\r
324 //\r
325 // Done\r
326 //\r
327 fclose (fpIn);\r
328 fclose (fpOut);\r
329 //\r
330 // printf ("Created %s\n", OutImageName);\r
331 //\r
332 return STATUS_SUCCESS;\r
333}\r