]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Sample/Tools/Source/FwImage/fwimage.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / FwImage / fwimage.c
CommitLineData
3eb9473e 1/*++\r
2\r
3Copyright (c) 2004 - 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 fwimage.c\r
15\r
16Abstract:\r
17\r
18 Converts a pe32/pe32+ image to an FW image type\r
19\r
20--*/\r
21\r
22#include <windows.h>\r
23#include <stdio.h>\r
24#include <stdlib.h>\r
25#include <string.h>\r
26#include <time.h>\r
27\r
28#include "TianoCommon.h"\r
29#include "EfiImage.h"\r
30#include "EfiUtilityMsgs.c"\r
31\r
32#define UTILITY_NAME "FwImage"\r
33\r
34typedef union {\r
35 IMAGE_NT_HEADERS32 PeHeader32;\r
36 IMAGE_NT_HEADERS64 PeHeader64;\r
37} PE_HEADER;\r
38\r
39VOID\r
40Usage (\r
41 VOID\r
42 )\r
43{\r
44 printf ("Usage: " UTILITY_NAME " {-t time-date} {-e} {-r} [APPLICATION|BS_DRIVER|RT_DRIVER|SAL_RT_DRIVER|COMBINED_PEIM_DRIVER|SECURITY_CORE|PEI_CORE|PE32_PEIM|RELOCATABLE_PEIM] peimage [outimage]\n");\r
45 printf (" -t: Add Time Stamp for output image\n");\r
46 printf (" -e: Not clear ExceptionTable for output image\n");\r
47 printf (" -r: Not strip zero pending of .reloc for output image\n");\r
48}\r
49\r
50static\r
51STATUS\r
52FReadFile (\r
53 FILE *in,\r
54 VOID **Buffer,\r
55 UINTN *Length\r
56 )\r
57{\r
58 fseek (in, 0, SEEK_END);\r
59 *Length = ftell (in);\r
60 *Buffer = malloc (*Length);\r
61 fseek (in, 0, SEEK_SET);\r
62 fread (*Buffer, *Length, 1, in);\r
63 return STATUS_SUCCESS;\r
64}\r
65\r
66static\r
67STATUS\r
68FWriteFile (\r
69 FILE *out,\r
70 VOID *Buffer,\r
71 UINTN Length\r
72 )\r
73{\r
74 fseek (out, 0, SEEK_SET);\r
75 fwrite (Buffer, Length, 1, out);\r
76 if ((ULONG) ftell (out) != Length) {\r
77 Error (NULL, 0, 0, "write error", NULL);\r
78 return STATUS_ERROR;\r
79 }\r
80 free (Buffer);\r
81 return STATUS_SUCCESS;\r
82}\r
83\r
84VOID\r
85ZeroExceptionTable (\r
86 IN UINT8 *FileBuffer,\r
87 IN EFI_IMAGE_DOS_HEADER *DosHdr,\r
88 IN PE_HEADER *PeHdr\r
89 )\r
90{\r
91 UINT32 PdataSize;\r
92 UINT32 PdataOffset;\r
93 UINT32 PdataRVASize;\r
94 UINT32 PdataRVA;\r
95 UINT32 SectionOffset;\r
96 UINT16 SectionNumber;\r
97 UINT32 SectionNameSize;\r
98 EFI_IMAGE_SECTION_HEADER *Section;\r
99\r
100 PdataSize = 0;\r
101 PdataOffset = 0;\r
102 PdataRVASize = 0;\r
103 PdataRVA = 0;\r
104 SectionOffset = 0;\r
105\r
106 //\r
107 // Search .pdata section\r
108 //\r
109 if (PeHdr->PeHeader32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
110 if ((PeHdr->PeHeader32.OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXCEPTION) &&\r
111 (PeHdr->PeHeader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0) &&\r
112 (PeHdr->PeHeader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0)) {\r
113\r
114 PdataRVA = PeHdr->PeHeader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress;\r
115 PdataRVASize = PeHdr->PeHeader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size;\r
116\r
117 PeHdr->PeHeader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
118 PeHdr->PeHeader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
119\r
120 SectionOffset = sizeof(PeHdr->PeHeader32);\r
121 }\r
122 } else {\r
123 if ((PeHdr->PeHeader64.OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXCEPTION) &&\r
124 (PeHdr->PeHeader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0) &&\r
125 (PeHdr->PeHeader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0)) {\r
126\r
127 PdataRVA = PeHdr->PeHeader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress;\r
128 PdataRVASize = PeHdr->PeHeader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size;\r
129\r
130 PeHdr->PeHeader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
131 PeHdr->PeHeader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
132\r
133 SectionOffset = sizeof(PeHdr->PeHeader64);\r
134 }\r
135 }\r
136\r
137 if ((PdataRVASize != 0) && (PdataRVA != 0)) {\r
138\r
139 SectionNumber = PeHdr->PeHeader32.FileHeader.NumberOfSections;\r
140 SectionNameSize = sizeof(Section->Name);\r
141 while (SectionNumber > 0) {\r
142 Section = (EFI_IMAGE_SECTION_HEADER *) &FileBuffer[DosHdr->e_lfanew + SectionOffset];\r
143 if (strcmp (Section->Name, ".pdata") == 0) {\r
144 //\r
145 // Zero .pdata Section Header Name\r
146 //\r
147 memset (\r
148 FileBuffer + DosHdr->e_lfanew + SectionOffset,\r
149 0,\r
150 SectionNameSize);\r
151\r
152 //\r
153 // Zero .pdata Secton raw data\r
154 //\r
155 PdataOffset = Section->PointerToRawData;\r
156 PdataSize = Section->SizeOfRawData;\r
157 memset (FileBuffer + PdataOffset, 0, PdataSize);\r
158 break;\r
159 }\r
160 SectionNumber--;\r
161 SectionOffset += sizeof(EFI_IMAGE_SECTION_HEADER);\r
162 }\r
163 }\r
164 \r
165 return ;\r
166}\r
167\r
168VOID\r
169StripZeroPendingReloc (\r
170 IN UINT8 *FileBuffer,\r
171 IN OUT UINTN *FileLength,\r
172 IN EFI_IMAGE_DOS_HEADER *DosHdr,\r
173 IN PE_HEADER *PeHdr\r
174 )\r
175{\r
176 EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;\r
177 EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;\r
178 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
179 UINTN AllignedRelocSize;\r
180 UINTN Index;\r
181\r
182 if (PeHdr->PeHeader32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
183 Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->PeHeader32.OptionalHeader;\r
184 if ((Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) &&\r
185 (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)) {\r
186 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->PeHeader32.FileHeader.SizeOfOptionalHeader);\r
187 for (Index = 0; Index < PeHdr->PeHeader32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
188 //\r
189 // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
190 //\r
191 if (strcmp (SectionHeader->Name, ".reloc") == 0) {\r
192 SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
193\r
194 AllignedRelocSize = (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size +\r
195 Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1));\r
196 //\r
197 // Check to see if there is zero padding at the end of the base relocations\r
198 //\r
199 if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
200 //\r
201 // Check to see if the base relocations are at the end of the file\r
202 //\r
203 if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) {\r
204 //\r
205 // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
206 //\r
207 Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
208 Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
209 SectionHeader->SizeOfRawData = AllignedRelocSize;\r
210 *FileLength = Optional32->SizeOfImage;\r
211 }\r
212 }\r
213 }\r
214 }\r
215 }\r
216 } else {\r
217 Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->PeHeader64.OptionalHeader;\r
218 if ((Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) &&\r
219 (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)) {\r
220 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->PeHeader64.FileHeader.SizeOfOptionalHeader);\r
221 for (Index = 0; Index < PeHdr->PeHeader64.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
222 //\r
223 // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
224 //\r
225 if (strcmp (SectionHeader->Name, ".reloc") == 0) {\r
226 SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
227\r
228 AllignedRelocSize = (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size +\r
229 Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1));\r
230 //\r
231 // Check to see if there is zero padding at the end of the base relocations\r
232 //\r
233 if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
234 //\r
235 // Check to see if the base relocations are at the end of the file\r
236 //\r
237 if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) {\r
238 //\r
239 // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
240 //\r
241 Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
242 Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
243 SectionHeader->SizeOfRawData = AllignedRelocSize;\r
244 *FileLength = Optional64->SizeOfImage;\r
245 }\r
246 }\r
247 }\r
248 }\r
249 }\r
250 }\r
251}\r
252\r
253int\r
254main (\r
255 int argc,\r
256 char *argv[]\r
257 )\r
258/*++\r
259\r
260Routine Description:\r
261\r
262 Main function.\r
263\r
264Arguments:\r
265\r
266 argc - Number of command line parameters.\r
267 argv - Array of pointers to command line parameter strings.\r
268\r
269Returns:\r
270\r
271 STATUS_SUCCESS - Utility exits successfully.\r
272 STATUS_ERROR - Some error occurred during execution.\r
273\r
274--*/\r
275{\r
276 ULONG Type;\r
277 PUCHAR Ext;\r
278 PUCHAR p;\r
279 PUCHAR pe;\r
280 PUCHAR OutImageName;\r
281 UCHAR outname[500];\r
282 FILE *fpIn;\r
283 FILE *fpOut;\r
284 EFI_IMAGE_DOS_HEADER *DosHdr;\r
285 PE_HEADER *PeHdr;\r
286 time_t TimeStamp;\r
287 struct tm TimeStruct;\r
288 EFI_IMAGE_DOS_HEADER BackupDosHdr;\r
289 ULONG Index;\r
290 BOOLEAN TimeStampPresent;\r
291 BOOLEAN NeedClearExceptionTable;\r
292 BOOLEAN NeedStripZeroPendingReloc;\r
293 UINT8 *FileBuffer;\r
294 UINTN FileLength;\r
295 EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;\r
296 EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;\r
297\r
298 SetUtilityName (UTILITY_NAME);\r
299 //\r
300 // Assign to fix compile warning\r
301 //\r
302 OutImageName = NULL;\r
303 Type = 0;\r
304 Ext = 0;\r
305 TimeStamp = 0;\r
306 TimeStampPresent = FALSE;\r
307\r
308 NeedClearExceptionTable = TRUE;\r
309 NeedStripZeroPendingReloc = TRUE;\r
310\r
311 //\r
312 // Look for -t time-date option first. If the time is "0", then\r
313 // skip it.\r
314 //\r
315 if ((argc > 2) && !strcmp (argv[1], "-t")) {\r
316 TimeStampPresent = TRUE;\r
317 if (strcmp (argv[2], "0") != 0) {\r
318 //\r
319 // Convert the string to a value\r
320 //\r
321 memset ((char *) &TimeStruct, 0, sizeof (TimeStruct));\r
322 if (sscanf(\r
323 argv[2], "%d/%d/%d,%d:%d:%d",\r
324 &TimeStruct.tm_mon, /* months since January - [0,11] */\r
325 &TimeStruct.tm_mday, /* day of the month - [1,31] */\r
326 &TimeStruct.tm_year, /* years since 1900 */\r
327 &TimeStruct.tm_hour, /* hours since midnight - [0,23] */\r
328 &TimeStruct.tm_min, /* minutes after the hour - [0,59] */\r
329 &TimeStruct.tm_sec /* seconds after the minute - [0,59] */\r
330 ) != 6) {\r
331 Error (NULL, 0, 0, argv[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format");\r
332 return STATUS_ERROR;\r
333 }\r
334 //\r
335 // Now fixup some of the fields\r
336 //\r
337 TimeStruct.tm_mon--;\r
338 TimeStruct.tm_year -= 1900;\r
339 //\r
340 // Sanity-check values?\r
341 // Convert\r
342 //\r
343 TimeStamp = mktime (&TimeStruct);\r
344 if (TimeStamp == (time_t) - 1) {\r
345 Error (NULL, 0, 0, argv[2], "failed to convert time");\r
346 return STATUS_ERROR;\r
347 }\r
348 }\r
349 //\r
350 // Skip over the args\r
351 //\r
352 argc -= 2;\r
353 argv += 2;\r
354 }\r
355\r
356 //\r
357 // Look for -e option.\r
358 //\r
359 if ((argc > 1) && !strcmp (argv[1], "-e")) {\r
360 NeedClearExceptionTable = FALSE;\r
361 //\r
362 // Skip over the args\r
363 //\r
364 argc -= 1;\r
365 argv += 1;\r
366 }\r
367\r
368 //\r
369 // Look for -r option\r
370 //\r
371 if ((argc > 1) && !strcmp (argv[1], "-r")) {\r
372 NeedStripZeroPendingReloc = FALSE;\r
373 //\r
374 // Skip over the args\r
375 //\r
376 argc -= 1;\r
377 argv += 1;\r
378 }\r
379\r
380 //\r
381 // Check for enough args\r
382 //\r
383 if (argc < 3) {\r
384 Usage ();\r
385 return STATUS_ERROR;\r
386 }\r
387\r
388 if (argc == 4) {\r
389 OutImageName = argv[3];\r
390 }\r
391 //\r
392 // Get new image type\r
393 //\r
394 p = argv[1];\r
395 if (*p == '/' || *p == '\\') {\r
396 p += 1;\r
397 }\r
398\r
399 if (_stricmp (p, "app") == 0 || _stricmp (p, "APPLICATION") == 0) {\r
400 Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
401 Ext = ".efi";\r
402\r
403 } else if (_stricmp (p, "bsdrv") == 0 || _stricmp (p, "BS_DRIVER") == 0) {\r
404 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
405 Ext = ".efi";\r
406\r
407 } else if (_stricmp (p, "rtdrv") == 0 || _stricmp (p, "RT_DRIVER") == 0) {\r
408 Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;\r
409 Ext = ".efi";\r
410\r
411 } else if (_stricmp (p, "rtdrv") == 0 || _stricmp (p, "SAL_RT_DRIVER") == 0) {\r
412 Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;\r
413 Ext = ".efi";\r
414 } else if (_stricmp (p, "SECURITY_CORE") == 0) {\r
415 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
416 Ext = ".sec";\r
417 } else if (_stricmp (p, "peim") == 0 ||\r
418 _stricmp (p, "PEI_CORE") == 0 ||\r
419 _stricmp (p, "PE32_PEIM") == 0 ||\r
420 _stricmp (p, "RELOCATABLE_PEIM") == 0 ||\r
421 _stricmp (p, "combined_peim_driver") == 0\r
422 ) {\r
423 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
424 Ext = ".pei";\r
425 } else {\r
426 Usage ();\r
427 return STATUS_ERROR;\r
428 }\r
429 //\r
430 // open source file\r
431 //\r
432 fpIn = fopen (argv[2], "rb");\r
433 if (!fpIn) {\r
434 Error (NULL, 0, 0, argv[2], "failed to open input file for reading");\r
435 return STATUS_ERROR;\r
436 }\r
437 FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength);\r
438 //\r
439 // Read the dos & pe hdrs of the image\r
440 //\r
441 DosHdr = (EFI_IMAGE_DOS_HEADER *) FileBuffer;\r
442 if (DosHdr->e_magic != IMAGE_DOS_SIGNATURE) {\r
443 Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image");\r
444 fclose (fpIn);\r
445 return STATUS_ERROR;\r
446 }\r
447\r
448 PeHdr = (PE_HEADER *)(FileBuffer + DosHdr->e_lfanew);\r
449 if (PeHdr->PeHeader32.Signature != IMAGE_NT_SIGNATURE) {\r
450 Error (NULL, 0, 0, argv[2], "PE header signature not found in source image");\r
451 fclose (fpIn);\r
452 return STATUS_ERROR;\r
453 }\r
454 //\r
455 // open output file\r
456 //\r
457 strcpy (outname, argv[2]);\r
458 pe = NULL;\r
459 for (p = outname; *p; p++) {\r
460 if (*p == '.') {\r
461 pe = p;\r
462 }\r
463 }\r
464\r
465 if (!pe) {\r
466 pe = p;\r
467 }\r
468\r
469 strcpy (pe, Ext);\r
470\r
471 if (!OutImageName) {\r
472 OutImageName = outname;\r
473 }\r
474\r
475 fpOut = fopen (OutImageName, "w+b");\r
476 if (!fpOut) {\r
477 Error (NULL, 0, 0, OutImageName, "could not open output file for writing");\r
478 fclose (fpIn);\r
479 return STATUS_ERROR;\r
480 }\r
481 //\r
482 // Zero all unused fields of the DOS header\r
483 //\r
484 memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER));\r
485 memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));\r
486 DosHdr->e_magic = BackupDosHdr.e_magic;\r
487 DosHdr->e_lfanew = BackupDosHdr.e_lfanew;\r
488\r
489 for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (ULONG) DosHdr->e_lfanew; Index++) {\r
490 FileBuffer[Index] = (UINT8) DosHdr->e_cp;\r
491 }\r
492 \r
493 //\r
494 // Modify some fields in the PE header\r
495 //\r
496\r
497 //\r
498 // TimeDateStamp's offset is fixed for PE32/32+\r
499 //\r
500 if (TimeStampPresent) {\r
501 PeHdr->PeHeader32.FileHeader.TimeDateStamp = (UINT32) TimeStamp;\r
502 }\r
503\r
504 //\r
505 // PE32/32+ has different optional header layout\r
506 // Determine format is PE32 or PE32+ before modification\r
507 //\r
508 if (PeHdr->PeHeader32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
509 //\r
510 // PE32 image\r
511 //\r
512 Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->PeHeader32.OptionalHeader;\r
513\r
514 Optional32->MajorLinkerVersion = 0;\r
515 Optional32->MinorLinkerVersion = 0;\r
516 Optional32->MajorOperatingSystemVersion = 0;\r
517 Optional32->MinorOperatingSystemVersion = 0;\r
518 Optional32->MajorImageVersion = 0;\r
519 Optional32->MinorImageVersion = 0;\r
520 Optional32->MajorSubsystemVersion = 0;\r
521 Optional32->MinorSubsystemVersion = 0;\r
522 Optional32->Win32VersionValue = 0;\r
523 Optional32->CheckSum = 0;\r
524 Optional32->SizeOfStackReserve = 0;\r
525 Optional32->SizeOfStackCommit = 0;\r
526 Optional32->SizeOfHeapReserve = 0;\r
527 Optional32->SizeOfHeapCommit = 0;\r
528 Optional32->Subsystem = (USHORT) Type;\r
529\r
530 //\r
531 // Strip zero padding at the end of the .reloc section \r
532 //\r
533 if (NeedStripZeroPendingReloc) {\r
534 StripZeroPendingReloc (FileBuffer, &FileLength, DosHdr, PeHdr);\r
535 }\r
536 } else if (PeHdr->PeHeader32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
537 //\r
538 // PE32+ image\r
539 //\r
540 Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->PeHeader64.OptionalHeader;\r
541\r
542 Optional64->MajorLinkerVersion = 0;\r
543 Optional64->MinorLinkerVersion = 0;\r
544 Optional64->MajorOperatingSystemVersion = 0;\r
545 Optional64->MinorOperatingSystemVersion = 0;\r
546 Optional64->MajorImageVersion = 0;\r
547 Optional64->MinorImageVersion = 0;\r
548 Optional64->MajorSubsystemVersion = 0;\r
549 Optional64->MinorSubsystemVersion = 0;\r
550 Optional64->Win32VersionValue = 0;\r
551 Optional64->CheckSum = 0;\r
552 Optional64->SizeOfStackReserve = 0;\r
553 Optional64->SizeOfStackCommit = 0;\r
554 Optional64->SizeOfHeapReserve = 0;\r
555 Optional64->SizeOfHeapCommit = 0;\r
556 Optional64->Subsystem = (USHORT) Type;\r
557\r
558 //\r
559 // Strip zero padding at the end of the .reloc section \r
560 //\r
561 if (NeedStripZeroPendingReloc) {\r
562 StripZeroPendingReloc (FileBuffer, &FileLength, DosHdr, PeHdr);\r
563 }\r
564 } else {\r
565 Error (NULL, 0, 0, argv[2], "Unsupported PE image");\r
566 fclose (fpIn);\r
567 fclose (fpOut);\r
568 return STATUS_ERROR;\r
569 }\r
570\r
571 //\r
572 // Zero PDATA section for smaller binary size after compression\r
573 //\r
574 if (NeedClearExceptionTable) {\r
575 ZeroExceptionTable (FileBuffer, DosHdr, PeHdr);\r
576 }\r
577\r
578 FWriteFile (fpOut, FileBuffer, FileLength);\r
579\r
580 //\r
581 // Done\r
582 //\r
583 fclose (fpIn);\r
584 fclose (fpOut);\r
585\r
586 return STATUS_SUCCESS;\r
587}\r