3 Copyright (c) 2006 - 2011, 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 %s -Utility to break a file into two pieces at the request offset.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_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 UINT64 DebugLevel
= 0;
185 UINT64 VerboseLevel
= 0;
186 EFI_STATUS Status
= EFI_SUCCESS
;
188 SetUtilityName (UTILITY_NAME
);
198 if ((stricmp (argv
[0], "-h") == 0) || (stricmp (argv
[0], "--help") == 0)) {
200 return STATUS_SUCCESS
;
203 if (stricmp (argv
[0], "--version") == 0) {
205 return STATUS_SUCCESS
;
210 if ((stricmp (argv
[0], "-o") == 0) || (stricmp (argv
[0], "--output") == 0)) {
211 OutputFileName
= argv
[1];
212 if (OutputFileName
== NULL
) {
213 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be null");
221 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
227 if ((strlen(argv
[0]) >= 2 && argv
[0][0] == '-' && (argv
[0][1] == 'v' || argv
[0][1] == 'V')) || (stricmp (argv
[0], "--verbose") == 0)) {
229 if (strlen(argv
[0]) > 2) {
230 Status
= CountVerboseLevel (&argv
[0][2], strlen(argv
[0]) - 2, &VerboseLevel
);
231 if (EFI_ERROR (Status
)) {
232 Error (NULL
, 0, 1003, "Invalid option value", argv
[0]);
242 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
243 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &DebugLevel
);
244 if (EFI_ERROR (Status
)) {
245 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
253 // Don't recognize the parameter, should be regarded as the input file name.
255 InputFileNames
[InputFileCount
] = argv
[0];
261 if (InputFileCount
== 0) {
262 Error (NULL
, 0, 1001, "Missing option", "No input file");
266 // Open output file for write
268 if (OutputFileName
== NULL
) {
269 Error (NULL
, 0, 1001, "Missing option", "No output file");
273 fpOut
= fopen(OutputFileName
, "w+b");
275 Error (NULL
, 0, 0001, "Could not open output file", OutputFileName
);
279 memset (&EfiLdrHeader
, 0, sizeof (EfiLdrHeader
));
280 memset (&EfiLdrImage
, 0, sizeof (EFILDR_IMAGE
) * (InputFileCount
));
282 memcpy (&EfiLdrHeader
.Signature
, "EFIL", 4);
283 EfiLdrHeader
.FileLength
= sizeof(EFILDR_HEADER
) + sizeof(EFILDR_IMAGE
)*(InputFileCount
);
286 // Skip the file header first
288 fseek (fpOut
, EfiLdrHeader
.FileLength
, SEEK_SET
);
291 // copy all the input files to the output file
293 for(i
=0;i
<InputFileCount
;i
++) {
295 // Copy the content of PeImage file to output file
297 fpIn
= fopen (InputFileNames
[i
], "rb");
299 Error (NULL
, 0, 0001, "Could not open input file", InputFileNames
[i
]);
303 filesize
= FCopyFile (fpIn
, fpOut
);
307 // And in the same time update the EfiLdrHeader and EfiLdrImage array
309 EfiLdrImage
[i
].Offset
= EfiLdrHeader
.FileLength
;
310 EfiLdrImage
[i
].Length
= (UINT32
) filesize
;
311 strncpy ((CHAR8
*) EfiLdrImage
[i
].FileName
, InputFileNames
[i
], sizeof (EfiLdrImage
[i
].FileName
) - 1);
312 EfiLdrHeader
.FileLength
+= (UINT32
) filesize
;
313 EfiLdrHeader
.NumberOfImages
++;
317 // Write the image header to the output file finally
319 fseek (fpOut
, 0, SEEK_SET
);
320 fwrite (&EfiLdrHeader
, sizeof(EFILDR_HEADER
) , 1, fpOut
);
321 fwrite (&EfiLdrImage
, sizeof(EFILDR_IMAGE
)*(InputFileCount
), 1, fpOut
);
324 printf ("Created %s\n", OutputFileName
);