]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/EfiLdrImage/EfiLdrImage.c
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / C / EfiLdrImage / EfiLdrImage.c
CommitLineData
30fdf114 1/** @file\r
97fa0ee9
YL
2Creates and EFILDR image.\r
3This tool combines several PE Image files together using following format denoted as EBNF:\r
4FILE := EFILDR_HEADER\r
5 EFILDR_IMAGE +\r
6 <PeImageFileContent> +\r
7The order of EFILDR_IMAGE is same as the order of placing PeImageFileContent.\r
30fdf114 8\r
f7496d71
LG
9Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
10This program and the accompanying materials\r
11are licensed and made available under the terms and conditions of the BSD License\r
12which accompanies this distribution. The full text of the license may be found at\r
13http://opensource.org/licenses/bsd-license.php\r
14\r
15THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
16WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
30fdf114 17\r
30fdf114
LG
18**/\r
19\r
20\r
21#include <stdio.h>\r
22#include <stdlib.h>\r
23#include <string.h>\r
24#include "ParseInf.h"\r
25#include "CommonLib.h"\r
26#include "EfiUtilityMsgs.h"\r
27\r
28#define MAX_PE_IMAGES 63\r
29#define FILE_TYPE_FIXED_LOADER 0\r
30#define FILE_TYPE_RELOCATABLE_PE_IMAGE 1\r
31\r
32typedef struct {\r
33 UINT32 CheckSum;\r
34 UINT32 Offset;\r
35 UINT32 Length;\r
36 UINT8 FileName[52];\r
37} EFILDR_IMAGE;\r
38\r
f7496d71
LG
39typedef struct {\r
40 UINT32 Signature;\r
30fdf114
LG
41 UINT32 HeaderCheckSum;\r
42 UINT32 FileLength;\r
43 UINT32 NumberOfImages;\r
44} EFILDR_HEADER;\r
45\r
46//\r
47// Utility Name\r
48//\r
49#define UTILITY_NAME "EfiLdrImage"\r
50\r
51//\r
52// Utility version information\r
53//\r
45258285
LG
54#define UTILITY_MAJOR_VERSION 1\r
55#define UTILITY_MINOR_VERSION 0\r
30fdf114
LG
56\r
57void\r
58Version (\r
59 void\r
60 )\r
61/*++\r
62\r
63Routine Description:\r
64\r
65 Displays the standard utility information to SDTOUT\r
66\r
67Arguments:\r
68\r
69 None\r
70\r
71Returns:\r
72\r
73 None\r
74\r
75--*/\r
76{\r
45258285 77 printf ("%s Version %d.%d Build %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
30fdf114
LG
78}\r
79\r
80VOID\r
81Usage (\r
82 VOID\r
83 )\r
84{\r
85 printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");\r
45258285 86 printf ("%s Version %d.%d Build %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
b5bd6387 87 printf ("Copyright (c) 1999-2017 Intel Corporation. All rights reserved.\n");\r
45258285 88 printf ("\n The EfiLdrImage tool is used to combine PE files into EFILDR image with Efi loader header.\n");\r
30fdf114
LG
89}\r
90\r
91EFI_STATUS\r
92CountVerboseLevel (\r
93 IN CONST CHAR8* VerboseLevelString,\r
94 IN CONST UINT64 Length,\r
95 OUT UINT64 *ReturnValue\r
96)\r
97{\r
98 UINT64 i = 0;\r
99 for (;i < Length; ++i) {\r
100 if (VerboseLevelString[i] != 'v' && VerboseLevelString[i] != 'V') {\r
101 return EFI_ABORTED;\r
102 }\r
103 ++(*ReturnValue);\r
104 }\r
f7496d71 105\r
30fdf114
LG
106 return EFI_SUCCESS;\r
107}\r
108\r
109UINT64\r
110FCopyFile (\r
111 FILE *in,\r
112 FILE *out\r
113 )\r
114/*++\r
115Routine Description:\r
116 Write all the content of input file to output file.\r
117\r
118Arguments:\r
119 in - input file pointer\r
120 out - output file pointer\r
121\r
122Return:\r
123 UINT64 : file size of input file\r
124--*/\r
125{\r
fd171542 126 UINT32 filesize, offset, length;\r
30fdf114
LG
127 CHAR8 Buffer[8*1024];\r
128\r
129 fseek (in, 0, SEEK_END);\r
130 filesize = ftell(in);\r
131\r
132 fseek (in, 0, SEEK_SET);\r
133\r
134 offset = 0;\r
135 while (offset < filesize) {\r
136 length = sizeof(Buffer);\r
137 if (filesize-offset < length) {\r
138 length = filesize-offset;\r
139 }\r
140\r
141 fread (Buffer, length, 1, in);\r
142 fwrite (Buffer, length, 1, out);\r
143 offset += length;\r
144 }\r
145\r
146 return filesize;\r
147}\r
148\r
149\r
150int\r
151main (\r
152 int argc,\r
153 char *argv[]\r
154 )\r
155/*++\r
156\r
157Routine Description:\r
158\r
159\r
160Arguments:\r
161\r
162\r
163Returns:\r
164\r
165\r
166--*/\r
167{\r
168 UINT64 i;\r
169 UINT64 filesize;\r
170 FILE *fpIn, *fpOut;\r
171 EFILDR_HEADER EfiLdrHeader;\r
172 EFILDR_IMAGE EfiLdrImage[MAX_PE_IMAGES];\r
173 CHAR8* OutputFileName = NULL;\r
174 CHAR8* InputFileNames[MAX_PE_IMAGES + 1];\r
175 UINT8 InputFileCount = 0;\r
30fdf114
LG
176 UINT64 DebugLevel = 0;\r
177 UINT64 VerboseLevel = 0;\r
178 EFI_STATUS Status = EFI_SUCCESS;\r
f7496d71 179\r
30fdf114
LG
180 SetUtilityName (UTILITY_NAME);\r
181\r
182 if (argc == 1) {\r
45258285 183 printf ("Usage: EfiLdrImage -o OutImage LoaderImage PeImage1 PeImage2 ... PeImageN\n");\r
30fdf114
LG
184 return STATUS_ERROR;\r
185 }\r
f7496d71 186\r
30fdf114
LG
187 argc --;\r
188 argv ++;\r
189\r
190 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
191 Usage();\r
f7496d71 192 return STATUS_SUCCESS;\r
30fdf114
LG
193 }\r
194\r
195 if (stricmp (argv[0], "--version") == 0) {\r
196 Version();\r
f7496d71 197 return STATUS_SUCCESS;\r
30fdf114
LG
198 }\r
199\r
200 while (argc > 0) {\r
f7496d71 201\r
30fdf114
LG
202 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {\r
203 OutputFileName = argv[1];\r
204 if (OutputFileName == NULL) {\r
205 Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");\r
206 return STATUS_ERROR;\r
207 }\r
208 argc -= 2;\r
209 argv += 2;\r
f7496d71 210 continue;\r
30fdf114 211 }\r
f7496d71 212\r
30fdf114 213 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
30fdf114
LG
214 argc --;\r
215 argv ++;\r
f7496d71 216 continue;\r
30fdf114 217 }\r
f7496d71 218\r
30fdf114
LG
219 if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (stricmp (argv[0], "--verbose") == 0)) {\r
220 VerboseLevel = 1;\r
221 if (strlen(argv[0]) > 2) {\r
222 Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel);\r
223 if (EFI_ERROR (Status)) {\r
b5bd6387 224 Error (NULL, 0, 1003, "Invalid option value", "%s", argv[0]);\r
f7496d71 225 return STATUS_ERROR;\r
30fdf114
LG
226 }\r
227 }\r
f7496d71 228\r
30fdf114
LG
229 argc --;\r
230 argv ++;\r
f7496d71 231 continue;\r
30fdf114 232 }\r
f7496d71 233\r
30fdf114
LG
234 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
235 Status = AsciiStringToUint64 (argv[1], FALSE, &DebugLevel);\r
236 if (EFI_ERROR (Status)) {\r
237 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
f7496d71 238 return STATUS_ERROR;\r
30fdf114
LG
239 }\r
240 argc -= 2;\r
241 argv += 2;\r
f7496d71 242 continue;\r
30fdf114
LG
243 }\r
244 //\r
fd171542 245 // Don't recognize the parameter, should be regarded as the input file name.\r
30fdf114
LG
246 //\r
247 InputFileNames[InputFileCount] = argv[0];\r
248 InputFileCount++;\r
249 argc--;\r
250 argv++;\r
251 }\r
252\r
253 if (InputFileCount == 0) {\r
254 Error (NULL, 0, 1001, "Missing option", "No input file");\r
255 return STATUS_ERROR;\r
256 }\r
257 //\r
258 // Open output file for write\r
259 //\r
260 if (OutputFileName == NULL) {\r
261 Error (NULL, 0, 1001, "Missing option", "No output file");\r
262 return STATUS_ERROR;\r
263 }\r
264\r
1be2ed90 265 fpOut = fopen (LongFilePath (OutputFileName), "w+b");\r
30fdf114
LG
266 if (!fpOut) {\r
267 Error (NULL, 0, 0001, "Could not open output file", OutputFileName);\r
268 return STATUS_ERROR;\r
269 }\r
270\r
271 memset (&EfiLdrHeader, 0, sizeof (EfiLdrHeader));\r
272 memset (&EfiLdrImage, 0, sizeof (EFILDR_IMAGE) * (InputFileCount));\r
273\r
274 memcpy (&EfiLdrHeader.Signature, "EFIL", 4);\r
275 EfiLdrHeader.FileLength = sizeof(EFILDR_HEADER) + sizeof(EFILDR_IMAGE)*(InputFileCount);\r
276\r
277 //\r
278 // Skip the file header first\r
279 //\r
280 fseek (fpOut, EfiLdrHeader.FileLength, SEEK_SET);\r
281\r
282 //\r
283 // copy all the input files to the output file\r
284 //\r
285 for(i=0;i<InputFileCount;i++) {\r
286 //\r
287 // Copy the content of PeImage file to output file\r
288 //\r
1be2ed90 289 fpIn = fopen (LongFilePath (InputFileNames[i]), "rb");\r
30fdf114
LG
290 if (!fpIn) {\r
291 Error (NULL, 0, 0001, "Could not open input file", InputFileNames[i]);\r
292 fclose (fpOut);\r
293 return STATUS_ERROR;\r
294 }\r
295 filesize = FCopyFile (fpIn, fpOut);\r
296 fclose(fpIn);\r
297\r
298 //\r
299 // And in the same time update the EfiLdrHeader and EfiLdrImage array\r
300 //\r
301 EfiLdrImage[i].Offset = EfiLdrHeader.FileLength;\r
fd171542 302 EfiLdrImage[i].Length = (UINT32) filesize;\r
30fdf114 303 strncpy ((CHAR8*) EfiLdrImage[i].FileName, InputFileNames[i], sizeof (EfiLdrImage[i].FileName) - 1);\r
fd171542 304 EfiLdrHeader.FileLength += (UINT32) filesize;\r
30fdf114
LG
305 EfiLdrHeader.NumberOfImages++;\r
306 }\r
307\r
308 //\r
309 // Write the image header to the output file finally\r
310 //\r
311 fseek (fpOut, 0, SEEK_SET);\r
312 fwrite (&EfiLdrHeader, sizeof(EFILDR_HEADER) , 1, fpOut);\r
313 fwrite (&EfiLdrImage , sizeof(EFILDR_IMAGE)*(InputFileCount), 1, fpOut);\r
314\r
315 fclose (fpOut);\r
316 printf ("Created %s\n", OutputFileName);\r
317 return 0;\r
318}\r
319\r