3 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
4 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 Creates and EFILDR image.
19 This tool combines several PE Image files together using following format denoted as EBNF:
22 <PeImageFileContent> +
23 The order of EFILDR_IMAGE is same as the order of placing PeImageFileContent.
34 #include "CommonLib.h"
35 #include "EfiUtilityMsgs.h"
37 #define MAX_PE_IMAGES 63
38 #define FILE_TYPE_FIXED_LOADER 0
39 #define FILE_TYPE_RELOCATABLE_PE_IMAGE 1
50 UINT32 HeaderCheckSum
;
52 UINT32 NumberOfImages
;
58 #define UTILITY_NAME "EfiLdrImage"
61 // Utility version information
63 #define UTILITY_MAJOR_VERSION 0
64 #define UTILITY_MINOR_VERSION 1
74 Displays the standard utility information to SDTOUT
86 printf ("%s Version %d.%d %s\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
87 printf ("Copyright (c) 1999-2014 Intel Corporation. All rights reserved.\n");
88 printf ("\n The EfiLdrImage tool is used to combine PE files into EFILDR image with Efi loader header.\n");
96 printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");
102 IN CONST CHAR8
* VerboseLevelString
,
103 IN CONST UINT64 Length
,
104 OUT UINT64
*ReturnValue
108 for (;i
< Length
; ++i
) {
109 if (VerboseLevelString
[i
] != 'v' && VerboseLevelString
[i
] != 'V') {
125 Write all the content of input file to output file.
128 in - input file pointer
129 out - output file pointer
132 UINT64 : file size of input file
135 UINT32 filesize
, offset
, length
;
136 CHAR8 Buffer
[8*1024];
138 fseek (in
, 0, SEEK_END
);
139 filesize
= ftell(in
);
141 fseek (in
, 0, SEEK_SET
);
144 while (offset
< filesize
) {
145 length
= sizeof(Buffer
);
146 if (filesize
-offset
< length
) {
147 length
= filesize
-offset
;
150 fread (Buffer
, length
, 1, in
);
151 fwrite (Buffer
, length
, 1, out
);
180 EFILDR_HEADER EfiLdrHeader
;
181 EFILDR_IMAGE EfiLdrImage
[MAX_PE_IMAGES
];
182 CHAR8
* OutputFileName
= NULL
;
183 CHAR8
* InputFileNames
[MAX_PE_IMAGES
+ 1];
184 UINT8 InputFileCount
= 0;
185 UINT64 DebugLevel
= 0;
186 UINT64 VerboseLevel
= 0;
187 EFI_STATUS Status
= EFI_SUCCESS
;
189 SetUtilityName (UTILITY_NAME
);
199 if ((stricmp (argv
[0], "-h") == 0) || (stricmp (argv
[0], "--help") == 0)) {
201 return STATUS_SUCCESS
;
204 if (stricmp (argv
[0], "--version") == 0) {
206 return STATUS_SUCCESS
;
211 if ((stricmp (argv
[0], "-o") == 0) || (stricmp (argv
[0], "--output") == 0)) {
212 OutputFileName
= argv
[1];
213 if (OutputFileName
== NULL
) {
214 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be null");
222 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
228 if ((strlen(argv
[0]) >= 2 && argv
[0][0] == '-' && (argv
[0][1] == 'v' || argv
[0][1] == 'V')) || (stricmp (argv
[0], "--verbose") == 0)) {
230 if (strlen(argv
[0]) > 2) {
231 Status
= CountVerboseLevel (&argv
[0][2], strlen(argv
[0]) - 2, &VerboseLevel
);
232 if (EFI_ERROR (Status
)) {
233 Error (NULL
, 0, 1003, "Invalid option value", argv
[0]);
243 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
244 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &DebugLevel
);
245 if (EFI_ERROR (Status
)) {
246 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
254 // Don't recognize the parameter, should be regarded as the input file name.
256 InputFileNames
[InputFileCount
] = argv
[0];
262 if (InputFileCount
== 0) {
263 Error (NULL
, 0, 1001, "Missing option", "No input file");
267 // Open output file for write
269 if (OutputFileName
== NULL
) {
270 Error (NULL
, 0, 1001, "Missing option", "No output file");
274 fpOut
= fopen (LongFilePath (OutputFileName
), "w+b");
276 Error (NULL
, 0, 0001, "Could not open output file", OutputFileName
);
280 memset (&EfiLdrHeader
, 0, sizeof (EfiLdrHeader
));
281 memset (&EfiLdrImage
, 0, sizeof (EFILDR_IMAGE
) * (InputFileCount
));
283 memcpy (&EfiLdrHeader
.Signature
, "EFIL", 4);
284 EfiLdrHeader
.FileLength
= sizeof(EFILDR_HEADER
) + sizeof(EFILDR_IMAGE
)*(InputFileCount
);
287 // Skip the file header first
289 fseek (fpOut
, EfiLdrHeader
.FileLength
, SEEK_SET
);
292 // copy all the input files to the output file
294 for(i
=0;i
<InputFileCount
;i
++) {
296 // Copy the content of PeImage file to output file
298 fpIn
= fopen (LongFilePath (InputFileNames
[i
]), "rb");
300 Error (NULL
, 0, 0001, "Could not open input file", InputFileNames
[i
]);
304 filesize
= FCopyFile (fpIn
, fpOut
);
308 // And in the same time update the EfiLdrHeader and EfiLdrImage array
310 EfiLdrImage
[i
].Offset
= EfiLdrHeader
.FileLength
;
311 EfiLdrImage
[i
].Length
= (UINT32
) filesize
;
312 strncpy ((CHAR8
*) EfiLdrImage
[i
].FileName
, InputFileNames
[i
], sizeof (EfiLdrImage
[i
].FileName
) - 1);
313 EfiLdrHeader
.FileLength
+= (UINT32
) filesize
;
314 EfiLdrHeader
.NumberOfImages
++;
318 // Write the image header to the output file finally
320 fseek (fpOut
, 0, SEEK_SET
);
321 fwrite (&EfiLdrHeader
, sizeof(EFILDR_HEADER
) , 1, fpOut
);
322 fwrite (&EfiLdrImage
, sizeof(EFILDR_IMAGE
)*(InputFileCount
), 1, fpOut
);
325 printf ("Created %s\n", OutputFileName
);