3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. 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
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.
18 Converts a pe32+ image to an FW image type
22 #include <WinNtInclude.h>
32 #include <UefiBaseTypes.h>
33 #include <CommonLib.h>
35 #include <EfiUtilityMsgs.c>
37 #define UTILITY_NAME "FwImage"
40 typedef unsigned long ULONG
;
41 typedef unsigned char UCHAR
;
42 typedef unsigned char *PUCHAR
;
43 typedef unsigned short USHORT
;
51 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]");
64 UCHAR Buffer
[8 * 1024];
66 fseek (in
, 0, SEEK_END
);
67 filesize
= ftell (in
);
69 fseek (in
, 0, SEEK_SET
);
70 fseek (out
, 0, SEEK_SET
);
73 while (offset
< filesize
) {
74 length
= sizeof (Buffer
);
75 if (filesize
- offset
< length
) {
76 length
= filesize
- offset
;
79 fread (Buffer
, length
, 1, in
);
80 fwrite (Buffer
, length
, 1, out
);
84 if ((ULONG
) ftell (out
) != filesize
) {
85 Error (NULL
, 0, 0, "write error", NULL
);
89 return STATUS_SUCCESS
;
105 argc - Number of command line parameters.
106 argv - Array of pointers to command line parameter strings.
109 STATUS_SUCCESS - Utility exits successfully.
110 STATUS_ERROR - Some error occurred during execution.
122 EFI_IMAGE_DOS_HEADER DosHdr
;
123 EFI_IMAGE_NT_HEADERS PeHdr
;
125 struct tm TimeStruct
;
126 EFI_IMAGE_DOS_HEADER BackupDosHdr
;
128 BOOLEAN TimeStampPresent
;
130 SetUtilityName (UTILITY_NAME
);
132 // Assign to fix compile warning
138 TimeStampPresent
= FALSE
;
141 // Look for -t time-date option first. If the time is "0", then
144 if ((argc
> 2) && !strcmp (argv
[1], "-t")) {
145 TimeStampPresent
= TRUE
;
146 if (strcmp (argv
[2], "0") != 0) {
148 // Convert the string to a value
150 memset ((char *) &TimeStruct
, 0, sizeof (TimeStruct
));
152 argv
[2], "%d/%d/%d,%d:%d:%d",
153 &TimeStruct
.tm_mon
, /* months since January - [0,11] */
154 &TimeStruct
.tm_mday
, /* day of the month - [1,31] */
155 &TimeStruct
.tm_year
, /* years since 1900 */
156 &TimeStruct
.tm_hour
, /* hours since midnight - [0,23] */
157 &TimeStruct
.tm_min
, /* minutes after the hour - [0,59] */
158 &TimeStruct
.tm_sec
/* seconds after the minute - [0,59] */
160 Error (NULL
, 0, 0, argv
[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format");
164 // Now fixup some of the fields
167 TimeStruct
.tm_year
-= 1900;
169 // Sanity-check values?
172 TimeStamp
= mktime (&TimeStruct
);
173 if (TimeStamp
== (time_t) - 1) {
174 Error (NULL
, 0, 0, argv
[2], "failed to convert time");
179 // Skip over the args
185 // Check for enough args
193 OutImageName
= argv
[3];
196 // Get new image type
199 if (*p
== '/' || *p
== '\\') {
203 if (stricmp (p
, "app") == 0 || stricmp (p
, "APPLICATION") == 0) {
204 Type
= EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
;
207 } else if (stricmp (p
, "bsdrv") == 0 || stricmp (p
, "BS_DRIVER") == 0) {
208 Type
= EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
;
211 } else if (stricmp (p
, "rtdrv") == 0 || stricmp (p
, "RT_DRIVER") == 0) {
212 Type
= EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
;
215 } else if (stricmp (p
, "rtdrv") == 0 || stricmp (p
, "SAL_RT_DRIVER") == 0) {
216 Type
= EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER
;
218 } else if (stricmp (p
, "SECURITY_CORE") == 0) {
219 Type
= EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
;
221 } else if (stricmp (p
, "peim") == 0 ||
222 stricmp (p
, "PEI_CORE") == 0 ||
223 stricmp (p
, "PE32_PEIM") == 0 ||
224 stricmp (p
, "RELOCATABLE_PEIM") == 0 ||
225 stricmp (p
, "combined_peim_driver") == 0
227 Type
= EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
;
236 fpIn
= fopen (argv
[2], "rb");
238 Error (NULL
, 0, 0, argv
[2], "failed to open input file for reading");
242 // Read the dos & pe hdrs of the image
244 fseek (fpIn
, 0, SEEK_SET
);
245 fread (&DosHdr
, sizeof (DosHdr
), 1, fpIn
);
246 if (DosHdr
.e_magic
!= EFI_IMAGE_DOS_SIGNATURE
) {
247 Error (NULL
, 0, 0, argv
[2], "DOS header signature not found in source image");
252 fseek (fpIn
, DosHdr
.e_lfanew
, SEEK_SET
);
253 fread (&PeHdr
, sizeof (PeHdr
), 1, fpIn
);
254 if (PeHdr
.Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
255 Error (NULL
, 0, 0, argv
[2], "PE header signature not found in source image");
262 strcpy (outname
, argv
[2]);
264 for (p
= outname
; *p
; p
++) {
277 OutImageName
= outname
;
280 fpOut
= fopen (OutImageName
, "w+b");
282 Error (NULL
, 0, 0, OutImageName
, "could not open output file for writing");
289 if (FCopyFile (fpIn
, fpOut
) != STATUS_SUCCESS
) {
295 // Zero all unused fields of the DOS header
297 memcpy (&BackupDosHdr
, &DosHdr
, sizeof (DosHdr
));
298 memset (&DosHdr
, 0, sizeof (DosHdr
));
299 DosHdr
.e_magic
= BackupDosHdr
.e_magic
;
300 DosHdr
.e_lfanew
= BackupDosHdr
.e_lfanew
;
301 fseek (fpOut
, 0, SEEK_SET
);
302 fwrite (&DosHdr
, sizeof (DosHdr
), 1, fpOut
);
304 fseek (fpOut
, sizeof (DosHdr
), SEEK_SET
);
305 for (Index
= sizeof (DosHdr
); Index
< (ULONG
) DosHdr
.e_lfanew
; Index
++) {
306 fwrite (&DosHdr
.e_cp
, 1, 1, fpOut
);
309 // Path the PE header
311 PeHdr
.OptionalHeader
.Subsystem
= (USHORT
) Type
;
312 if (TimeStampPresent
) {
313 PeHdr
.FileHeader
.TimeDateStamp
= (UINT32
) TimeStamp
;
316 PeHdr
.OptionalHeader
.SizeOfStackReserve
= 0;
317 PeHdr
.OptionalHeader
.SizeOfStackCommit
= 0;
318 PeHdr
.OptionalHeader
.SizeOfHeapReserve
= 0;
319 PeHdr
.OptionalHeader
.SizeOfHeapCommit
= 0;
320 fseek (fpOut
, DosHdr
.e_lfanew
, SEEK_SET
);
321 fwrite (&PeHdr
, sizeof (PeHdr
), 1, fpOut
);
329 // printf ("Created %s\n", OutImageName);
331 return STATUS_SUCCESS
;