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