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 <Common/UefiBaseTypes.h>
33 #include <Common/EfiImage.h>
35 #include "CommonLib.h"
36 #include "EfiUtilityMsgs.c"
38 #define UTILITY_NAME "FwImage"
41 typedef unsigned long ULONG
;
42 typedef unsigned char UCHAR
;
43 typedef unsigned char *PUCHAR
;
44 typedef unsigned short USHORT
;
52 printf ("Usage: " UTILITY_NAME
" {-t time-date} [BASE|SEC|PEI_CORE|PEIM|DXE_CORE|DXE_DRIVER|DXE_RUNTIME_DRIVER|DXE_SAL_DRIVER|DXE_SMM_DRIVER|TOOL|UEFI_DRIVER|UEFI_APPLICATION|USER_DEFINED] peimage [outimage]");
65 UCHAR Buffer
[8 * 1024];
67 fseek (in
, 0, SEEK_END
);
68 filesize
= ftell (in
);
70 fseek (in
, 0, SEEK_SET
);
71 fseek (out
, 0, SEEK_SET
);
74 while (offset
< filesize
) {
75 length
= sizeof (Buffer
);
76 if (filesize
- offset
< length
) {
77 length
= filesize
- offset
;
80 fread (Buffer
, length
, 1, in
);
81 fwrite (Buffer
, length
, 1, out
);
85 if ((ULONG
) ftell (out
) != filesize
) {
86 Error (NULL
, 0, 0, "write error", NULL
);
90 return STATUS_SUCCESS
;
106 argc - Number of command line parameters.
107 argv - Array of pointers to command line parameter strings.
110 STATUS_SUCCESS - Utility exits successfully.
111 STATUS_ERROR - Some error occurred during execution.
123 EFI_IMAGE_DOS_HEADER DosHdr
;
124 EFI_IMAGE_NT_HEADERS PeHdr
;
126 struct tm TimeStruct
;
127 EFI_IMAGE_DOS_HEADER BackupDosHdr
;
129 BOOLEAN TimeStampPresent
;
131 SetUtilityName (UTILITY_NAME
);
133 // Assign to fix compile warning
139 TimeStampPresent
= FALSE
;
142 // Look for -t time-date option first. If the time is "0", then
145 if ((argc
> 2) && !strcmp (argv
[1], "-t")) {
146 TimeStampPresent
= TRUE
;
147 if (strcmp (argv
[2], "0") != 0) {
149 // Convert the string to a value
151 memset ((char *) &TimeStruct
, 0, sizeof (TimeStruct
));
153 argv
[2], "%d/%d/%d,%d:%d:%d",
154 &TimeStruct
.tm_mon
, /* months since January - [0,11] */
155 &TimeStruct
.tm_mday
, /* day of the month - [1,31] */
156 &TimeStruct
.tm_year
, /* years since 1900 */
157 &TimeStruct
.tm_hour
, /* hours since midnight - [0,23] */
158 &TimeStruct
.tm_min
, /* minutes after the hour - [0,59] */
159 &TimeStruct
.tm_sec
/* seconds after the minute - [0,59] */
161 Error (NULL
, 0, 0, argv
[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format");
165 // Now fixup some of the fields
168 TimeStruct
.tm_year
-= 1900;
170 // Sanity-check values?
173 TimeStamp
= mktime (&TimeStruct
);
174 if (TimeStamp
== (time_t) - 1) {
175 Error (NULL
, 0, 0, argv
[2], "failed to convert time");
180 // Skip over the args
186 // Check for enough args
194 OutImageName
= argv
[3];
197 // Get new image type
200 if (*p
== '/' || *p
== '\\') {
204 if (stricmp (p
, "app") == 0 || stricmp (p
, "UEFI_APPLICATION") == 0) {
205 Type
= EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
;
208 } else if (stricmp (p
, "bsdrv") == 0 || stricmp (p
, "DXE_DRIVER") == 0) {
209 Type
= EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
;
212 } else if (stricmp (p
, "rtdrv") == 0 || stricmp (p
, "DXE_RUNTIME_DRIVER") == 0) {
213 Type
= EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
;
216 } else if (stricmp (p
, "rtdrv") == 0 || stricmp (p
, "DXE_SAL_DRIVER") == 0) {
217 Type
= EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER
;
219 } else if (stricmp (p
, "SEC") == 0) {
220 Type
= EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
;
222 } else if (stricmp (p
, "peim") == 0 ||
223 stricmp (p
, "BASE") == 0 ||
224 stricmp (p
, "PEI_CORE") == 0 ||
225 stricmp (p
, "PEIM") == 0 ||
226 stricmp (p
, "DXE_SMM_DRIVER") == 0 ||
227 stricmp (p
, "TOOL") == 0 ||
228 stricmp (p
, "UEFI_APPLICATION") == 0 ||
229 stricmp (p
, "USER_DEFINED") == 0 ||
230 stricmp (p
, "UEFI_DRIVER") == 0 ||
231 stricmp (p
, "DXE_CORE") == 0
233 Type
= EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
;
243 fpIn
= fopen (argv
[2], "rb");
245 Error (NULL
, 0, 0, argv
[2], "failed to open input file for reading");
249 // Read the dos & pe hdrs of the image
251 fseek (fpIn
, 0, SEEK_SET
);
252 fread (&DosHdr
, sizeof (DosHdr
), 1, fpIn
);
253 if (DosHdr
.e_magic
!= EFI_IMAGE_DOS_SIGNATURE
) {
254 Error (NULL
, 0, 0, argv
[2], "DOS header signature not found in source image");
259 fseek (fpIn
, DosHdr
.e_lfanew
, SEEK_SET
);
260 fread (&PeHdr
, sizeof (PeHdr
), 1, fpIn
);
261 if (PeHdr
.Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
262 Error (NULL
, 0, 0, argv
[2], "PE header signature not found in source image");
269 strcpy (outname
, argv
[2]);
271 for (p
= outname
; *p
; p
++) {
284 OutImageName
= outname
;
287 fpOut
= fopen (OutImageName
, "w+b");
289 Error (NULL
, 0, 0, OutImageName
, "could not open output file for writing");
296 if (FCopyFile (fpIn
, fpOut
) != STATUS_SUCCESS
) {
302 // Zero all unused fields of the DOS header
304 memcpy (&BackupDosHdr
, &DosHdr
, sizeof (DosHdr
));
305 memset (&DosHdr
, 0, sizeof (DosHdr
));
306 DosHdr
.e_magic
= BackupDosHdr
.e_magic
;
307 DosHdr
.e_lfanew
= BackupDosHdr
.e_lfanew
;
308 fseek (fpOut
, 0, SEEK_SET
);
309 fwrite (&DosHdr
, sizeof (DosHdr
), 1, fpOut
);
311 fseek (fpOut
, sizeof (DosHdr
), SEEK_SET
);
312 for (Index
= sizeof (DosHdr
); Index
< (ULONG
) DosHdr
.e_lfanew
; Index
++) {
313 fwrite (&DosHdr
.e_cp
, 1, 1, fpOut
);
316 // Path the PE header
318 PeHdr
.OptionalHeader
.Subsystem
= (USHORT
) Type
;
319 if (TimeStampPresent
) {
320 PeHdr
.FileHeader
.TimeDateStamp
= (UINT32
) TimeStamp
;
323 PeHdr
.OptionalHeader
.SizeOfStackReserve
= 0;
324 PeHdr
.OptionalHeader
.SizeOfStackCommit
= 0;
325 PeHdr
.OptionalHeader
.SizeOfHeapReserve
= 0;
326 PeHdr
.OptionalHeader
.SizeOfHeapCommit
= 0;
327 fseek (fpOut
, DosHdr
.e_lfanew
, SEEK_SET
);
328 fwrite (&PeHdr
, sizeof (PeHdr
), 1, fpOut
);
336 // printf ("Created %s\n", OutImageName);
338 return STATUS_SUCCESS
;