1 /********************************************************************************
2 * *
3 * L o a d I c o n F r o m E x e c u t a b l e *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2014,2020 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as published by *
10 * the Free Software Foundation; either version 3 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/> *
20 ********************************************************************************/
21 #include "xincs.h"
22 #include "fxver.h"
23 #include "fxdefs.h"
24 #include "fxmath.h"
25 #include "fxascii.h"
26 #include "fxunicode.h"
27 #include "FXArray.h"
28 #include "FXHash.h"
29 #include "FXStream.h"
30 #include "FXString.h"
31 #include "FXElement.h"
32 #include "FXStream.h"
33
34
35 /*
36 Notes:
37 - Load icon from resource in Microsoft Windows executable.
38
39 - Useful to display correct icon inside file list widgets.
40
41 - Operation:
42
43 o Scan portable execution header for resource segment.
44 o Burrow down resource directories matching resource type and id.
45 o Then, depending on resource type, use fxloadBMP() or fxloadICO() to pluck
46 the resource apart into the desired image pixel data.
47
48 - Not the entire executable image is scanned; thus, potential problem exists
49 because we have no way of determining the end of the stream. Thus there is
50 no way these can be embedded in a stream of other things as the stream-
51 pointer is left somewhere in the resource segment of the executable image.
52
53 - Thankfully this is not a major issue in most cases.
54 */
55
56 // Maximum recursion level
57 #define MAXRECLEVEL 3
58
59 // Executable file signatures
60 #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
61 #define IMAGE_OS2_SIGNATURE 0x454E // NE
62 #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
63 #define IMAGE_VXD_SIGNATURE 0x454C // LE
64 #define IMAGE_NT_SIGNATURE 0x00004550 // PE00
65
66 // Optional header magic numbers
67 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
68 #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
69
70 // Image data directory entries
71 #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
72 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
73 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
74 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
75 #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
76 #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
77 #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
78 #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
79 #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
80 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
81 #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
82 #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
83 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
84 #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
85 #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
86 #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
87
88 // Image resource directory entry flag bits
89 #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
90 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
91
92 // Resource types
93 #define RST_CURSOR 1
94 #define RST_BITMAP 2
95 #define RST_ICON 3
96 #define RST_MENU 4
97 #define RST_DIALOG 5
98 #define RST_STRING 6
99 #define RST_FONTDIR 7
100 #define RST_FONT 8
101 #define RST_ACCELERATOR 9
102 #define RST_RCDATA 10
103 #define RST_MESSAGELIST 11
104 #define RST_GROUP_CURSOR 12
105 #define RST_GROUP_ICON 14
106
107 using namespace FX;
108
109 /*******************************************************************************/
110
111 namespace FX {
112
113 // Declarations
114 extern FXAPI FXbool fxcheckEXE(FXStream& store);
115 extern FXAPI FXbool fxloadEXE(FXStream& store,FXColor*& data,FXint& width,FXint& height,FXint type,FXint id);
116
117 // From BMP loader
118 extern FXAPI FXbool fxloadBMP(FXStream& store,FXColor*& data,FXint& width,FXint& height);
119 extern FXAPI FXbool fxloadDIB(FXStream& store,FXColor*& data,FXint& width,FXint& height);
120
121 // From ICO loader
122 extern FXAPI FXbool fxloadICO(FXStream& store,FXColor*& data,FXint& width,FXint& height,FXint& xspot,FXint& yspot);
123 extern FXAPI FXbool fxloadICOStream(FXStream& store,FXColor*& data,FXint& width,FXint& height);
124
125
126 // DOS file header
127 struct ImageDosHeader {
128 FXushort magic; // Magic number
129 FXushort cblp; // Bytes on last page of file
130 FXushort cp; // Pages in file
131 FXushort crlc; // Relocations
132 FXushort cparhdr; // Size of header in paragraphs
133 FXushort minalloc; // Minimum extra paragraphs needed
134 FXushort maxalloc; // Maximum extra paragraphs needed
135 FXushort ss; // Initial (relative) SS value
136 FXushort sp; // Initial SP value
137 FXushort csum; // Checksum
138 FXushort ip; // Initial IP value
139 FXushort cs; // Initial (relative) CS value
140 FXushort lfarlc; // File address of relocation table
141 FXushort ovno; // Overlay number
142 FXushort res[4]; // Reserved words
143 FXushort oemid; // OEM identifier (for e_oeminfo)
144 FXushort oeminfo; // OEM information; e_oemid specific
145 FXushort res2[10]; // Reserved words
146 FXuint lfanew; // File address of new exe header
147 };
148
149
150 // Image file header
151 struct ImageFileHeader {
152 FXushort machine; // CPU architecture
153 FXushort numberOfSections; // Number of sections in section table
154 FXuint timeDateStamp; // Date and time of program link
155 FXuint pointerToSymbolTable; // RVA of symbol table
156 FXuint numberOfSymbols; // Number of symbols in table
157 FXushort sizeOfOptionalHeader; // Size of IMAGE_OPTIONAL_HEADER in bytes
158 FXushort characteristics; // Flag bits
159 };
160
161
162 // Portable executable file header
163 struct ImageNTHeader {
164 FXuint signature;
165 ImageFileHeader fileHeader;
166 };
167
168
169 // Data Directory
170 struct ImageDataDirectory {
171 FXuint virtualAddress; // RVA of table
172 FXuint size; // Size of table
173 };
174
175
176 // Optional Header
177 struct ImageOptionalHeader32 {
178 FXushort magic; // IMAGE_NT_OPTIONAL_HDR32_MAGIC
179 FXuchar majorLinkerVersion; // Linker version
180 FXuchar minorLinkerVersion;
181 FXuint sizeOfCode; // Size of .text in bytes
182 FXuint sizeOfInitializedData; // Size of .bss (and others) in bytes
183 FXuint sizeOfUninitializedData; // Size of .data,.sdata etc in bytes
184 FXuint addressOfEntryPoint; // RVA of entry point
185 FXuint baseOfCode; // Base of .text
186 FXuint baseOfData; // Base of .data
187 FXuint imageBase; // Image base VA
188 FXuint sectionAlignment; // File section alignment
189 FXuint fileAlignment; // File alignment
190 FXushort majorOperatingSystemVersion;
191 FXushort minorOperatingSystemVersion;
192 FXushort majorImageVersion; // Version of program
193 FXushort minorImageVersion;
194 FXushort majorSubsystemVersion; // Windows specific. Version of SubSystem
195 FXushort minorSubsystemVersion;
196 FXuint win32VersionValue;
197 FXuint sizeOfImage; // Size of image in bytes
198 FXuint sizeOfHeaders; // Size of headers (and stub program) in bytes
199 FXuint checksum;
200 FXushort subsystem;
201 FXushort dllCharacteristics; // DLL properties
202 FXuint sizeOfStackReserve; // Size of stack, in bytes
203 FXuint sizeOfStackCommit; // Size of stack to commit
204 FXuint sizeOfHeapReserve; // Size of heap, in bytes
205 FXuint sizeOfHeapCommit; // Size of heap to commit
206 FXuint loaderFlags;
207 FXuint numberOfRvaAndSizes; // Number of entries in dataDirectory
208 ImageDataDirectory dataDirectory[16];
209 };
210
211
212 // Optional Header
213 struct ImageOptionalHeader64 {
214 FXushort magic; // IMAGE_NT_OPTIONAL_HDR64_MAGIC
215 FXuchar majorLinkerVersion; // Linker version
216 FXuchar minorLinkerVersion;
217 FXuint sizeOfCode; // Size of .text in bytes
218 FXuint sizeOfInitializedData; // Size of .bss (and others) in bytes
219 FXuint sizeOfUninitializedData; // Size of .data,.sdata etc in bytes
220 FXuint addressOfEntryPoint; // RVA of entry point
221 FXuint baseOfCode; // Base of .text
222 FXulong imageBase; // Base of .data
223 FXuint sectionAlignment; // File section alignment
224 FXuint fileAlignment; // File alignment
225 FXushort majorOperatingSystemVersion;
226 FXushort minorOperatingSystemVersion;
227 FXushort majorImageVersion; // Version of program
228 FXushort minorImageVersion;
229 FXushort majorSubsystemVersion;
230 FXushort minorSubsystemVersion;
231 FXuint win32VersionValue;
232 FXuint sizeOfImage; // Size of image in bytes
233 FXuint sizeOfHeaders; // Size of headers (and stub program) in bytes
234 FXuint checksum;
235 FXushort subsystem;
236 FXushort dllCharacteristics; // DLL properties
237 FXulong sizeOfStackReserve; // Size of stack, in bytes
238 FXulong sizeOfStackCommit; // Size of stack to commit
239 FXulong sizeOfHeapReserve; // Size of heap, in bytes
240 FXulong sizeOfHeapCommit; // Size of heap to commit
241 FXuint loaderFlags;
242 FXuint numberOfRvaAndSizes; // Number of entries in dataDirectory
243 ImageDataDirectory dataDirectory[16];
244 };
245
246
247 // Optional header
248 union ImageOptionalHeader {
249 ImageOptionalHeader32 pe32; // 32 bit version
250 ImageOptionalHeader64 pe64; // 64 bit version
251 };
252
253
254 // Section header
255 struct ImageSectionHeader {
256 FXchar name[8]; // Name, e.g. .text
257 FXuint virtualSize; // Virtual size (may be bigger than sizeOfRawData)
258 FXuint virtualAddress; // Offset of first byte relative to imageBase
259 FXuint sizeOfRawData; // Size of raw data
260 FXuint pointerToRawData; // Pointer to raw data in COFF
261 FXuint pointerToRelocations;
262 FXuint pointerToLinenumbers;
263 FXushort numberOfRelocations;
264 FXushort numberOfLinenumbers;
265 FXuint characteristics;
266 };
267
268
269 // Resource Name (8-bit characters)
270 struct ImageResourceDirectoryString {
271 FXushort length;
272 FXchar nameString[1];
273 };
274
275
276 // Resource Name (16-bit characters)
277 struct ImageResourceDirectoryStringW {
278 FXushort length;
279 FXnchar nameString[1];
280 };
281
282
283 // Resource directory entry
284 struct ImageResourceDirectoryEntry {
285 FXuint name;
286 FXuint data;
287 };
288
289
290 // Resource directory
291 struct ImageResourceDirectory {
292 FXuint characteristics;
293 FXuint timeDateStamp;
294 FXushort majorVersion;
295 FXushort minorVersion;
296 FXushort numberOfNamedEntries;
297 FXushort numberOfIdEntries;
298 };
299
300
301 // Resource directory entry
302 struct ImageResourceDataEntry {
303 FXuint offsetToData;
304 FXuint size;
305 FXuint codePage;
306 FXuint reserved;
307 };
308
309
310 // Resource loader context
311 struct Context {
312 FXuint pointer; // Pointer in pe
313 FXuint address; // Relocated virtual address
314 FXuint size; // Size of resource
315 FXint wanted[MAXRECLEVEL]; // Items to match at each level
316 };
317
318 /*******************************************************************************/
319
320 // Check if stream represents windows executable
fxcheckEXE(FXStream & store)321 FXbool fxcheckEXE(FXStream& store){
322 FXuchar ss[2];
323 store.load(ss,2);
324 store.position(-2,FXFromCurrent);
325 return ss[0]=='M' && ss[1]=='Z';
326 }
327
328
329 // Scan the data
scandata(FXStream & store,FXColor * & data,FXint & width,FXint & height,const Context & ctx,FXlong start)330 static FXbool scandata(FXStream& store,FXColor*& data,FXint& width,FXint& height,const Context& ctx,FXlong start){
331 ImageResourceDataEntry res;
332 FXlong pos=store.position();
333 FXbool result=false;
334
335 FXTRACE((100,"scandata: %llu (%#llx)\n",start,start));
336
337 // Read resource data entry, at start
338 store.position(start);
339 store >> res.offsetToData;
340 store >> res.size;
341 store >> res.codePage;
342 store >> res.reserved;
343
344 FXTRACE((100,"res.offsetToData: %u (%#x)\n",res.offsetToData,res.offsetToData));
345 FXTRACE((100,"res.size: %u\n",res.size));
346 FXTRACE((100,"res.codePage: %u\n",res.codePage));
347 FXTRACE((100,"res.reserved: %u\n",res.reserved));
348
349 // Bail if at end
350 if(store.eof()) goto x;
351
352 // Now try read the image, or icon
353 store.position(ctx.pointer+res.offsetToData-ctx.address);
354 if(ctx.wanted[0]==RST_BITMAP){
355 result=fxloadDIB(store,data,width,height);
356 }
357 else if(ctx.wanted[0]==RST_ICON){
358 result=fxloadICOStream(store,data,width,height);
359 }
360 FXTRACE((100,"result: %u\n",result));
361 x:store.position(pos);
362 return result;
363 }
364
365
366 // Scan resource directory until we hit the jackpot
scanresources(FXStream & store,FXColor * & data,FXint & width,FXint & height,const Context & ctx,FXlong start,FXint lev)367 static FXbool scanresources(FXStream& store,FXColor*& data,FXint& width,FXint& height,const Context& ctx,FXlong start,FXint lev){
368 FXbool result=false;
369 if(ctx.pointer<=start && start<ctx.pointer+ctx.size && lev<MAXRECLEVEL){
370 ImageResourceDirectory dir;
371 FXlong pos=store.position();
372
373 // Jump to start of directory
374 store.position(start);
375 store >> dir.characteristics;
376 store >> dir.timeDateStamp;
377 store >> dir.majorVersion;
378 store >> dir.minorVersion;
379 store >> dir.numberOfNamedEntries;
380 store >> dir.numberOfIdEntries;
381
382 FXTRACE((100,"%*sdir.characteristics: %#08x\n",lev<<2,"",dir.characteristics));
383 FXTRACE((100,"%*sdir.timeDateStamp: %u\n",lev<<2,"",dir.timeDateStamp));
384 FXTRACE((100,"%*sdir.majorVersion: %u\n",lev<<2,"",dir.majorVersion));
385 FXTRACE((100,"%*sdir.minorVersion: %u\n",lev<<2,"",dir.minorVersion));
386 FXTRACE((100,"%*sdir.numberOfNamedEntries: %u\n",lev<<2,"",dir.numberOfNamedEntries));
387 FXTRACE((100,"%*sdir.numberOfIdEntries: %u\n\n",lev<<2,"",dir.numberOfIdEntries));
388
389 // We're still good?
390 if(!store.eof()){
391 ImageResourceDirectoryEntry entry;
392 FXint want=ctx.wanted[lev];
393
394 // Loop over the entries
395 for(FXint s=0; !result && s<dir.numberOfNamedEntries+dir.numberOfIdEntries; ++s){
396
397 // Read resource directory entry
398 store >> entry.name;
399 store >> entry.data;
400
401 // Still good?
402 if(store.eof()) goto x;
403
404 FXTRACE((100,"%*sentry.name: %u\n",lev<<2,"",entry.name));
405
406 // If don't care match or matching ID then check the rest, otherwise move on to next
407 if(want==-1 || (!(entry.name&IMAGE_RESOURCE_NAME_IS_STRING) && (entry.name&0xFFFF)==want)){
408 if(entry.data&IMAGE_RESOURCE_DATA_IS_DIRECTORY){
409 entry.data&=~IMAGE_RESOURCE_DATA_IS_DIRECTORY;
410 result=scanresources(store,data,width,height,ctx,ctx.pointer+entry.data,lev+1);
411 }
412 else{
413 result=scandata(store,data,width,height,ctx,ctx.pointer+entry.data);
414 }
415 }
416 }
417 }
418
419 // Restore
420 x: store.position(pos);
421 }
422 return result;
423 }
424
425
426 // Load resource from executable or dll
fxloadEXE(FXStream & store,FXColor * & data,FXint & width,FXint & height,FXint type,FXint id)427 FXbool fxloadEXE(FXStream& store,FXColor*& data,FXint& width,FXint& height,FXint type,FXint id){
428 FXbool result=false;
429
430 FXTRACE((100,"fxloadEXE(data,width,height,type:%d,id:%d)\n\n",type,id));
431
432 // Null out
433 data=NULL;
434 width=0;
435 height=0;
436
437 // Loading other than these is not gonna work
438 if(type==RST_BITMAP || type==RST_ICON){
439 FXbool swap=store.swapBytes();
440 ImageDosHeader dos;
441
442 // Bitmaps are little-endian
443 store.setBigEndian(false);
444
445 // Load DOS header
446 store >> dos.magic; // must contain "MZ"
447 store >> dos.cblp; // number of bytes on the last page of the file
448 store >> dos.cp; // number of pages in file
449 store >> dos.crlc; // relocations
450 store >> dos.cparhdr; // size of the header in paragraphs
451 store >> dos.minalloc; // minimum and maximum paragraphs to allocate
452 store >> dos.maxalloc;
453 store >> dos.ss; // initial SS:SP to set by Loader
454 store >> dos.sp;
455 store >> dos.csum; // checksum
456 store >> dos.ip; // initial CS:IP
457 store >> dos.cs;
458 store >> dos.lfarlc; // address of relocation table
459 store >> dos.ovno; // overlay number
460 store.load(dos.res,4);
461 store >> dos.oemid; // OEM id
462 store >> dos.oeminfo; // OEM info
463 store.load(dos.res2,10);
464 store >> dos.lfanew; // address of new EXE header
465
466 FXTRACE((100,"dos.magic: %#04x\n",dos.magic));
467 FXTRACE((100,"dos.cblp: %d\n",dos.cblp));
468 FXTRACE((100,"dos.cp: %d\n",dos.cp));
469 FXTRACE((100,"dos.crlc: %d\n",dos.crlc));
470 FXTRACE((100,"dos.cparhdr: %d\n",dos.cparhdr));
471 FXTRACE((100,"dos.minalloc: %d\n",dos.minalloc));
472 FXTRACE((100,"dos.maxalloc: %d\n",dos.maxalloc));
473 FXTRACE((100,"dos.ss: %d\n",dos.ss));
474 FXTRACE((100,"dos.sp: %d\n",dos.sp));
475 FXTRACE((100,"dos.csum: %d\n",dos.csum));
476 FXTRACE((100,"dos.ip: %d\n",dos.ip));
477 FXTRACE((100,"dos.cs: %d\n",dos.cs));
478 FXTRACE((100,"dos.lfarlc: %d\n",dos.lfarlc));
479 FXTRACE((100,"dos.oemid: %d\n",dos.oemid));
480 FXTRACE((100,"dos.oeminfo: %d\n",dos.oeminfo));
481 FXTRACE((100,"dos.lfanew: %d\n\n",dos.lfanew));
482
483 // Expect MZ
484 if((dos.magic==IMAGE_DOS_SIGNATURE) && !store.eof()){
485 ImageNTHeader nt;
486
487 // Skip to NT header
488 store.position(dos.lfanew);
489
490 // File header
491 store >> nt.signature;
492 store >> nt.fileHeader.machine;
493 store >> nt.fileHeader.numberOfSections; // Number of sections in section table
494 store >> nt.fileHeader.timeDateStamp; // Date and time of program link
495 store >> nt.fileHeader.pointerToSymbolTable; // RVA of symbol table
496 store >> nt.fileHeader.numberOfSymbols; // Number of symbols in table
497 store >> nt.fileHeader.sizeOfOptionalHeader; // Size of IMAGE_OPTIONAL_HEADER in bytes
498 store >> nt.fileHeader.characteristics;
499
500 // Dump NT header
501 FXTRACE((100,"nt.signature: %#04x\n",nt.signature));
502 FXTRACE((100,"nt.fileHeader.machine: %4x\n",nt.fileHeader.machine));
503 FXTRACE((100,"nt.fileHeader.numberOfSections: %u\n",nt.fileHeader.numberOfSections));
504 FXTRACE((100,"nt.fileHeader.timeDateStamp: %u\n",nt.fileHeader.timeDateStamp));
505 FXTRACE((100,"nt.fileHeader.pointerToSymbolTable: %u\n",nt.fileHeader.pointerToSymbolTable));
506 FXTRACE((100,"nt.fileHeader.numberOfSymbols: %u\n",nt.fileHeader.numberOfSymbols));
507 FXTRACE((100,"nt.fileHeader.sizeOfOptionalHeader: %u\n",nt.fileHeader.sizeOfOptionalHeader));
508 FXTRACE((100,"nt.fileHeader.characteristics: %#04x\n\n",nt.fileHeader.characteristics));
509
510 // Check NT signature
511 if((nt.signature==IMAGE_NT_SIGNATURE) && !store.eof()){
512 FXushort optionalheadermagic;
513
514 // Start of optional header here
515 FXlong optbase=store.position();
516
517 // Read magic number
518 store >> optionalheadermagic;
519
520 // Check if its PE or PE+
521 if((optionalheadermagic==IMAGE_NT_OPTIONAL_HDR32_MAGIC || optionalheadermagic==IMAGE_NT_OPTIONAL_HDR64_MAGIC) && !store.eof()){
522 ImageSectionHeader sec;
523
524 // Skip over to section headers
525 store.position(optbase+nt.fileHeader.sizeOfOptionalHeader);
526
527 // Hunt for the .rsrc section now
528 for(FXint s=0; s<nt.fileHeader.numberOfSections; ++s){
529
530 // Load section header info
531 store.load(sec.name,sizeof(sec.name));
532 store >> sec.virtualSize;
533 store >> sec.virtualAddress;
534 store >> sec.sizeOfRawData;
535 store >> sec.pointerToRawData;
536 store >> sec.pointerToRelocations;
537 store >> sec.pointerToLinenumbers;
538 store >> sec.numberOfRelocations;
539 store >> sec.numberOfLinenumbers;
540 store >> sec.characteristics;
541
542 // Bail if at end
543 if(store.eof()) break;
544
545 FXTRACE((100,"sec%d.name: %.8s\n",s,sec.name));
546 FXTRACE((100,"sec%d.virtualSize: %u\n",s,sec.virtualSize));
547 FXTRACE((100,"sec%d.virtualAddress: %u\n",s,sec.virtualAddress));
548 FXTRACE((100,"sec%d.sizeOfRawData: %u\n",s,sec.sizeOfRawData));
549 FXTRACE((100,"sec%d.pointerToRawData: %u (%#08x)\n",s,sec.pointerToRawData,sec.pointerToRawData));
550 FXTRACE((100,"sec%d.pointerToRelocations: %u\n",s,sec.pointerToRelocations));
551 FXTRACE((100,"sec%d.pointerToLinenumbers: %u\n",s,sec.pointerToLinenumbers));
552 FXTRACE((100,"sec%d.numberOfRelocations: %u\n",s,sec.numberOfRelocations));
553 FXTRACE((100,"sec%d.numberOfLinenumbers: %u\n",s,sec.numberOfLinenumbers));
554 FXTRACE((100,"sec%d.characteristics: %#08x\n\n",s,sec.characteristics));
555
556 // Found the resource section in the pe file
557 if(compare(sec.name,".rsrc")==0){
558 Context context={sec.pointerToRawData,sec.virtualAddress,sec.sizeOfRawData,{type,id,-1}};
559
560 // Scan resources in resource section
561 result=scanresources(store,data,width,height,context,sec.pointerToRawData,0);
562 break;
563 }
564 }
565 }
566 }
567 }
568 store.swapBytes(swap);
569 }
570 return result;
571 }
572
573
574 }
575