3 Copyright (c) 2006 - 2010, 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 v%d.%d -Utility to break a file into two pieces at the request offset.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
);
87 printf ("Copyright (c) 1999-2010 Intel Corporation. All rights reserved.\n");
95 printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");
101 IN CONST CHAR8
* VerboseLevelString
,
102 IN CONST UINT64 Length
,
103 OUT UINT64
*ReturnValue
107 for (;i
< Length
; ++i
) {
108 if (VerboseLevelString
[i
] != 'v' && VerboseLevelString
[i
] != 'V') {
124 Write all the content of input file to output file.
127 in - input file pointer
128 out - output file pointer
131 UINT64 : file size of input file
134 UINT32 filesize
, offset
, length
;
135 CHAR8 Buffer
[8*1024];
137 fseek (in
, 0, SEEK_END
);
138 filesize
= ftell(in
);
140 fseek (in
, 0, SEEK_SET
);
143 while (offset
< filesize
) {
144 length
= sizeof(Buffer
);
145 if (filesize
-offset
< length
) {
146 length
= filesize
-offset
;
149 fread (Buffer
, length
, 1, in
);
150 fwrite (Buffer
, length
, 1, out
);
179 EFILDR_HEADER EfiLdrHeader
;
180 EFILDR_IMAGE EfiLdrImage
[MAX_PE_IMAGES
];
181 CHAR8
* OutputFileName
= NULL
;
182 CHAR8
* InputFileNames
[MAX_PE_IMAGES
+ 1];
183 UINT8 InputFileCount
= 0;
184 BOOLEAN QuietFlag
= FALSE
;
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)) {
229 if ((strlen(argv
[0]) >= 2 && argv
[0][0] == '-' && (argv
[0][1] == 'v' || argv
[0][1] == 'V')) || (stricmp (argv
[0], "--verbose") == 0)) {
231 if (strlen(argv
[0]) > 2) {
232 Status
= CountVerboseLevel (&argv
[0][2], strlen(argv
[0]) - 2, &VerboseLevel
);
233 if (EFI_ERROR (Status
)) {
234 Error (NULL
, 0, 1003, "Invalid option value", argv
[0]);
244 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
245 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &DebugLevel
);
246 if (EFI_ERROR (Status
)) {
247 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
255 // Don't recognize the parameter, should be regarded as the input file name.
257 InputFileNames
[InputFileCount
] = argv
[0];
263 if (InputFileCount
== 0) {
264 Error (NULL
, 0, 1001, "Missing option", "No input file");
268 // Open output file for write
270 if (OutputFileName
== NULL
) {
271 Error (NULL
, 0, 1001, "Missing option", "No output file");
275 fpOut
= fopen(OutputFileName
, "w+b");
277 Error (NULL
, 0, 0001, "Could not open output file", OutputFileName
);
281 memset (&EfiLdrHeader
, 0, sizeof (EfiLdrHeader
));
282 memset (&EfiLdrImage
, 0, sizeof (EFILDR_IMAGE
) * (InputFileCount
));
284 memcpy (&EfiLdrHeader
.Signature
, "EFIL", 4);
285 EfiLdrHeader
.FileLength
= sizeof(EFILDR_HEADER
) + sizeof(EFILDR_IMAGE
)*(InputFileCount
);
288 // Skip the file header first
290 fseek (fpOut
, EfiLdrHeader
.FileLength
, SEEK_SET
);
293 // copy all the input files to the output file
295 for(i
=0;i
<InputFileCount
;i
++) {
297 // Copy the content of PeImage file to output file
299 fpIn
= fopen (InputFileNames
[i
], "rb");
301 Error (NULL
, 0, 0001, "Could not open input file", InputFileNames
[i
]);
305 filesize
= FCopyFile (fpIn
, fpOut
);
309 // And in the same time update the EfiLdrHeader and EfiLdrImage array
311 EfiLdrImage
[i
].Offset
= EfiLdrHeader
.FileLength
;
312 EfiLdrImage
[i
].Length
= (UINT32
) filesize
;
313 strncpy ((CHAR8
*) EfiLdrImage
[i
].FileName
, InputFileNames
[i
], sizeof (EfiLdrImage
[i
].FileName
) - 1);
314 EfiLdrHeader
.FileLength
+= (UINT32
) filesize
;
315 EfiLdrHeader
.NumberOfImages
++;
319 // Write the image header to the output file finally
321 fseek (fpOut
, 0, SEEK_SET
);
322 fwrite (&EfiLdrHeader
, sizeof(EFILDR_HEADER
) , 1, fpOut
);
323 fwrite (&EfiLdrImage
, sizeof(EFILDR_IMAGE
)*(InputFileCount
), 1, fpOut
);
326 printf ("Created %s\n", OutputFileName
);