1c2c66affSColin Finck //
2c2c66affSColin Finck // This program was written by Sang Cho, assistant professor at
3c2c66affSColin Finck //                                       the department of
4c2c66affSColin Finck //                                                                               computer science and engineering
5c2c66affSColin Finck //                                                                               chongju university
6c2c66affSColin Finck // this program is based on the program pefile.c
7c2c66affSColin Finck // which is written by Randy Kath(Microsoft Developmer Network Technology Group)
8c2c66affSColin Finck // in june 12, 1993.
9c2c66affSColin Finck // I have investigated P.E. file format as thoroughly as possible,
10c2c66affSColin Finck // but I cannot claim that I am an expert yet, so some of its information
11c2c66affSColin Finck // may give you wrong results.
12c2c66affSColin Finck //
13c2c66affSColin Finck //
14c2c66affSColin Finck //
15c2c66affSColin Finck // language used: djgpp
16c2c66affSColin Finck // date of creation: September 28, 1997
17c2c66affSColin Finck //
18c2c66affSColin Finck // date of first release: October 15, 1997
19c2c66affSColin Finck //
20c2c66affSColin Finck //
21c2c66affSColin Finck //      you can contact me: e-mail address: sangcho@alpha94.chongju.ac.kr
22c2c66affSColin Finck //                            hitel id: chokhas
23c2c66affSColin Finck //                        phone number: (0431) 229-8491    +82-431-229-8491
24c2c66affSColin Finck //
25c2c66affSColin Finck //
26c2c66affSColin Finck //
27c2c66affSColin Finck //   Copyright (C) 1997.                                 by Sang Cho.
28c2c66affSColin Finck //
29c2c66affSColin Finck //   Permission is granted to make and distribute verbatim copies of this
30c2c66affSColin Finck // program provided the copyright notice and this permission notice are
31c2c66affSColin Finck // preserved on all copies.
32c2c66affSColin Finck //
33c2c66affSColin Finck //
34c2c66affSColin Finck // File: pedump.c ( I included header file into source file. )
35c2c66affSColin Finck //
36c2c66affSColin Finck // LICENSE
37c2c66affSColin Finck //      Sources released under GNU General Public License version 2
38c2c66affSColin Finck //      or later by Mr. Sang Cho permission.
39c2c66affSColin Finck //
40c2c66affSColin Finck // REVISIONS
41c2c66affSColin Finck //      2000-04-23 (ea) Initial adaptation to GCC/MinGW/ROS.
42c2c66affSColin Finck //      2000-08-05 (ea) Initial raw adaptation done.
43c2c66affSColin Finck //
44c2c66affSColin Finck 
45c2c66affSColin Finck #include <stdio.h>
46c2c66affSColin Finck #include <stdlib.h>
47c2c66affSColin Finck #include <stdarg.h>
48c2c66affSColin Finck #include <string.h>
49c2c66affSColin Finck #include <setjmp.h>
50c2c66affSColin Finck #include <malloc.h>
51c2c66affSColin Finck #include <ctype.h>
52c2c66affSColin Finck 
53c2c66affSColin Finck #ifndef bcopy
54c2c66affSColin Finck #define bcopy(s,d,z) memcpy((d),(s),(z))
55c2c66affSColin Finck #endif
56c2c66affSColin Finck 
57c2c66affSColin Finck typedef char CHAR;
58c2c66affSColin Finck typedef short WCHAR;
59c2c66affSColin Finck typedef short SHORT;
60c2c66affSColin Finck typedef long LONG;
61c2c66affSColin Finck typedef unsigned short USHORT;
62c2c66affSColin Finck typedef unsigned long DWORD;
63c2c66affSColin Finck typedef int BOOL;
64c2c66affSColin Finck typedef unsigned char BYTE;
65c2c66affSColin Finck typedef unsigned short WORD;
66c2c66affSColin Finck typedef BYTE *PBYTE;
67c2c66affSColin Finck typedef WORD *PWORD;
68c2c66affSColin Finck typedef DWORD *PDWORD;
69c2c66affSColin Finck typedef void *LPVOID;
70c2c66affSColin Finck typedef int boolean;
71c2c66affSColin Finck 
72c2c66affSColin Finck #define VOID                void
73c2c66affSColin Finck #define BOOLEAN             boolean
74c2c66affSColin Finck 
75c2c66affSColin Finck #ifndef NULL
76c2c66affSColin Finck #define NULL                0
77c2c66affSColin Finck #endif
78c2c66affSColin Finck 
79c2c66affSColin Finck #define FALSE               0
80c2c66affSColin Finck #define TRUE                1
81c2c66affSColin Finck #define CONST               const
82c2c66affSColin Finck #define LOWORD(l)           ((WORD)(l))
83c2c66affSColin Finck #define WINAPI		__stdcall
84c2c66affSColin Finck 
85c2c66affSColin Finck //
86c2c66affSColin Finck // Image Format
87c2c66affSColin Finck //
88c2c66affSColin Finck 
89c2c66affSColin Finck #define IMAGE_DOS_SIGNATURE                 0x5A4D	// MZ
90c2c66affSColin Finck #define IMAGE_OS2_SIGNATURE                 0x454E	// NE
91c2c66affSColin Finck #define IMAGE_OS2_SIGNATURE_LE              0x454C	// LE
92c2c66affSColin Finck #define IMAGE_VXD_SIGNATURE                 0x454C	// LE
93c2c66affSColin Finck #define IMAGE_NT_SIGNATURE                  0x00004550	// PE00
94c2c66affSColin Finck 
95c2c66affSColin Finck typedef struct _IMAGE_DOS_HEADER
96c2c66affSColin Finck   {				// DOS .EXE header
97c2c66affSColin Finck 
98c2c66affSColin Finck     WORD e_magic;		// Magic number
99c2c66affSColin Finck 
100c2c66affSColin Finck     WORD e_cblp;		// Bytes on last page of file
101c2c66affSColin Finck 
102c2c66affSColin Finck     WORD e_cp;			// Pages in file
103c2c66affSColin Finck 
104c2c66affSColin Finck     WORD e_crlc;		// Relocations
105c2c66affSColin Finck 
106c2c66affSColin Finck     WORD e_cparhdr;		// Size of header in paragraphs
107c2c66affSColin Finck 
108c2c66affSColin Finck     WORD e_minalloc;		// Minimum extra paragraphs needed
109c2c66affSColin Finck 
110c2c66affSColin Finck     WORD e_maxalloc;		// Maximum extra paragraphs needed
111c2c66affSColin Finck 
112c2c66affSColin Finck     WORD e_ss;			// Initial (relative) SS value
113c2c66affSColin Finck 
114c2c66affSColin Finck     WORD e_sp;			// Initial SP value
115c2c66affSColin Finck 
116c2c66affSColin Finck     WORD e_csum;		// Checksum
117c2c66affSColin Finck 
118c2c66affSColin Finck     WORD e_ip;			// Initial IP value
119c2c66affSColin Finck 
120c2c66affSColin Finck     WORD e_cs;			// Initial (relative) CS value
121c2c66affSColin Finck 
122c2c66affSColin Finck     WORD e_lfarlc;		// File address of relocation table
123c2c66affSColin Finck 
124c2c66affSColin Finck     WORD e_ovno;		// Overlay number
125c2c66affSColin Finck 
126c2c66affSColin Finck     WORD e_res[4];		// Reserved words
127c2c66affSColin Finck 
128c2c66affSColin Finck     WORD e_oemid;		// OEM identifier (for e_oeminfo)
129c2c66affSColin Finck 
130c2c66affSColin Finck     WORD e_oeminfo;		// OEM information; e_oemid specific
131c2c66affSColin Finck 
132c2c66affSColin Finck     WORD e_res2[10];		// Reserved words
133c2c66affSColin Finck 
134c2c66affSColin Finck     LONG e_lfanew;		// File address of new exe header
135c2c66affSColin Finck 
136c2c66affSColin Finck   }
137c2c66affSColin Finck IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
138c2c66affSColin Finck 
139c2c66affSColin Finck //
140c2c66affSColin Finck // File header format.
141c2c66affSColin Finck //
142c2c66affSColin Finck 
143c2c66affSColin Finck 
144c2c66affSColin Finck 
145c2c66affSColin Finck typedef struct _IMAGE_FILE_HEADER
146c2c66affSColin Finck   {
147c2c66affSColin Finck     WORD Machine;
148c2c66affSColin Finck     WORD NumberOfSections;
149c2c66affSColin Finck     DWORD TimeDateStamp;
150c2c66affSColin Finck     DWORD PointerToSymbolTable;
151c2c66affSColin Finck     DWORD NumberOfSymbols;
152c2c66affSColin Finck     WORD SizeOfOptionalHeader;
153c2c66affSColin Finck     WORD Characteristics;
154c2c66affSColin Finck   }
155c2c66affSColin Finck IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
156c2c66affSColin Finck 
157c2c66affSColin Finck #define IMAGE_SIZEOF_FILE_HEADER             20
158c2c66affSColin Finck 
159c2c66affSColin Finck #define IMAGE_FILE_RELOCS_STRIPPED           0x0001	// Relocation info stripped from file.
160c2c66affSColin Finck #define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002	// File is executable  (i.e. no unresolved externel references).
161c2c66affSColin Finck #define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004	// Line nunbers stripped from file.
162c2c66affSColin Finck #define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008	// Local symbols stripped from file.
163c2c66affSColin Finck #define IMAGE_FILE_BYTES_REVERSED_LO         0x0080	// Bytes of machine word are reversed.
164c2c66affSColin Finck #define IMAGE_FILE_32BIT_MACHINE             0x0100	// 32 bit word machine.
165c2c66affSColin Finck #define IMAGE_FILE_DEBUG_STRIPPED            0x0200	// Debugging info stripped from file in .DBG file
166c2c66affSColin Finck #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400	// If Image is on removable media, copy and run from the swap file.
167c2c66affSColin Finck #define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800	// If Image is on Net, copy and run from the swap file.
168c2c66affSColin Finck #define IMAGE_FILE_SYSTEM                    0x1000	// System File.
169c2c66affSColin Finck #define IMAGE_FILE_DLL                       0x2000	// File is a DLL.
170c2c66affSColin Finck #define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000	// File should only be run on a UP machine
171c2c66affSColin Finck #define IMAGE_FILE_BYTES_REVERSED_HI         0x8000	// Bytes of machine word are reversed.
172c2c66affSColin Finck 
173c2c66affSColin Finck #define IMAGE_FILE_MACHINE_UNKNOWN           0
174c2c66affSColin Finck #define IMAGE_FILE_MACHINE_I386              0x14c	// Intel 386.
175c2c66affSColin Finck #define IMAGE_FILE_MACHINE_R3000             0x162	// MIPS little-endian, 0x160 big-endian
176c2c66affSColin Finck #define IMAGE_FILE_MACHINE_R4000             0x166	// MIPS little-endian
177c2c66affSColin Finck #define IMAGE_FILE_MACHINE_R10000            0x168	// MIPS little-endian
178c2c66affSColin Finck #define IMAGE_FILE_MACHINE_ALPHA             0x184	// Alpha_AXP
179c2c66affSColin Finck #define IMAGE_FILE_MACHINE_POWERPC           0x1F0	// IBM PowerPC Little-Endian
180c2c66affSColin Finck 
181c2c66affSColin Finck 
182c2c66affSColin Finck 
183c2c66affSColin Finck //
184c2c66affSColin Finck // Directory format.
185c2c66affSColin Finck //
186c2c66affSColin Finck 
187c2c66affSColin Finck typedef struct _IMAGE_DATA_DIRECTORY
188c2c66affSColin Finck   {
189c2c66affSColin Finck     DWORD VirtualAddress;
190c2c66affSColin Finck     DWORD Size;
191c2c66affSColin Finck 
192c2c66affSColin Finck   }
193c2c66affSColin Finck IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
194c2c66affSColin Finck 
195c2c66affSColin Finck #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16
196c2c66affSColin Finck 
197c2c66affSColin Finck //
198c2c66affSColin Finck // Optional header format.
199c2c66affSColin Finck //
200c2c66affSColin Finck 
201c2c66affSColin Finck typedef struct _IMAGE_OPTIONAL_HEADER
202c2c66affSColin Finck   {
203c2c66affSColin Finck     //
204c2c66affSColin Finck     // Standard fields.
205c2c66affSColin Finck     //
206c2c66affSColin Finck     WORD Magic;
207c2c66affSColin Finck     BYTE MajorLinkerVersion;
208c2c66affSColin Finck     BYTE MinorLinkerVersion;
209c2c66affSColin Finck     DWORD SizeOfCode;
210c2c66affSColin Finck     DWORD SizeOfInitializedData;
211c2c66affSColin Finck     DWORD SizeOfUninitializedData;
212c2c66affSColin Finck     DWORD AddressOfEntryPoint;
213c2c66affSColin Finck     DWORD BaseOfCode;
214c2c66affSColin Finck     DWORD BaseOfData;
215c2c66affSColin Finck 
216c2c66affSColin Finck     //
217c2c66affSColin Finck     // NT additional fields.
218c2c66affSColin Finck     //
219c2c66affSColin Finck 
220c2c66affSColin Finck     DWORD ImageBase;
221c2c66affSColin Finck     DWORD SectionAlignment;
222c2c66affSColin Finck     DWORD FileAlignment;
223c2c66affSColin Finck     WORD MajorOperatingSystemVersion;
224c2c66affSColin Finck     WORD MinorOperatingSystemVersion;
225c2c66affSColin Finck     WORD MajorImageVersion;
226c2c66affSColin Finck     WORD MinorImageVersion;
227c2c66affSColin Finck     WORD MajorSubsystemVersion;
228c2c66affSColin Finck     WORD MinorSubsystemVersion;
229c2c66affSColin Finck     DWORD Win32VersionValue;
230c2c66affSColin Finck     DWORD SizeOfImage;
231c2c66affSColin Finck     DWORD SizeOfHeaders;
232c2c66affSColin Finck     DWORD CheckSum;
233c2c66affSColin Finck     WORD Subsystem;
234c2c66affSColin Finck     WORD DllCharacteristics;
235c2c66affSColin Finck     DWORD SizeOfStackReserve;
236c2c66affSColin Finck     DWORD SizeOfStackCommit;
237c2c66affSColin Finck     DWORD SizeOfHeapReserve;
238c2c66affSColin Finck     DWORD SizeOfHeapCommit;
239c2c66affSColin Finck     DWORD LoaderFlags;
240c2c66affSColin Finck     DWORD NumberOfRvaAndSizes;
241c2c66affSColin Finck     IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
242c2c66affSColin Finck 
243c2c66affSColin Finck   }
244c2c66affSColin Finck IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
245c2c66affSColin Finck 
246c2c66affSColin Finck 
247c2c66affSColin Finck typedef struct _IMAGE_NT_HEADERS
248c2c66affSColin Finck   {
249c2c66affSColin Finck     DWORD Signature;
250c2c66affSColin Finck     IMAGE_FILE_HEADER FileHeader;
251c2c66affSColin Finck     IMAGE_OPTIONAL_HEADER OptionalHeader;
252c2c66affSColin Finck 
253c2c66affSColin Finck   }
254c2c66affSColin Finck IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
255c2c66affSColin Finck 
256c2c66affSColin Finck 
257c2c66affSColin Finck // Directory Entries
258c2c66affSColin Finck 
259c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_EXPORT         0	// Export Directory
260c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_IMPORT         1	// Import Directory
261c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_RESOURCE       2	// Resource Directory
262c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_EXCEPTION      3	// Exception Directory
263c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_SECURITY       4	// Security Directory
264c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_BASERELOC      5	// Base Relocation Table
265c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_DEBUG          6	// Debug Directory
266c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT      7	// Description String
267c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR      8	// Machine Value (MIPS GP)
268c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_TLS            9	// TLS Directory
269c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG   10	// Load Configuration Directory
270c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT  11	// Bound Import Directory in headers
271c2c66affSColin Finck #define IMAGE_DIRECTORY_ENTRY_IAT           12	// Import Address Table
272c2c66affSColin Finck 
273c2c66affSColin Finck //
274c2c66affSColin Finck // Section header format.
275c2c66affSColin Finck //
276c2c66affSColin Finck 
277c2c66affSColin Finck #define IMAGE_SIZEOF_SHORT_NAME              8
278c2c66affSColin Finck 
279c2c66affSColin Finck typedef struct _IMAGE_SECTION_HEADER
280c2c66affSColin Finck   {
281c2c66affSColin Finck     BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
282c2c66affSColin Finck     union
283c2c66affSColin Finck       {
284c2c66affSColin Finck 	DWORD PhysicalAddress;
285c2c66affSColin Finck 	DWORD VirtualSize;
286c2c66affSColin Finck       }
287c2c66affSColin Finck     Misc;
288c2c66affSColin Finck     DWORD VirtualAddress;
289c2c66affSColin Finck     DWORD SizeOfRawData;
290c2c66affSColin Finck     DWORD PointerToRawData;
291c2c66affSColin Finck     DWORD PointerToRelocations;
292c2c66affSColin Finck     DWORD PointerToLinenumbers;
293c2c66affSColin Finck     WORD NumberOfRelocations;
294c2c66affSColin Finck     WORD NumberOfLinenumbers;
295c2c66affSColin Finck     DWORD Characteristics;
296c2c66affSColin Finck 
297c2c66affSColin Finck   }
298c2c66affSColin Finck IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
299c2c66affSColin Finck 
300c2c66affSColin Finck #define IMAGE_SIZEOF_SECTION_HEADER          40
301c2c66affSColin Finck 
302c2c66affSColin Finck 
303c2c66affSColin Finck //
304c2c66affSColin Finck // Export Format
305c2c66affSColin Finck //
306c2c66affSColin Finck 
307c2c66affSColin Finck typedef struct _IMAGE_EXPORT_DIRECTORY
308c2c66affSColin Finck   {
309c2c66affSColin Finck     DWORD Characteristics;
310c2c66affSColin Finck     DWORD TimeDateStamp;
311c2c66affSColin Finck     WORD MajorVersion;
312c2c66affSColin Finck     WORD MinorVersion;
313c2c66affSColin Finck     DWORD Name;
314c2c66affSColin Finck     DWORD Base;
315c2c66affSColin Finck     DWORD NumberOfFunctions;
316c2c66affSColin Finck     DWORD NumberOfNames;
317c2c66affSColin Finck     PDWORD *AddressOfFunctions;
318c2c66affSColin Finck     PDWORD *AddressOfNames;
319c2c66affSColin Finck     PWORD *AddressOfNameOrdinals;
320c2c66affSColin Finck 
321c2c66affSColin Finck   }
322c2c66affSColin Finck IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
323c2c66affSColin Finck 
324c2c66affSColin Finck //
325c2c66affSColin Finck // Import Format
326c2c66affSColin Finck //
327c2c66affSColin Finck 
328c2c66affSColin Finck typedef struct _IMAGE_IMPORT_BY_NAME
329c2c66affSColin Finck   {
330c2c66affSColin Finck     WORD Hint;
331c2c66affSColin Finck     BYTE Name[1];
332c2c66affSColin Finck 
333c2c66affSColin Finck   }
334c2c66affSColin Finck IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
335c2c66affSColin Finck 
336c2c66affSColin Finck #define IMAGE_ORDINAL_FLAG 0x80000000
337c2c66affSColin Finck #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
338c2c66affSColin Finck 
339c2c66affSColin Finck 
340c2c66affSColin Finck //
341c2c66affSColin Finck // Resource Format.
342c2c66affSColin Finck //
343c2c66affSColin Finck 
344c2c66affSColin Finck //
345c2c66affSColin Finck // Resource directory consists of two counts, following by a variable length
346c2c66affSColin Finck // array of directory entries.  The first count is the number of entries at
347c2c66affSColin Finck // beginning of the array that have actual names associated with each entry.
348c2c66affSColin Finck // The entries are in ascending order, case insensitive strings.  The second
349c2c66affSColin Finck // count is the number of entries that immediately follow the named entries.
350c2c66affSColin Finck // This second count identifies the number of entries that have 16-bit integer
351c2c66affSColin Finck // Ids as their name.  These entries are also sorted in ascending order.
352c2c66affSColin Finck //
353c2c66affSColin Finck // This structure allows fast lookup by either name or number, but for any
354c2c66affSColin Finck // given resource entry only one form of lookup is supported, not both.
355c2c66affSColin Finck // This is consistant with the syntax of the .RC file and the .RES file.
356c2c66affSColin Finck //
357c2c66affSColin Finck 
358c2c66affSColin Finck // Predefined resource types ... there may be some more, but I don't have
359c2c66affSColin Finck //                               the information yet.  .....sang cho.....
360c2c66affSColin Finck 
361c2c66affSColin Finck #define    RT_NEWRESOURCE   0x2000
362c2c66affSColin Finck #define    RT_ERROR         0x7fff
363c2c66affSColin Finck #define    RT_CURSOR        1
364c2c66affSColin Finck #define    RT_BITMAP        2
365c2c66affSColin Finck #define    RT_ICON          3
366c2c66affSColin Finck #define    RT_MENU          4
367c2c66affSColin Finck #define    RT_DIALOG        5
368c2c66affSColin Finck #define    RT_STRING        6
369c2c66affSColin Finck #define    RT_FONTDIR       7
370c2c66affSColin Finck #define    RT_FONT          8
371c2c66affSColin Finck #define    RT_ACCELERATORS  9
372c2c66affSColin Finck #define    RT_RCDATA        10
373c2c66affSColin Finck #define    RT_MESSAGETABLE  11
374c2c66affSColin Finck #define    RT_GROUP_CURSOR  12
375c2c66affSColin Finck #define    RT_GROUP_ICON    14
376c2c66affSColin Finck #define    RT_VERSION       16
377c2c66affSColin Finck #define    NEWBITMAP        (RT_BITMAP|RT_NEWRESOURCE)
378c2c66affSColin Finck #define    NEWMENU          (RT_MENU|RT_NEWRESOURCE)
379c2c66affSColin Finck #define    NEWDIALOG        (RT_DIALOG|RT_NEWRESOURCE)
380c2c66affSColin Finck 
381c2c66affSColin Finck 
382c2c66affSColin Finck typedef struct _IMAGE_RESOURCE_DIRECTORY
383c2c66affSColin Finck   {
384c2c66affSColin Finck     DWORD Characteristics;
385c2c66affSColin Finck     DWORD TimeDateStamp;
386c2c66affSColin Finck     WORD MajorVersion;
387c2c66affSColin Finck     WORD MinorVersion;
388c2c66affSColin Finck     WORD NumberOfNamedEntries;
389c2c66affSColin Finck     WORD NumberOfIdEntries;
390c2c66affSColin Finck //      IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[1];
391c2c66affSColin Finck 
392c2c66affSColin Finck   }
393c2c66affSColin Finck IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
394c2c66affSColin Finck 
395c2c66affSColin Finck #define IMAGE_RESOURCE_NAME_IS_STRING        0x80000000
396c2c66affSColin Finck #define IMAGE_RESOURCE_DATA_IS_DIRECTORY     0x80000000
397c2c66affSColin Finck 
398c2c66affSColin Finck //
399c2c66affSColin Finck // Each directory contains the 32-bit Name of the entry and an offset,
400c2c66affSColin Finck // relative to the beginning of the resource directory of the data associated
401c2c66affSColin Finck // with this directory entry.  If the name of the entry is an actual text
402c2c66affSColin Finck // string instead of an integer Id, then the high order bit of the name field
403c2c66affSColin Finck // is set to one and the low order 31-bits are an offset, relative to the
404c2c66affSColin Finck // beginning of the resource directory of the string, which is of type
405c2c66affSColin Finck // IMAGE_RESOURCE_DIRECTORY_STRING.  Otherwise the high bit is clear and the
406c2c66affSColin Finck // low-order 16-bits are the integer Id that identify this resource directory
407c2c66affSColin Finck // entry. If the directory entry is yet another resource directory (i.e. a
408c2c66affSColin Finck // subdirectory), then the high order bit of the offset field will be
409c2c66affSColin Finck // set to indicate this.  Otherwise the high bit is clear and the offset
410c2c66affSColin Finck // field points to a resource data entry.
411c2c66affSColin Finck //
412c2c66affSColin Finck 
413c2c66affSColin Finck typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
414c2c66affSColin Finck   {
415c2c66affSColin Finck     DWORD Name;
416c2c66affSColin Finck     DWORD OffsetToData;
417c2c66affSColin Finck 
418c2c66affSColin Finck   }
419c2c66affSColin Finck IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
420c2c66affSColin Finck 
421c2c66affSColin Finck //
422c2c66affSColin Finck // For resource directory entries that have actual string names, the Name
423c2c66affSColin Finck // field of the directory entry points to an object of the following type.
424c2c66affSColin Finck // All of these string objects are stored together after the last resource
425c2c66affSColin Finck // directory entry and before the first resource data object.  This minimizes
426c2c66affSColin Finck // the impact of these variable length objects on the alignment of the fixed
427c2c66affSColin Finck // size directory entry objects.
428c2c66affSColin Finck //
429c2c66affSColin Finck 
430c2c66affSColin Finck typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING
431c2c66affSColin Finck   {
432c2c66affSColin Finck     WORD Length;
433c2c66affSColin Finck     CHAR NameString[1];
434c2c66affSColin Finck 
435c2c66affSColin Finck   }
436c2c66affSColin Finck IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;
437c2c66affSColin Finck 
438c2c66affSColin Finck 
439c2c66affSColin Finck typedef struct _IMAGE_RESOURCE_DIR_STRING_U
440c2c66affSColin Finck   {
441c2c66affSColin Finck     WORD Length;
442c2c66affSColin Finck     WCHAR NameString[1];
443c2c66affSColin Finck 
444c2c66affSColin Finck   }
445c2c66affSColin Finck IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
446c2c66affSColin Finck 
447c2c66affSColin Finck 
448c2c66affSColin Finck //
449c2c66affSColin Finck // Each resource data entry describes a leaf node in the resource directory
450c2c66affSColin Finck // tree.  It contains an offset, relative to the beginning of the resource
451c2c66affSColin Finck // directory of the data for the resource, a size field that gives the number
452c2c66affSColin Finck // of bytes of data at that offset, a CodePage that should be used when
453c2c66affSColin Finck // decoding code point values within the resource data.  Typically for new
454c2c66affSColin Finck // applications the code page would be the unicode code page.
455c2c66affSColin Finck //
456c2c66affSColin Finck 
457c2c66affSColin Finck typedef struct _IMAGE_RESOURCE_DATA_ENTRY
458c2c66affSColin Finck   {
459c2c66affSColin Finck     DWORD OffsetToData;
460c2c66affSColin Finck     DWORD Size;
461c2c66affSColin Finck     DWORD CodePage;
462c2c66affSColin Finck     DWORD Reserved;
463c2c66affSColin Finck 
464c2c66affSColin Finck   }
465c2c66affSColin Finck IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
466c2c66affSColin Finck 
467c2c66affSColin Finck 
468c2c66affSColin Finck //  Menu Resources       ... added by .....sang cho....
469c2c66affSColin Finck 
470c2c66affSColin Finck // Menu resources are composed of a menu header followed by a sequential list
471c2c66affSColin Finck // of menu items. There are two types of menu items: pop-ups and normal menu
472c2c66affSColin Finck // itmes. The MENUITEM SEPARATOR is a special case of a normal menu item with
473c2c66affSColin Finck // an empty name, zero ID, and zero flags.
474c2c66affSColin Finck 
475c2c66affSColin Finck typedef struct _IMAGE_MENU_HEADER
476c2c66affSColin Finck   {
477c2c66affSColin Finck     WORD wVersion;		// Currently zero
478c2c66affSColin Finck 
479c2c66affSColin Finck     WORD cbHeaderSize;		// Also zero
480c2c66affSColin Finck 
481c2c66affSColin Finck   }
482c2c66affSColin Finck IMAGE_MENU_HEADER, *PIMAGE_MENU_HEADER;
483c2c66affSColin Finck 
484c2c66affSColin Finck typedef struct _IMAGE_POPUP_MENU_ITEM
485c2c66affSColin Finck   {
486c2c66affSColin Finck     WORD fItemFlags;
487c2c66affSColin Finck     WCHAR szItemText[1];
488c2c66affSColin Finck 
489c2c66affSColin Finck   }
490c2c66affSColin Finck IMAGE_POPUP_MENU_ITEM, *PIMAGE_POPUP_MENU_ITEM;
491c2c66affSColin Finck 
492c2c66affSColin Finck typedef struct _IMAGE_NORMAL_MENU_ITEM
493c2c66affSColin Finck   {
494c2c66affSColin Finck     WORD fItemFlags;
495c2c66affSColin Finck     WORD wMenuID;
496c2c66affSColin Finck     WCHAR szItemText[1];
497c2c66affSColin Finck 
498c2c66affSColin Finck   }
499c2c66affSColin Finck IMAGE_NORMAL_MENU_ITEM, *PIMAGE_NORMAL_MENU_ITEM;
500c2c66affSColin Finck 
501c2c66affSColin Finck #define GRAYED       0x0001	// GRAYED keyword
502c2c66affSColin Finck #define INACTIVE     0x0002	// INACTIVE keyword
503c2c66affSColin Finck #define BITMAP       0x0004	// BITMAP keyword
504c2c66affSColin Finck #define OWNERDRAW    0x0100	// OWNERDRAW keyword
505c2c66affSColin Finck #define CHECKED      0x0008	// CHECKED keyword
506c2c66affSColin Finck #define POPUP        0x0010	// used internally
507c2c66affSColin Finck #define MENUBARBREAK 0x0020	// MENUBARBREAK keyword
508c2c66affSColin Finck #define MENUBREAK    0x0040	// MENUBREAK keyword
509c2c66affSColin Finck #define ENDMENU      0x0080	// used internally
510c2c66affSColin Finck 
511c2c66affSColin Finck 
512c2c66affSColin Finck // Dialog Box Resources .................. added by sang cho.
513c2c66affSColin Finck 
514c2c66affSColin Finck // A dialog box is contained in a single resource and has a header and
515c2c66affSColin Finck // a portion repeated for each control in the dialog box.
516c2c66affSColin Finck // The item DWORD IStyle is a standard window style composed of flags found
517c2c66affSColin Finck // in WINDOWS.H.
518c2c66affSColin Finck // The default style for a dialog box is:
519c2c66affSColin Finck // WS_POPUP | WS_BORDER | WS_SYSMENU
520c2c66affSColin Finck //
521c2c66affSColin Finck // The itme marked "Name or Ordinal" are :
522c2c66affSColin Finck // If the first word is an 0xffff, the next two bytes contain an ordinal ID.
523c2c66affSColin Finck // Otherwise, the first one or more WORDS contain a double-null-terminated string.
524c2c66affSColin Finck // An empty string is represented by a single WORD zero in the first location.
525c2c66affSColin Finck //
526c2c66affSColin Finck // The WORD wPointSize and WCHAR szFontName entries are present if the FONT
527c2c66affSColin Finck // statement was included for the dialog box. This can be detected by checking
528c2c66affSColin Finck // the entry IStyle. If IStyle & DS_SETFONT ( which is 0x40), then these
529c2c66affSColin Finck // entries will be present.
530c2c66affSColin Finck 
531c2c66affSColin Finck typedef struct _IMAGE_DIALOG_BOX_HEADER1
532c2c66affSColin Finck   {
533c2c66affSColin Finck     DWORD IStyle;
534c2c66affSColin Finck     DWORD IExtendedStyle;	// New for Windows NT
535c2c66affSColin Finck 
536c2c66affSColin Finck     WORD nControls;		// Number of Controls
537c2c66affSColin Finck 
538c2c66affSColin Finck     WORD x;
539c2c66affSColin Finck     WORD y;
540c2c66affSColin Finck     WORD cx;
541c2c66affSColin Finck     WORD cy;
542c2c66affSColin Finck //      N_OR_O MenuName;         // Name or Ordinal ID
543c2c66affSColin Finck     //      N_OR_O ClassName;                // Name or Ordinal ID
544c2c66affSColin Finck     //      WCHAR  szCaption[];
545c2c66affSColin Finck     //      WORD   wPointSize;       // Only here if FONT set for dialog
546c2c66affSColin Finck     //      WCHAR  szFontName[];     // This too
547c2c66affSColin Finck   }
548c2c66affSColin Finck IMAGE_DIALOG_HEADER, *PIMAGE_DIALOG_HEADER;
549c2c66affSColin Finck 
550c2c66affSColin Finck typedef union _NAME_OR_ORDINAL
551c2c66affSColin Finck   {				// Name or Ordinal ID
552c2c66affSColin Finck 
553c2c66affSColin Finck     struct _ORD_ID
554c2c66affSColin Finck       {
555c2c66affSColin Finck 	WORD flgId;
556c2c66affSColin Finck 	WORD Id;
557c2c66affSColin Finck       }
558c2c66affSColin Finck     ORD_ID;
559c2c66affSColin Finck     WCHAR szName[1];
560c2c66affSColin Finck   }
561c2c66affSColin Finck NAME_OR_ORDINAL, *PNAME_OR_ORDINAL;
562c2c66affSColin Finck 
563c2c66affSColin Finck // The data for each control starts on a DWORD boundary (which may require
564c2c66affSColin Finck // some padding from the previous control), and its format is as follows:
565c2c66affSColin Finck 
566c2c66affSColin Finck typedef struct _IMAGE_CONTROL_DATA
567c2c66affSColin Finck   {
568c2c66affSColin Finck     DWORD IStyle;
569c2c66affSColin Finck     DWORD IExtendedStyle;
570c2c66affSColin Finck     WORD x;
571c2c66affSColin Finck     WORD y;
572c2c66affSColin Finck     WORD cx;
573c2c66affSColin Finck     WORD cy;
574c2c66affSColin Finck     WORD wId;
575c2c66affSColin Finck //  N_OR_O  ClassId;
576c2c66affSColin Finck     //  N_OR_O  Text;
577c2c66affSColin Finck     //  WORD    nExtraStuff;
578c2c66affSColin Finck   }
579c2c66affSColin Finck IMAGE_CONTROL_DATA, *PIMAGE_CONTROL_DATA;
580c2c66affSColin Finck 
581c2c66affSColin Finck #define BUTTON       0x80
582c2c66affSColin Finck #define EDIT         0x81
583c2c66affSColin Finck #define STATIC       0x82
584c2c66affSColin Finck #define LISTBOX      0x83
585c2c66affSColin Finck #define SCROLLBAR    0x84
586c2c66affSColin Finck #define COMBOBOX     0x85
587c2c66affSColin Finck 
588c2c66affSColin Finck // The various statements used in a dialog script are all mapped to these
589c2c66affSColin Finck // classes along with certain modifying styles. The values for these styles
590c2c66affSColin Finck // can be found in WINDOWS.H. All dialog controls have the default styles
591c2c66affSColin Finck // of WS_CHILD and WS_VISIBLE. A list of the default styles used follows:
592c2c66affSColin Finck //
593c2c66affSColin Finck // Statement           Default Class         Default Styles
594c2c66affSColin Finck // CONTROL             None                  WS_CHILD|WS_VISIBLE
595c2c66affSColin Finck // LTEXT               STATIC                ES_LEFT
596c2c66affSColin Finck // RTEXT               STATIC                ES_RIGHT
597c2c66affSColin Finck // CTEXT               STATIC                ES_CENTER
598c2c66affSColin Finck // LISTBOX             LISTBOX               WS_BORDER|LBS_NOTIFY
599c2c66affSColin Finck // CHECKBOX            BUTTON                BS_CHECKBOX|WS_TABSTOP
600c2c66affSColin Finck // PUSHBUTTON          BUTTON                BS_PUSHBUTTON|WS_TABSTOP
601c2c66affSColin Finck // GROUPBOX            BUTTON                BS_GROUPBOX
602c2c66affSColin Finck // DEFPUSHBUTTON       BUTTON                BS_DFPUSHBUTTON|WS_TABSTOP
603c2c66affSColin Finck // RADIOBUTTON         BUTTON                BS_RADIOBUTTON
604c2c66affSColin Finck // AUTOCHECKBOX        BUTTON                BS_AUTOCHECKBOX
605c2c66affSColin Finck // AUTO3STATE          BUTTON                BS_AUTO3STATE
606c2c66affSColin Finck // AUTORADIOBUTTON     BUTTON                BS_AUTORADIOBUTTON
607c2c66affSColin Finck // PUSHBOX             BUTTON                BS_PUSHBOX
608c2c66affSColin Finck // STATE3              BUTTON                BS_3STATE
609c2c66affSColin Finck // EDITTEXT            EDIT                  ES_LEFT|WS_BORDER|WS_TABSTOP
610c2c66affSColin Finck // COMBOBOX            COMBOBOX              None
611c2c66affSColin Finck // ICON                STATIC                SS_ICON
612c2c66affSColin Finck // SCROLLBAR           SCROLLBAR             None
613c2c66affSColin Finck ///
614c2c66affSColin Finck 
615c2c66affSColin Finck #define WS_OVERLAPPED   0x00000000L
616c2c66affSColin Finck #define WS_POPUP        0x80000000L
617c2c66affSColin Finck #define WS_CHILD        0x40000000L
618c2c66affSColin Finck #define WS_CLIPSIBLINGS 0x04000000L
619c2c66affSColin Finck #define WS_CLIPCHILDREN 0x02000000L
620c2c66affSColin Finck #define WS_VISIBLE      0x10000000L
621c2c66affSColin Finck #define WS_DISABLED     0x08000000L
622c2c66affSColin Finck #define WS_MINIMIZE     0x20000000L
623c2c66affSColin Finck #define WS_MAXIMIZE     0x01000000L
624c2c66affSColin Finck #define WS_CAPTION      0x00C00000L
625c2c66affSColin Finck #define WS_BORDER       0x00800000L
626c2c66affSColin Finck #define WS_DLGFRAME     0x00400000L
627c2c66affSColin Finck #define WS_VSCROLL      0x00200000L
628c2c66affSColin Finck #define WS_HSCROLL      0x00100000L
629c2c66affSColin Finck #define WS_SYSMENU      0x00080000L
630c2c66affSColin Finck #define WS_THICKFRAME   0x00040000L
631c2c66affSColin Finck #define WS_MINIMIZEBOX  0x00020000L
632c2c66affSColin Finck #define WS_MAXIMIZEBOX  0x00010000L
633c2c66affSColin Finck #define WS_GROUP        0x00020000L
634c2c66affSColin Finck #define WS_TABSTOP      0x00010000L
635c2c66affSColin Finck 
636c2c66affSColin Finck // other aliases
637c2c66affSColin Finck #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
638c2c66affSColin Finck #define WS_POPUPWINDOW  (WS_POPUP | WS_BORDER | WS_SYSMENU)
639c2c66affSColin Finck #define WS_CHILDWINDOW  (WS_CHILD)
640c2c66affSColin Finck #define WS_TILED        WS_OVERLAPPED
641c2c66affSColin Finck #define WS_ICONIC       WS_MINIMIZE
642c2c66affSColin Finck #define WS_SIZEBOX      WS_THICKFRAME
643c2c66affSColin Finck #define WS_TILEDWINDOW  WS_OVERLAPPEDWINDOW
644c2c66affSColin Finck 
645c2c66affSColin Finck #define WS_EX_DLGMODALFRAME     0x00000001L
646c2c66affSColin Finck #define WS_EX_NOPARENTNOTIFY    0x00000004L
647c2c66affSColin Finck #define WS_EX_TOPMOST           0x00000008L
648c2c66affSColin Finck #define WS_EX_ACCEPTFILES       0x00000010L
649c2c66affSColin Finck #define WS_EX_TRANSPARENT       0x00000020L
650c2c66affSColin Finck 
651c2c66affSColin Finck #define BS_PUSHBUTTON           0x00000000L
652c2c66affSColin Finck #define BS_DEFPUSHBUTTON        0x00000001L
653c2c66affSColin Finck #define BS_CHECKBOX             0x00000002L
654c2c66affSColin Finck #define BS_AUTOCHECKBOX         0x00000003L
655c2c66affSColin Finck #define BS_RADIOBUTTON          0x00000004L
656c2c66affSColin Finck #define BS_3STATE               0x00000005L
657c2c66affSColin Finck #define BS_AUTO3STATE           0x00000006L
658c2c66affSColin Finck #define BS_GROUPBOX             0x00000007L
659c2c66affSColin Finck #define BS_USERBUTTON           0x00000008L
660c2c66affSColin Finck #define BS_AUTORADIOBUTTON      0x00000009L
661c2c66affSColin Finck #define BS_OWNERDRAW            0x0000000BL
662c2c66affSColin Finck #define BS_LEFTTEXT             0x00000020L
663c2c66affSColin Finck 
664c2c66affSColin Finck #define ES_LEFT         0x00000000L
665c2c66affSColin Finck #define ES_CENTER       0x00000001L
666c2c66affSColin Finck #define ES_RIGHT        0x00000002L
667c2c66affSColin Finck #define ES_MULTILINE    0x00000004L
668c2c66affSColin Finck #define ES_UPPERCASE    0x00000008L
669c2c66affSColin Finck #define ES_LOWERCASE    0x00000010L
670c2c66affSColin Finck #define ES_PASSWORD     0x00000020L
671c2c66affSColin Finck #define ES_AUTOVSCROLL  0x00000040L
672c2c66affSColin Finck #define ES_AUTOHSCROLL  0x00000080L
673c2c66affSColin Finck #define ES_NOHIDESEL    0x00000100L
674c2c66affSColin Finck #define ES_OEMCONVERT   0x00000400L
675c2c66affSColin Finck #define ES_READONLY     0x00000800L
676c2c66affSColin Finck #define ES_WANTRETURN   0x00001000L
677c2c66affSColin Finck 
678c2c66affSColin Finck #define LBS_NOTIFY            0x0001L
679c2c66affSColin Finck #define LBS_SORT              0x0002L
680c2c66affSColin Finck #define LBS_NOREDRAW          0x0004L
681c2c66affSColin Finck #define LBS_MULTIPLESEL       0x0008L
682c2c66affSColin Finck #define LBS_OWNERDRAWFIXED    0x0010L
683c2c66affSColin Finck #define LBS_OWNERDRAWVARIABLE 0x0020L
684c2c66affSColin Finck #define LBS_HASSTRINGS        0x0040L
685c2c66affSColin Finck #define LBS_USETABSTOPS       0x0080L
686c2c66affSColin Finck #define LBS_NOINTEGRALHEIGHT  0x0100L
687c2c66affSColin Finck #define LBS_MULTICOLUMN       0x0200L
688c2c66affSColin Finck #define LBS_WANTKEYBOARDINPUT 0x0400L
689c2c66affSColin Finck #define LBS_EXTENDEDSEL       0x0800L
690c2c66affSColin Finck #define LBS_DISABLENOSCROLL   0x1000L
691c2c66affSColin Finck 
692c2c66affSColin Finck #define SS_LEFT             0x00000000L
693c2c66affSColin Finck #define SS_CENTER           0x00000001L
694c2c66affSColin Finck #define SS_RIGHT            0x00000002L
695c2c66affSColin Finck #define SS_ICON             0x00000003L
696c2c66affSColin Finck #define SS_BLACKRECT        0x00000004L
697c2c66affSColin Finck #define SS_GRAYRECT         0x00000005L
698c2c66affSColin Finck #define SS_WHITERECT        0x00000006L
699c2c66affSColin Finck #define SS_BLACKFRAME       0x00000007L
700c2c66affSColin Finck #define SS_GRAYFRAME        0x00000008L
701c2c66affSColin Finck #define SS_WHITEFRAME       0x00000009L
702c2c66affSColin Finck #define SS_SIMPLE           0x0000000BL
703c2c66affSColin Finck #define SS_LEFTNOWORDWRAP   0x0000000CL
704c2c66affSColin Finck #define SS_BITMAP           0x0000000EL
705c2c66affSColin Finck 
706c2c66affSColin Finck //
707c2c66affSColin Finck // Debug Format
708c2c66affSColin Finck //
709c2c66affSColin Finck 
710c2c66affSColin Finck typedef struct _IMAGE_DEBUG_DIRECTORY
711c2c66affSColin Finck   {
712c2c66affSColin Finck     DWORD Characteristics;
713c2c66affSColin Finck     DWORD TimeDateStamp;
714c2c66affSColin Finck     WORD MajorVersion;
715c2c66affSColin Finck     WORD MinorVersion;
716c2c66affSColin Finck     DWORD Type;
717c2c66affSColin Finck     DWORD SizeOfData;
718c2c66affSColin Finck     DWORD AddressOfRawData;
719c2c66affSColin Finck     DWORD PointerToRawData;
720c2c66affSColin Finck   }
721c2c66affSColin Finck IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
722c2c66affSColin Finck 
723c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_UNKNOWN          0
724c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_COFF             1
725c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_CODEVIEW         2
726c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_FPO              3
727c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_MISC             4
728c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_EXCEPTION        5
729c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_FIXUP            6
730c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_OMAP_TO_SRC      7
731c2c66affSColin Finck #define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC    8
732c2c66affSColin Finck 
733c2c66affSColin Finck 
734c2c66affSColin Finck typedef struct _IMAGE_DEBUG_MISC
735c2c66affSColin Finck   {
736c2c66affSColin Finck     DWORD DataType;		// type of misc data, see defines
737c2c66affSColin Finck 
738c2c66affSColin Finck     DWORD Length;		// total length of record, rounded to four
739c2c66affSColin Finck     // byte multiple.
740c2c66affSColin Finck 
741c2c66affSColin Finck     BOOLEAN Unicode;		// TRUE if data is unicode string
742c2c66affSColin Finck 
743c2c66affSColin Finck     BYTE Reserved[3];
744c2c66affSColin Finck     BYTE Data[1];		// Actual data
745c2c66affSColin Finck 
746c2c66affSColin Finck   }
747c2c66affSColin Finck IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC;
748c2c66affSColin Finck 
749c2c66affSColin Finck 
750c2c66affSColin Finck //
751c2c66affSColin Finck // Debugging information can be stripped from an image file and placed
752c2c66affSColin Finck // in a separate .DBG file, whose file name part is the same as the
753c2c66affSColin Finck // image file name part (e.g. symbols for CMD.EXE could be stripped
754c2c66affSColin Finck // and placed in CMD.DBG).  This is indicated by the IMAGE_FILE_DEBUG_STRIPPED
755c2c66affSColin Finck // flag in the Characteristics field of the file header.  The beginning of
756c2c66affSColin Finck // the .DBG file contains the following structure which captures certain
757c2c66affSColin Finck // information from the image file.  This allows a debug to proceed even if
758c2c66affSColin Finck // the original image file is not accessable.  This header is followed by
759c2c66affSColin Finck // zero of more IMAGE_SECTION_HEADER structures, followed by zero or more
760c2c66affSColin Finck // IMAGE_DEBUG_DIRECTORY structures.  The latter structures and those in
761c2c66affSColin Finck // the image file contain file offsets relative to the beginning of the
762c2c66affSColin Finck // .DBG file.
763c2c66affSColin Finck //
764c2c66affSColin Finck // If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure
765c2c66affSColin Finck // is left in the image file, but not mapped.  This allows a debugger to
766c2c66affSColin Finck // compute the name of the .DBG file, from the name of the image in the
767c2c66affSColin Finck // IMAGE_DEBUG_MISC structure.
768c2c66affSColin Finck //
769c2c66affSColin Finck 
770c2c66affSColin Finck typedef struct _IMAGE_SEPARATE_DEBUG_HEADER
771c2c66affSColin Finck   {
772c2c66affSColin Finck     WORD Signature;
773c2c66affSColin Finck     WORD Flags;
774c2c66affSColin Finck     WORD Machine;
775c2c66affSColin Finck     WORD Characteristics;
776c2c66affSColin Finck     DWORD TimeDateStamp;
777c2c66affSColin Finck     DWORD CheckSum;
778c2c66affSColin Finck     DWORD ImageBase;
779c2c66affSColin Finck     DWORD SizeOfImage;
780c2c66affSColin Finck     DWORD NumberOfSections;
781c2c66affSColin Finck     DWORD ExportedNamesSize;
782c2c66affSColin Finck     DWORD DebugDirectorySize;
783c2c66affSColin Finck     DWORD SectionAlignment;
784c2c66affSColin Finck     DWORD Reserved[2];
785c2c66affSColin Finck   }
786c2c66affSColin Finck IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER;
787c2c66affSColin Finck 
788c2c66affSColin Finck #define IMAGE_SEPARATE_DEBUG_SIGNATURE  0x4944
789c2c66affSColin Finck 
790c2c66affSColin Finck #define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000
791c2c66affSColin Finck #define IMAGE_SEPARATE_DEBUG_MISMATCH   0x8000	// when DBG was updated, the
792c2c66affSColin Finck 						// old checksum didn't match.
793c2c66affSColin Finck 
794c2c66affSColin Finck 
795c2c66affSColin Finck //
796c2c66affSColin Finck // End Image Format
797c2c66affSColin Finck //
798c2c66affSColin Finck 
799c2c66affSColin Finck 
800c2c66affSColin Finck #define SIZE_OF_NT_SIGNATURE	sizeof (DWORD)
801c2c66affSColin Finck #define MAXRESOURCENAME 	13
802c2c66affSColin Finck 
803c2c66affSColin Finck /* global macros to define header offsets into file */
804c2c66affSColin Finck /* offset to PE file signature                                 */
805c2c66affSColin Finck #define NTSIGNATURE(a) ((LPVOID)((BYTE *)a		     +	\
806c2c66affSColin Finck 			((PIMAGE_DOS_HEADER)a)->e_lfanew))
807c2c66affSColin Finck 
808c2c66affSColin Finck /* DOS header identifies the NT PEFile signature dword
809c2c66affSColin Finck    the PEFILE header exists just after that dword              */
810c2c66affSColin Finck #define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a		     +	\
811c2c66affSColin Finck 			 ((PIMAGE_DOS_HEADER)a)->e_lfanew    +	\
812c2c66affSColin Finck 			 SIZE_OF_NT_SIGNATURE))
813c2c66affSColin Finck 
814c2c66affSColin Finck /* PE optional header is immediately after PEFile header       */
815c2c66affSColin Finck #define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a		     +	\
816c2c66affSColin Finck 			 ((PIMAGE_DOS_HEADER)a)->e_lfanew    +	\
817c2c66affSColin Finck 			 SIZE_OF_NT_SIGNATURE		     +	\
818c2c66affSColin Finck 			 sizeof (IMAGE_FILE_HEADER)))
819c2c66affSColin Finck 
820c2c66affSColin Finck /* section headers are immediately after PE optional header    */
821c2c66affSColin Finck #define SECHDROFFSET(a) ((LPVOID)((BYTE *)a		     +	\
822c2c66affSColin Finck 			 ((PIMAGE_DOS_HEADER)a)->e_lfanew    +	\
823c2c66affSColin Finck 			 SIZE_OF_NT_SIGNATURE		     +	\
824c2c66affSColin Finck 			 sizeof (IMAGE_FILE_HEADER)	     +	\
825c2c66affSColin Finck 			 sizeof (IMAGE_OPTIONAL_HEADER)))
826c2c66affSColin Finck 
827c2c66affSColin Finck 
828c2c66affSColin Finck typedef struct tagImportDirectory
829c2c66affSColin Finck   {
830c2c66affSColin Finck     DWORD dwRVAFunctionNameList;
831c2c66affSColin Finck     DWORD dwUseless1;
832c2c66affSColin Finck     DWORD dwUseless2;
833c2c66affSColin Finck     DWORD dwRVAModuleName;
834c2c66affSColin Finck     DWORD dwRVAFunctionAddressList;
835c2c66affSColin Finck   }
836c2c66affSColin Finck IMAGE_IMPORT_MODULE_DIRECTORY, *PIMAGE_IMPORT_MODULE_DIRECTORY;
837c2c66affSColin Finck 
838c2c66affSColin Finck 
839c2c66affSColin Finck /* global prototypes for functions in pefile.c */
840c2c66affSColin Finck /* PE file header info */
841c2c66affSColin Finck BOOL WINAPI GetDosHeader (LPVOID, PIMAGE_DOS_HEADER);
842c2c66affSColin Finck DWORD WINAPI ImageFileType (LPVOID);
843c2c66affSColin Finck BOOL WINAPI GetPEFileHeader (LPVOID, PIMAGE_FILE_HEADER);
844c2c66affSColin Finck 
845c2c66affSColin Finck /* PE optional header info */
846c2c66affSColin Finck BOOL WINAPI GetPEOptionalHeader (LPVOID, PIMAGE_OPTIONAL_HEADER);
847c2c66affSColin Finck LPVOID WINAPI GetModuleEntryPoint (LPVOID);
848c2c66affSColin Finck int WINAPI NumOfSections (LPVOID);
849c2c66affSColin Finck LPVOID WINAPI GetImageBase (LPVOID);
850c2c66affSColin Finck LPVOID WINAPI ImageDirectoryOffset (LPVOID, DWORD);
851c2c66affSColin Finck LPVOID WINAPI ImageDirectorySection (LPVOID, DWORD);
852c2c66affSColin Finck 
853c2c66affSColin Finck /* PE section header info */
854c2c66affSColin Finck //int   WINAPI GetSectionNames (LPVOID, HANDLE, char **);
855c2c66affSColin Finck int WINAPI GetSectionNames (LPVOID, char **);
856c2c66affSColin Finck BOOL WINAPI GetSectionHdrByName (LPVOID, PIMAGE_SECTION_HEADER, char *);
857c2c66affSColin Finck 
858c2c66affSColin Finck //
859c2c66affSColin Finck // structur to store string tokens
860c2c66affSColin Finck //
861c2c66affSColin Finck typedef struct _Str_P
862c2c66affSColin Finck   {
863c2c66affSColin Finck     char flag;			// string_flag '@' or '%' or '#'
864c2c66affSColin Finck 
865c2c66affSColin Finck     char *pos;			// starting postion of string
866c2c66affSColin Finck 
867c2c66affSColin Finck     int length;			// length of string
868c2c66affSColin Finck 
869c2c66affSColin Finck     BOOL wasString;		// if it were stringMode or not
870c2c66affSColin Finck 
871c2c66affSColin Finck   }
872c2c66affSColin Finck Str_P;
873c2c66affSColin Finck 
874c2c66affSColin Finck /* import section info */
875c2c66affSColin Finck int WINAPI GetImportModuleNames (LPVOID, char **);
876c2c66affSColin Finck int WINAPI GetImportFunctionNamesByModule (LPVOID, char *, char **);
877c2c66affSColin Finck 
878c2c66affSColin Finck // import function name reporting
879c2c66affSColin Finck int WINAPI GetStringLength (char *);
880c2c66affSColin Finck void WINAPI GetPreviousParamString (char *, char *);
881c2c66affSColin Finck void WINAPI TranslateParameters (char **, char **, char **);
882c2c66affSColin Finck BOOL WINAPI StringExpands (char **, char **, char **, Str_P *);
883c2c66affSColin Finck char * WINAPI TranslateFunctionName (char *);
884c2c66affSColin Finck 
885c2c66affSColin Finck /* export section info */
886c2c66affSColin Finck int WINAPI GetExportFunctionNames (LPVOID, char **);
887c2c66affSColin Finck 
888c2c66affSColin Finck /* resource section info */
889c2c66affSColin Finck int WINAPI GetNumberOfResources (LPVOID);
890c2c66affSColin Finck int WINAPI GetListOfResourceTypes (LPVOID, char **);
891c2c66affSColin Finck int WINAPI MenuScan (int *, WORD **);
892c2c66affSColin Finck int WINAPI MenuFill (char **, WORD **);
893c2c66affSColin Finck void WINAPI StrangeMenuFill (char **, WORD **, int);
894c2c66affSColin Finck int WINAPI GetContentsOfMenu (LPVOID, char **);
895c2c66affSColin Finck int WINAPI PrintMenu (int, char **);
896c2c66affSColin Finck int WINAPI PrintStrangeMenu (char **);
897c2c66affSColin Finck int WINAPI dumpMenu (char **psz, int size);
898c2c66affSColin Finck 
899c2c66affSColin Finck /* debug section info */
900c2c66affSColin Finck BOOL WINAPI IsDebugInfoStripped (LPVOID);
901c2c66affSColin Finck int WINAPI RetrieveModuleName (LPVOID, char **);
902c2c66affSColin Finck BOOL WINAPI IsDebugFile (LPVOID);
903c2c66affSColin Finck BOOL WINAPI GetSeparateDebugHeader (LPVOID, PIMAGE_SEPARATE_DEBUG_HEADER);
904c2c66affSColin Finck 
905c2c66affSColin Finck 
906c2c66affSColin Finck /**********************************************************************
907c2c66affSColin Finck  * NAME
908c2c66affSColin Finck  *
909c2c66affSColin Finck  * DESCRIPTION
910c2c66affSColin Finck  *	Copy DOS header information to structure.
911c2c66affSColin Finck  *
912c2c66affSColin Finck  * ARGUMENTS
913c2c66affSColin Finck  */
914c2c66affSColin Finck BOOL WINAPI
GetDosHeader(LPVOID lpFile,PIMAGE_DOS_HEADER pHeader)915c2c66affSColin Finck GetDosHeader (
916c2c66affSColin Finck 	       LPVOID lpFile,
917c2c66affSColin Finck 	       PIMAGE_DOS_HEADER pHeader
918c2c66affSColin Finck )
919c2c66affSColin Finck {
920c2c66affSColin Finck   /*
921c2c66affSColin Finck    * DOS header represents first structure
922c2c66affSColin Finck    * of bytes in PE image file.
923c2c66affSColin Finck    */
924c2c66affSColin Finck   if ((WORD) IMAGE_DOS_SIGNATURE == *(WORD *) lpFile)
925c2c66affSColin Finck     {
926c2c66affSColin Finck       bcopy (
927c2c66affSColin Finck 	      lpFile,
928c2c66affSColin Finck 	      (LPVOID) pHeader,
929c2c66affSColin Finck 	      sizeof (IMAGE_DOS_HEADER)
930c2c66affSColin Finck 	);
931c2c66affSColin Finck       return TRUE;
932c2c66affSColin Finck     }
933c2c66affSColin Finck   return FALSE;
934c2c66affSColin Finck }
935c2c66affSColin Finck 
936c2c66affSColin Finck 
937c2c66affSColin Finck 
938c2c66affSColin Finck 
939c2c66affSColin Finck /* return file signature */
940c2c66affSColin Finck DWORD WINAPI
ImageFileType(LPVOID lpFile)941c2c66affSColin Finck ImageFileType (
942c2c66affSColin Finck 		LPVOID lpFile)
943c2c66affSColin Finck {
944c2c66affSColin Finck   /* dos file signature comes first */
945c2c66affSColin Finck   if (*(USHORT *) lpFile == IMAGE_DOS_SIGNATURE)
946c2c66affSColin Finck     {
947c2c66affSColin Finck       /* determine location of PE File header from dos header */
948c2c66affSColin Finck       if (LOWORD (*(DWORD *) NTSIGNATURE (lpFile)) == IMAGE_OS2_SIGNATURE ||
949c2c66affSColin Finck 	  LOWORD (*(DWORD *) NTSIGNATURE (lpFile)) == IMAGE_OS2_SIGNATURE_LE)
950c2c66affSColin Finck 	return (DWORD) LOWORD (*(DWORD *) NTSIGNATURE (lpFile));
951c2c66affSColin Finck 
952c2c66affSColin Finck       else if (*(DWORD *) NTSIGNATURE (lpFile) == IMAGE_NT_SIGNATURE)
953c2c66affSColin Finck 	return IMAGE_NT_SIGNATURE;
954c2c66affSColin Finck 
955c2c66affSColin Finck       else
956c2c66affSColin Finck 	return IMAGE_DOS_SIGNATURE;
957c2c66affSColin Finck     }
958c2c66affSColin Finck 
959c2c66affSColin Finck   else
960c2c66affSColin Finck     /* unknown file type */
961c2c66affSColin Finck     return 0;
962c2c66affSColin Finck }
963c2c66affSColin Finck 
964c2c66affSColin Finck 
965c2c66affSColin Finck 
966c2c66affSColin Finck 
967c2c66affSColin Finck /* copy file header information to structure */
968c2c66affSColin Finck BOOL WINAPI
GetPEFileHeader(LPVOID lpFile,PIMAGE_FILE_HEADER pHeader)969c2c66affSColin Finck GetPEFileHeader (
970c2c66affSColin Finck 		  LPVOID lpFile,
971c2c66affSColin Finck 		  PIMAGE_FILE_HEADER pHeader)
972c2c66affSColin Finck {
973c2c66affSColin Finck   /* file header follows dos header */
974c2c66affSColin Finck   if (ImageFileType (lpFile) == IMAGE_NT_SIGNATURE)
975c2c66affSColin Finck     bcopy (PEFHDROFFSET (lpFile), (LPVOID) pHeader, sizeof (IMAGE_FILE_HEADER));
976c2c66affSColin Finck   else
977c2c66affSColin Finck     return FALSE;
978c2c66affSColin Finck 
979c2c66affSColin Finck   return TRUE;
980c2c66affSColin Finck }
981c2c66affSColin Finck 
982c2c66affSColin Finck 
983c2c66affSColin Finck 
984c2c66affSColin Finck 
985c2c66affSColin Finck 
986c2c66affSColin Finck /* copy optional header info to structure */
987c2c66affSColin Finck BOOL WINAPI
GetPEOptionalHeader(LPVOID lpFile,PIMAGE_OPTIONAL_HEADER pHeader)988c2c66affSColin Finck GetPEOptionalHeader (
989c2c66affSColin Finck 		      LPVOID lpFile,
990c2c66affSColin Finck 		      PIMAGE_OPTIONAL_HEADER pHeader)
991c2c66affSColin Finck {
992c2c66affSColin Finck   /* optional header follows file header and dos header */
993c2c66affSColin Finck   if (ImageFileType (lpFile) == IMAGE_NT_SIGNATURE)
994c2c66affSColin Finck     bcopy (OPTHDROFFSET (lpFile), (LPVOID) pHeader, sizeof (IMAGE_OPTIONAL_HEADER));
995c2c66affSColin Finck   else
996c2c66affSColin Finck     return FALSE;
997c2c66affSColin Finck 
998c2c66affSColin Finck   return TRUE;
999c2c66affSColin Finck }
1000c2c66affSColin Finck 
1001c2c66affSColin Finck 
1002c2c66affSColin Finck 
1003c2c66affSColin Finck 
1004c2c66affSColin Finck /* function returns the entry point for an exe module lpFile must
1005c2c66affSColin Finck    be a memory mapped file pointer to the beginning of the image file */
1006c2c66affSColin Finck LPVOID WINAPI
GetModuleEntryPoint(LPVOID lpFile)1007c2c66affSColin Finck GetModuleEntryPoint (
1008c2c66affSColin Finck 		      LPVOID lpFile)
1009c2c66affSColin Finck {
1010c2c66affSColin Finck   PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1011c2c66affSColin Finck 
1012c2c66affSColin Finck   if (poh != NULL)
1013c2c66affSColin Finck     return (LPVOID) (poh->AddressOfEntryPoint);
1014c2c66affSColin Finck   else
1015c2c66affSColin Finck     return NULL;
1016c2c66affSColin Finck }
1017c2c66affSColin Finck 
1018c2c66affSColin Finck 
1019c2c66affSColin Finck 
1020c2c66affSColin Finck 
1021c2c66affSColin Finck /* return the total number of sections in the module */
1022c2c66affSColin Finck int WINAPI
NumOfSections(LPVOID lpFile)1023c2c66affSColin Finck NumOfSections (
1024c2c66affSColin Finck 		LPVOID lpFile)
1025c2c66affSColin Finck {
1026c2c66affSColin Finck   /* number os sections is indicated in file header */
1027c2c66affSColin Finck   return ((int) ((PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile))->NumberOfSections);
1028c2c66affSColin Finck }
1029c2c66affSColin Finck 
1030c2c66affSColin Finck 
1031c2c66affSColin Finck 
1032c2c66affSColin Finck 
1033c2c66affSColin Finck /* retrieve entry point */
1034c2c66affSColin Finck LPVOID WINAPI
GetImageBase(LPVOID lpFile)1035c2c66affSColin Finck GetImageBase (
1036c2c66affSColin Finck 	       LPVOID lpFile)
1037c2c66affSColin Finck {
1038c2c66affSColin Finck   PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1039c2c66affSColin Finck 
1040c2c66affSColin Finck   if (poh != NULL)
1041c2c66affSColin Finck     return (LPVOID) (poh->ImageBase);
1042c2c66affSColin Finck   else
1043c2c66affSColin Finck     return NULL;
1044c2c66affSColin Finck }
1045c2c66affSColin Finck 
1046c2c66affSColin Finck 
1047c2c66affSColin Finck 
1048c2c66affSColin Finck //
1049c2c66affSColin Finck // This function is written by sang cho
1050c2c66affSColin Finck //                                                 .. october 5, 1997
1051c2c66affSColin Finck //
1052c2c66affSColin Finck /* function returns the actual address of given RVA,      lpFile must
1053c2c66affSColin Finck    be a memory mapped file pointer to the beginning of the image file */
1054c2c66affSColin Finck LPVOID WINAPI
GetActualAddress(LPVOID lpFile,DWORD dwRVA)1055c2c66affSColin Finck GetActualAddress (
1056c2c66affSColin Finck 		   LPVOID lpFile,
1057c2c66affSColin Finck 		   DWORD dwRVA)
1058c2c66affSColin Finck {
1059c2c66affSColin Finck //    PIMAGE_OPTIONAL_HEADER   poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
1060c2c66affSColin Finck   PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
1061c2c66affSColin Finck   int nSections = NumOfSections (lpFile);
1062c2c66affSColin Finck   int i = 0;
1063c2c66affSColin Finck 
1064c2c66affSColin Finck   if (dwRVA == 0)
1065c2c66affSColin Finck     return NULL;
1066c2c66affSColin Finck   if (dwRVA & 0x80000000)
1067c2c66affSColin Finck     {
1068c2c66affSColin Finck       //return (LPVOID)dwRVA;
1069c2c66affSColin Finck       printf ("\n$$ what is going on $$");
1070c2c66affSColin Finck       exit (0);
1071c2c66affSColin Finck     }
1072c2c66affSColin Finck 
1073c2c66affSColin Finck   /* locate section containing image directory */
1074c2c66affSColin Finck   while (i++ < nSections)
1075c2c66affSColin Finck     {
1076c2c66affSColin Finck       if (psh->VirtualAddress <= (DWORD) dwRVA &&
1077c2c66affSColin Finck 	  psh->VirtualAddress + psh->SizeOfRawData > (DWORD) dwRVA)
1078c2c66affSColin Finck 	break;
1079c2c66affSColin Finck       psh++;
1080c2c66affSColin Finck     }
1081c2c66affSColin Finck 
1082c2c66affSColin Finck   if (i > nSections)
1083c2c66affSColin Finck     return NULL;
1084c2c66affSColin Finck 
1085c2c66affSColin Finck   /* return image import directory offset */
1086c2c66affSColin Finck   return (LPVOID) (((int) lpFile + (int) dwRVA - psh->VirtualAddress) +
1087c2c66affSColin Finck 		   (int) psh->PointerToRawData);
1088c2c66affSColin Finck }
1089c2c66affSColin Finck 
1090c2c66affSColin Finck 
1091c2c66affSColin Finck //
1092c2c66affSColin Finck // This function is modified by sang cho
1093c2c66affSColin Finck //
1094c2c66affSColin Finck //
1095c2c66affSColin Finck /* return offset to specified IMAGE_DIRECTORY entry */
1096c2c66affSColin Finck LPVOID WINAPI
ImageDirectoryOffset(LPVOID lpFile,DWORD dwIMAGE_DIRECTORY)1097c2c66affSColin Finck ImageDirectoryOffset (
1098c2c66affSColin Finck 		       LPVOID lpFile,
1099c2c66affSColin Finck 		       DWORD dwIMAGE_DIRECTORY)
1100c2c66affSColin Finck {
1101c2c66affSColin Finck   PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1102c2c66affSColin Finck   PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
1103c2c66affSColin Finck   int nSections = NumOfSections (lpFile);
1104c2c66affSColin Finck   int i = 0;
1105c2c66affSColin Finck   LPVOID VAImageDir;
1106c2c66affSColin Finck 
1107c2c66affSColin Finck   /* must be 0 thru (NumberOfRvaAndSizes-1) */
1108c2c66affSColin Finck   if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
1109c2c66affSColin Finck     return NULL;
1110c2c66affSColin Finck 
1111c2c66affSColin Finck   /* locate specific image directory's relative virtual address */
1112c2c66affSColin Finck   VAImageDir = (LPVOID) poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress;
1113c2c66affSColin Finck 
1114c2c66affSColin Finck   if (VAImageDir == NULL)
1115c2c66affSColin Finck     return NULL;
1116c2c66affSColin Finck   /* locate section containing image directory */
1117c2c66affSColin Finck   while (i++ < nSections)
1118c2c66affSColin Finck     {
1119c2c66affSColin Finck       if (psh->VirtualAddress <= (DWORD) VAImageDir &&
1120c2c66affSColin Finck 	  psh->VirtualAddress + psh->SizeOfRawData > (DWORD) VAImageDir)
1121c2c66affSColin Finck 	break;
1122c2c66affSColin Finck       psh++;
1123c2c66affSColin Finck     }
1124c2c66affSColin Finck 
1125c2c66affSColin Finck   if (i > nSections)
1126c2c66affSColin Finck     return NULL;
1127c2c66affSColin Finck 
1128c2c66affSColin Finck   /* return image import directory offset */
1129c2c66affSColin Finck   return (LPVOID) (((int) lpFile + (int) VAImageDir - psh->VirtualAddress) +
1130c2c66affSColin Finck 		   (int) psh->PointerToRawData);
1131c2c66affSColin Finck }
1132c2c66affSColin Finck 
1133c2c66affSColin Finck 
1134c2c66affSColin Finck /* function retrieve names of all the sections in the file */
1135c2c66affSColin Finck int WINAPI
GetSectionNames(LPVOID lpFile,char ** pszSections)1136c2c66affSColin Finck GetSectionNames (
1137c2c66affSColin Finck 		  LPVOID lpFile,
1138c2c66affSColin Finck 		  char **pszSections)
1139c2c66affSColin Finck {
1140c2c66affSColin Finck   int nSections = NumOfSections (lpFile);
1141c2c66affSColin Finck   int i, nCnt = 0;
1142c2c66affSColin Finck   PIMAGE_SECTION_HEADER psh;
1143c2c66affSColin Finck   char *ps;
1144c2c66affSColin Finck 
1145c2c66affSColin Finck 
1146c2c66affSColin Finck   if (ImageFileType (lpFile) != IMAGE_NT_SIGNATURE ||
1147c2c66affSColin Finck       (psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) == NULL)
1148c2c66affSColin Finck     return 0;
1149c2c66affSColin Finck 
1150c2c66affSColin Finck   /* count the number of chars used in the section names */
1151c2c66affSColin Finck   for (i = 0; i < nSections; i++)
1152c2c66affSColin Finck     nCnt += strlen ((char *)psh[i].Name) + 1;
1153c2c66affSColin Finck 
1154c2c66affSColin Finck   /* allocate space for all section names from heap */
1155c2c66affSColin Finck   ps = *pszSections = (char *) calloc (nCnt, 1);
1156c2c66affSColin Finck 
1157c2c66affSColin Finck 
1158c2c66affSColin Finck   for (i = 0; i < nSections; i++)
1159c2c66affSColin Finck     {
1160c2c66affSColin Finck       strcpy (ps, (char *)psh[i].Name);
1161c2c66affSColin Finck       ps += strlen ((char *)psh[i].Name) + 1;
1162c2c66affSColin Finck     }
1163c2c66affSColin Finck 
1164c2c66affSColin Finck   return nCnt;
1165c2c66affSColin Finck }
1166c2c66affSColin Finck 
1167c2c66affSColin Finck 
1168c2c66affSColin Finck 
1169c2c66affSColin Finck 
1170c2c66affSColin Finck /* function gets the function header for a section identified by name */
1171c2c66affSColin Finck BOOL WINAPI
GetSectionHdrByName(LPVOID lpFile,IMAGE_SECTION_HEADER * sh,char * szSection)1172c2c66affSColin Finck GetSectionHdrByName (
1173c2c66affSColin Finck 		      LPVOID lpFile,
1174c2c66affSColin Finck 		      IMAGE_SECTION_HEADER * sh,
1175c2c66affSColin Finck 		      char *szSection)
1176c2c66affSColin Finck {
1177c2c66affSColin Finck   PIMAGE_SECTION_HEADER psh;
1178c2c66affSColin Finck   int nSections = NumOfSections (lpFile);
1179c2c66affSColin Finck   int i;
1180c2c66affSColin Finck 
1181c2c66affSColin Finck 
1182c2c66affSColin Finck   if ((psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) != NULL)
1183c2c66affSColin Finck     {
1184c2c66affSColin Finck       /* find the section by name */
1185c2c66affSColin Finck       for (i = 0; i < nSections; i++)
1186c2c66affSColin Finck 	{
1187c2c66affSColin Finck 	  if (!strcmp ((char *)psh->Name, szSection))
1188c2c66affSColin Finck 	    {
1189c2c66affSColin Finck 	      /* copy data to header */
1190c2c66affSColin Finck 	      bcopy ((LPVOID) psh, (LPVOID) sh, sizeof (IMAGE_SECTION_HEADER));
1191c2c66affSColin Finck 	      return TRUE;
1192c2c66affSColin Finck 	    }
1193c2c66affSColin Finck 	  else
1194c2c66affSColin Finck 	    psh++;
1195c2c66affSColin Finck 	}
1196c2c66affSColin Finck     }
1197c2c66affSColin Finck   return FALSE;
1198c2c66affSColin Finck }
1199c2c66affSColin Finck 
1200c2c66affSColin Finck 
1201c2c66affSColin Finck 
1202c2c66affSColin Finck //
1203c2c66affSColin Finck // This function is modified by sang cho
1204c2c66affSColin Finck //
1205c2c66affSColin Finck //
1206c2c66affSColin Finck /* get import modules names separated by null terminators, return module count */
1207c2c66affSColin Finck int WINAPI
GetImportModuleNames(LPVOID lpFile,char ** pszModules)1208c2c66affSColin Finck GetImportModuleNames (
1209c2c66affSColin Finck 		       LPVOID lpFile,
1210c2c66affSColin Finck 		       char **pszModules)
1211c2c66affSColin Finck {
1212c2c66affSColin Finck   PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)
1213c2c66affSColin Finck   ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1214c2c66affSColin Finck   //
1215c2c66affSColin Finck   // sometimes there may be no section for idata or edata
1216c2c66affSColin Finck   // instead rdata or data section may contain these sections ..
1217c2c66affSColin Finck   // or even module names or function names are in different section.
1218c2c66affSColin Finck   // so that's why we need to get actual address of RVAs each time.
1219c2c66affSColin Finck   //         ...................sang cho..................
1220c2c66affSColin Finck   //
1221c2c66affSColin Finck   // PIMAGE_SECTION_HEADER     psh = (PIMAGE_SECTION_HEADER)
1222c2c66affSColin Finck   // ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1223c2c66affSColin Finck   // BYTE                  *pData = (BYTE *)pid;
1224c2c66affSColin Finck   //      DWORD            *pdw = (DWORD *)pid;
1225c2c66affSColin Finck   int nCnt = 0, nSize = 0, i;
1226c2c66affSColin Finck   char *pModule[1024];		/* hardcoded maximum number of modules?? */
1227c2c66affSColin Finck   char *psz;
1228c2c66affSColin Finck 
1229c2c66affSColin Finck   if (pid == NULL)
1230c2c66affSColin Finck     return 0;
1231c2c66affSColin Finck 
1232c2c66affSColin Finck   // pData = (BYTE *)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1233c2c66affSColin Finck 
1234c2c66affSColin Finck   /* extract all import modules */
1235c2c66affSColin Finck   while (pid->dwRVAModuleName)
1236c2c66affSColin Finck     {
1237c2c66affSColin Finck       /* allocate temporary buffer for absolute string offsets */
1238c2c66affSColin Finck       //pModule[nCnt] = (char *)(pData + pid->dwRVAModuleName);
1239c2c66affSColin Finck       pModule[nCnt] = (char *) GetActualAddress (lpFile, pid->dwRVAModuleName);
1240c2c66affSColin Finck       nSize += strlen (pModule[nCnt]) + 1;
1241c2c66affSColin Finck 
1242c2c66affSColin Finck       /* increment to the next import directory entry */
1243c2c66affSColin Finck       pid++;
1244c2c66affSColin Finck       nCnt++;
1245c2c66affSColin Finck     }
1246c2c66affSColin Finck 
1247c2c66affSColin Finck   /* copy all strings to one chunk of memory */
1248c2c66affSColin Finck   *pszModules = (char *) calloc (nSize, 1);
1249c2c66affSColin Finck   psz = *pszModules;
1250c2c66affSColin Finck   for (i = 0; i < nCnt; i++)
1251c2c66affSColin Finck     {
1252c2c66affSColin Finck       strcpy (psz, pModule[i]);
1253c2c66affSColin Finck       psz += strlen (psz) + 1;
1254c2c66affSColin Finck     }
1255c2c66affSColin Finck   return nCnt;
1256c2c66affSColin Finck }
1257c2c66affSColin Finck 
1258c2c66affSColin Finck 
1259c2c66affSColin Finck //
1260c2c66affSColin Finck // This function is rewritten by sang cho
1261c2c66affSColin Finck //
1262c2c66affSColin Finck //
1263c2c66affSColin Finck /* get import module function names separated by null terminators, return function count */
1264c2c66affSColin Finck int WINAPI
GetImportFunctionNamesByModule(LPVOID lpFile,char * pszModule,char ** pszFunctions)1265c2c66affSColin Finck GetImportFunctionNamesByModule (
1266c2c66affSColin Finck 				 LPVOID lpFile,
1267c2c66affSColin Finck 				 char *pszModule,
1268c2c66affSColin Finck 				 char **pszFunctions)
1269c2c66affSColin Finck {
1270c2c66affSColin Finck   PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)
1271c2c66affSColin Finck   ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1272c2c66affSColin Finck   //
1273c2c66affSColin Finck   // sometimes there may be no section for idata or edata
1274c2c66affSColin Finck   // instead rdata or data section may contain these sections ..
1275c2c66affSColin Finck   // or even module names or function names are in different section.
1276c2c66affSColin Finck   // so that's why we need to get actual address each time.
1277c2c66affSColin Finck   //         ...................sang cho..................
1278c2c66affSColin Finck   //
1279c2c66affSColin Finck   //PIMAGE_SECTION_HEADER           psh = (PIMAGE_SECTION_HEADER)
1280c2c66affSColin Finck   //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1281c2c66affSColin Finck   //DWORD                  dwBase;
1282c2c66affSColin Finck   int nCnt = 0, nSize = 0;
1283c2c66affSColin Finck   int nnid = 0;
1284c2c66affSColin Finck   int mnlength, i;
1285c2c66affSColin Finck   DWORD dwFunctionName;
1286c2c66affSColin Finck   DWORD dwFunctionAddress;
1287c2c66affSColin Finck   char name[128];
1288c2c66affSColin Finck   char buff[256];		// enough for any string ??
1289c2c66affSColin Finck 
1290c2c66affSColin Finck   char *psz;
1291c2c66affSColin Finck   DWORD *pdw;
1292c2c66affSColin Finck 
1293c2c66affSColin Finck   //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1294c2c66affSColin Finck 
1295c2c66affSColin Finck   /* find module's pid */
1296c2c66affSColin Finck   while (pid->dwRVAModuleName &&
1297c2c66affSColin Finck 	 strcmp (pszModule, (char *) GetActualAddress (lpFile, pid->dwRVAModuleName)))
1298c2c66affSColin Finck     pid++;
1299c2c66affSColin Finck 
1300c2c66affSColin Finck   /* exit if the module is not found */
1301c2c66affSColin Finck   if (!pid->dwRVAModuleName)
1302c2c66affSColin Finck     return 0;
1303c2c66affSColin Finck 
1304c2c66affSColin Finck   // I am doing this to get rid of .dll from module name
1305c2c66affSColin Finck   strcpy (name, pszModule);
1306c2c66affSColin Finck   mnlength = strlen (pszModule);
1307c2c66affSColin Finck   for (i = 0; i < mnlength; i++)
1308c2c66affSColin Finck     if (name[i] == '.')
1309c2c66affSColin Finck       break;
1310c2c66affSColin Finck   name[i] = 0;
1311c2c66affSColin Finck   mnlength = i;
1312c2c66affSColin Finck 
1313c2c66affSColin Finck   /* count number of function names and length of strings */
1314c2c66affSColin Finck   dwFunctionName = pid->dwRVAFunctionNameList;
1315c2c66affSColin Finck 
1316c2c66affSColin Finck   // IMAGE_IMPORT_BY_NAME OR IMAGE_THUNK_DATA
1317c2c66affSColin Finck   // modified by Sang Cho
1318c2c66affSColin Finck   while (dwFunctionName &&
1319c2c66affSColin Finck 	 *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName)))
1320c2c66affSColin Finck     {
1321c2c66affSColin Finck       if ((*pdw) & 0x80000000)
1322c2c66affSColin Finck 	nSize += mnlength + 10 + 1 + 6;
1323c2c66affSColin Finck       else
1324c2c66affSColin Finck 	nSize += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1 + 6;
1325c2c66affSColin Finck       dwFunctionName += 4;
1326c2c66affSColin Finck       nCnt++;
1327c2c66affSColin Finck     }
1328c2c66affSColin Finck 
1329c2c66affSColin Finck   /* allocate memory  for function names */
1330c2c66affSColin Finck   *pszFunctions = (char *) calloc (nSize, 1);
1331c2c66affSColin Finck   psz = *pszFunctions;
1332c2c66affSColin Finck 
1333c2c66affSColin Finck   //
1334c2c66affSColin Finck   // I modified this part to store function address (4 bytes),
1335c2c66affSColin Finck   //                               ord number (2 bytes),
1336c2c66affSColin Finck   //                                                      and      name strings (which was there originally)
1337c2c66affSColin Finck   // so that's why there are 6 more bytes...... +6,  or +4 and +2 etc.
1338c2c66affSColin Finck   // these informations are used where they are needed.
1339c2c66affSColin Finck   //                      ...........sang cho..................
1340c2c66affSColin Finck   //
1341c2c66affSColin Finck   /* copy function names to mempry pointer */
1342c2c66affSColin Finck   dwFunctionName = pid->dwRVAFunctionNameList;
1343c2c66affSColin Finck   dwFunctionAddress = pid->dwRVAFunctionAddressList;
1344c2c66affSColin Finck   while (dwFunctionName &&
1345c2c66affSColin Finck 	 *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName)))
1346c2c66affSColin Finck     {
1347c2c66affSColin Finck       if ((*pdw) & 0x80000000)
1348c2c66affSColin Finck 	{
1349c2c66affSColin Finck 	  *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress));
1350c2c66affSColin Finck 	  psz += 4;
1351c2c66affSColin Finck 	  *(short *) psz = *(short *) pdw;
1352c2c66affSColin Finck 	  psz += 2;
1353c2c66affSColin Finck 	  sprintf (buff, "%s:NoName%04d", name, nnid++);
1354c2c66affSColin Finck 	  strcpy (psz, buff);
1355c2c66affSColin Finck 	  psz += strlen (buff) + 1;
1356c2c66affSColin Finck 	}
1357c2c66affSColin Finck       else
1358c2c66affSColin Finck 	{
1359c2c66affSColin Finck 	  *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress));
1360c2c66affSColin Finck 	  psz += 4;
1361c2c66affSColin Finck 	  *(short *) psz = (*(short *) GetActualAddress (lpFile, *pdw));
1362c2c66affSColin Finck 	  psz += 2;
1363c2c66affSColin Finck 	  strcpy (psz, (char *) GetActualAddress (lpFile, *pdw + 2));
1364c2c66affSColin Finck 	  psz += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1;
1365c2c66affSColin Finck 	}
1366c2c66affSColin Finck       dwFunctionName += 4;
1367c2c66affSColin Finck       dwFunctionAddress += 4;
1368c2c66affSColin Finck     }
1369c2c66affSColin Finck 
1370c2c66affSColin Finck   return nCnt;
1371c2c66affSColin Finck }
1372c2c66affSColin Finck 
1373c2c66affSColin Finck 
1374c2c66affSColin Finck 
1375c2c66affSColin Finck 
1376c2c66affSColin Finck //
1377c2c66affSColin Finck // This function is written by sang cho
1378c2c66affSColin Finck //                                                         October 6, 1997
1379c2c66affSColin Finck //
1380c2c66affSColin Finck /* get numerically expressed string length */
1381c2c66affSColin Finck int WINAPI
GetStringLength(char * psz)1382c2c66affSColin Finck GetStringLength (
1383c2c66affSColin Finck 		  char *psz)
1384c2c66affSColin Finck {
1385c2c66affSColin Finck   if (!isdigit (*psz))
1386c2c66affSColin Finck     return 0;
1387c2c66affSColin Finck   if (isdigit (*(psz + 1)))
1388c2c66affSColin Finck     return (*psz - '0') * 10 + *(psz + 1) - '0';
1389c2c66affSColin Finck   else
1390c2c66affSColin Finck     return *psz - '0';
1391c2c66affSColin Finck }
1392c2c66affSColin Finck 
1393c2c66affSColin Finck 
1394c2c66affSColin Finck 
1395c2c66affSColin Finck 
1396c2c66affSColin Finck //
1397c2c66affSColin Finck // This function is written by sang cho
1398c2c66affSColin Finck //                                                         October 12, 1997
1399c2c66affSColin Finck //
1400c2c66affSColin Finck 
1401c2c66affSColin Finck /* translate parameter part of condensed name */
1402c2c66affSColin Finck void WINAPI
GetPreviousParamString(char * xpin,char * xpout)1403c2c66affSColin Finck GetPreviousParamString (
1404c2c66affSColin Finck 			 char *xpin,	// read-only source
1405c2c66affSColin Finck 			  char *xpout)	// translated result
1406c2c66affSColin Finck  {
1407c2c66affSColin Finck   int n = 0;
1408c2c66affSColin Finck   char *pin, *pout;
1409c2c66affSColin Finck 
1410c2c66affSColin Finck   pin = xpin;
1411c2c66affSColin Finck   pout = xpout;
1412c2c66affSColin Finck 
1413c2c66affSColin Finck   pin--;
1414c2c66affSColin Finck   if (*pin == ',')
1415c2c66affSColin Finck     pin--;
1416c2c66affSColin Finck   else
1417c2c66affSColin Finck     {
1418c2c66affSColin Finck       printf ("\n **error PreviousParamString1 char = %c", *pin);
1419c2c66affSColin Finck       exit (0);
1420c2c66affSColin Finck     }
1421c2c66affSColin Finck 
1422c2c66affSColin Finck   while (*pin)
1423c2c66affSColin Finck     {
1424c2c66affSColin Finck       if (*pin == '>')
1425c2c66affSColin Finck 	n++;
1426c2c66affSColin Finck       else if (*pin == '<')
1427c2c66affSColin Finck 	n--;
1428c2c66affSColin Finck       else if (*pin == ')')
1429c2c66affSColin Finck 	n++;
1430c2c66affSColin Finck 
1431c2c66affSColin Finck       if (n > 0)
1432c2c66affSColin Finck 	{
1433c2c66affSColin Finck 	  if (*pin == '(')
1434c2c66affSColin Finck 	    n--;
1435c2c66affSColin Finck 	}
1436c2c66affSColin Finck       else if (strchr (",(", *pin))
1437c2c66affSColin Finck 	break;
1438c2c66affSColin Finck       pin--;
1439c2c66affSColin Finck     }
1440c2c66affSColin Finck 
1441c2c66affSColin Finck   //printf("\n ----- %s", pin);
1442c2c66affSColin Finck   if (strchr (",(", *pin))
1443c2c66affSColin Finck     {
1444c2c66affSColin Finck       pin++;
1445c2c66affSColin Finck     }				// printf("\n %s", pin); }
1446c2c66affSColin Finck 
1447c2c66affSColin Finck   else
1448c2c66affSColin Finck     {
1449c2c66affSColin Finck       printf ("\n **error PreviousParamString2");
1450c2c66affSColin Finck       exit (0);
1451c2c66affSColin Finck     }
1452c2c66affSColin Finck 
1453c2c66affSColin Finck   n = xpin - pin - 1;
1454c2c66affSColin Finck   strncpy (pout, pin, n);
1455c2c66affSColin Finck   *(pout + n) = 0;
1456c2c66affSColin Finck }
1457c2c66affSColin Finck 
1458c2c66affSColin Finck 
1459c2c66affSColin Finck 
1460c2c66affSColin Finck 
1461c2c66affSColin Finck //
1462c2c66affSColin Finck // This function is written by sang cho
1463c2c66affSColin Finck //                                                         October 10, 1997
1464c2c66affSColin Finck //
1465c2c66affSColin Finck 
1466c2c66affSColin Finck /* translate parameter part of condensed name */
1467c2c66affSColin Finck void WINAPI
TranslateParameters(char ** ppin,char ** ppout,char ** pps)1468c2c66affSColin Finck TranslateParameters (
1469c2c66affSColin Finck 		      char **ppin,	// read-only source
1470c2c66affSColin Finck 		       char **ppout,	// translated result
1471c2c66affSColin Finck 		       char **pps)	// parameter stack
1472c2c66affSColin Finck  {
1473c2c66affSColin Finck   int i, n;
1474c2c66affSColin Finck   char c;
1475c2c66affSColin Finck   char name[128];
1476c2c66affSColin Finck   char *pin, *pout, *ps;
1477c2c66affSColin Finck 
1478c2c66affSColin Finck   //printf(" %c ", **in);
1479c2c66affSColin Finck   pin = *ppin;
1480c2c66affSColin Finck   pout = *ppout;
1481c2c66affSColin Finck   ps = *pps;
1482c2c66affSColin Finck   c = *pin;
1483c2c66affSColin Finck   switch (c)
1484c2c66affSColin Finck     {
1485c2c66affSColin Finck       // types processing
1486c2c66affSColin Finck     case 'b':
1487c2c66affSColin Finck       strcpy (pout, "byte");
1488c2c66affSColin Finck       pout += 4;
1489c2c66affSColin Finck       pin++;
1490c2c66affSColin Finck       break;
1491c2c66affSColin Finck     case 'c':
1492c2c66affSColin Finck       strcpy (pout, "char");
1493c2c66affSColin Finck       pout += 4;
1494c2c66affSColin Finck       pin++;
1495c2c66affSColin Finck       break;
1496c2c66affSColin Finck     case 'd':
1497c2c66affSColin Finck       strcpy (pout, "double");
1498c2c66affSColin Finck       pout += 6;
1499c2c66affSColin Finck       pin++;
1500c2c66affSColin Finck       break;
1501c2c66affSColin Finck     case 'f':
1502c2c66affSColin Finck       strcpy (pout, "float");
1503c2c66affSColin Finck       pout += 5;
1504c2c66affSColin Finck       pin++;
1505c2c66affSColin Finck       break;
1506c2c66affSColin Finck     case 'g':
1507c2c66affSColin Finck       strcpy (pout, "long double");
1508c2c66affSColin Finck       pout += 11;
1509c2c66affSColin Finck       pin++;
1510c2c66affSColin Finck       break;
1511c2c66affSColin Finck     case 'i':
1512c2c66affSColin Finck       strcpy (pout, "int");
1513c2c66affSColin Finck       pout += 3;
1514c2c66affSColin Finck       pin++;
1515c2c66affSColin Finck       break;
1516c2c66affSColin Finck     case 'l':
1517c2c66affSColin Finck       strcpy (pout, "long");
1518c2c66affSColin Finck       pout += 4;
1519c2c66affSColin Finck       pin++;
1520c2c66affSColin Finck       break;
1521c2c66affSColin Finck     case 's':
1522c2c66affSColin Finck       strcpy (pout, "short");
1523c2c66affSColin Finck       pout += 5;
1524c2c66affSColin Finck       pin++;
1525c2c66affSColin Finck       break;
1526c2c66affSColin Finck     case 'v':
1527c2c66affSColin Finck       strcpy (pout, "void");
1528c2c66affSColin Finck       pout += 4;
1529c2c66affSColin Finck       pin++;
1530c2c66affSColin Finck       break;
1531c2c66affSColin Finck       // postfix processing
1532c2c66affSColin Finck     case 'M':
1533c2c66affSColin Finck     case 'p':
1534c2c66affSColin Finck       if (*(pin + 1) == 'p')
1535c2c66affSColin Finck 	{
1536c2c66affSColin Finck 	  *ps++ = 'p';
1537c2c66affSColin Finck 	  pin += 2;
1538c2c66affSColin Finck 	}
1539c2c66affSColin Finck       else
1540c2c66affSColin Finck 	{
1541c2c66affSColin Finck 	  *ps++ = '*';
1542c2c66affSColin Finck 	  pin++;
1543c2c66affSColin Finck 	}
1544c2c66affSColin Finck       *ppin = pin;
1545c2c66affSColin Finck       *ppout = pout;
1546c2c66affSColin Finck       *pps = ps;
1547c2c66affSColin Finck       return;
1548c2c66affSColin Finck     case 'q':
1549c2c66affSColin Finck       *pout++ = '(';
1550c2c66affSColin Finck       pin++;
1551c2c66affSColin Finck       *ps++ = 'q';
1552c2c66affSColin Finck       *ppin = pin;
1553c2c66affSColin Finck       *ppout = pout;
1554c2c66affSColin Finck       *pps = ps;
1555c2c66affSColin Finck       return;
1556c2c66affSColin Finck     case 'r':
1557c2c66affSColin Finck       if (*(pin + 1) == 'p')
1558c2c66affSColin Finck 	{
1559c2c66affSColin Finck 	  *ps++ = 'r';
1560c2c66affSColin Finck 	  pin += 2;
1561c2c66affSColin Finck 	}
1562c2c66affSColin Finck       else
1563c2c66affSColin Finck 	{
1564c2c66affSColin Finck 	  *ps++ = '&';
1565c2c66affSColin Finck 	  pin++;
1566c2c66affSColin Finck 	}
1567c2c66affSColin Finck       *ppin = pin;
1568c2c66affSColin Finck       *ppout = pout;
1569c2c66affSColin Finck       *pps = ps;
1570c2c66affSColin Finck       return;
1571c2c66affSColin Finck       // repeat processing
1572c2c66affSColin Finck     case 't':
1573c2c66affSColin Finck       if (isdigit (*(pin + 1)))
1574c2c66affSColin Finck 	{
1575c2c66affSColin Finck 	  n = *(pin + 1) - '0';
1576c2c66affSColin Finck 	  pin++;
1577c2c66affSColin Finck 	  pin++;
1578c2c66affSColin Finck 	  GetPreviousParamString (pout, name);
1579c2c66affSColin Finck 	  strcpy (pout, name);
1580c2c66affSColin Finck 	  pout += strlen (name);
1581c2c66affSColin Finck 	  for (i = 1; i < n; i++)
1582c2c66affSColin Finck 	    {
1583c2c66affSColin Finck 	      *pout++ = ',';
1584c2c66affSColin Finck 	      strcpy (pout, name);
1585c2c66affSColin Finck 	      pout += strlen (name);
1586c2c66affSColin Finck 	    }
1587c2c66affSColin Finck 	}
1588c2c66affSColin Finck       else
1589c2c66affSColin Finck 	pin++;
1590c2c66affSColin Finck       break;
1591c2c66affSColin Finck       // prefix processing
1592c2c66affSColin Finck     case 'u':
1593c2c66affSColin Finck       strcpy (pout, "u");
1594c2c66affSColin Finck       pout += 1;
1595c2c66affSColin Finck       pin++;
1596c2c66affSColin Finck       *ppin = pin;
1597c2c66affSColin Finck       *ppout = pout;
1598c2c66affSColin Finck       *pps = ps;
1599c2c66affSColin Finck       return;
1600c2c66affSColin Finck     case 'x':
1601c2c66affSColin Finck       strcpy (pout, "const ");
1602c2c66affSColin Finck       pout += 6;
1603c2c66affSColin Finck       pin++;
1604c2c66affSColin Finck       *ppin = pin;
1605c2c66affSColin Finck       *ppout = pout;
1606c2c66affSColin Finck       *pps = ps;
1607c2c66affSColin Finck       return;
1608c2c66affSColin Finck     case 'z':
1609c2c66affSColin Finck       strcpy (pout, "static ");
1610c2c66affSColin Finck       pout += 7;
1611c2c66affSColin Finck       pin++;
1612c2c66affSColin Finck       *ppin = pin;
1613c2c66affSColin Finck       *ppout = pout;
1614c2c66affSColin Finck       *pps = ps;
1615c2c66affSColin Finck       return;
1616c2c66affSColin Finck     default:
1617c2c66affSColin Finck       strcpy (pout, "!1!");
1618c2c66affSColin Finck       pout += 3;
1619c2c66affSColin Finck       *pout++ = *pin++;
1620c2c66affSColin Finck       *ppin = pin;
1621c2c66affSColin Finck       *ppout = pout;
1622c2c66affSColin Finck       *pps = ps;
1623c2c66affSColin Finck       return;
1624c2c66affSColin Finck     }
1625c2c66affSColin Finck   // need to process postfix finally
1626c2c66affSColin Finck   c = *(ps - 1);
1627c2c66affSColin Finck   if (strchr ("tqx", c))
1628c2c66affSColin Finck     {
1629c2c66affSColin Finck       if (*(pin) && !strchr ("@$%", *(pin)))
1630c2c66affSColin Finck 	*pout++ = ',';
1631c2c66affSColin Finck       *ppin = pin;
1632c2c66affSColin Finck       *ppout = pout;
1633c2c66affSColin Finck       *pps = ps;
1634c2c66affSColin Finck       return;
1635c2c66affSColin Finck     }
1636c2c66affSColin Finck   switch (c)
1637c2c66affSColin Finck     {
1638c2c66affSColin Finck     case 'r':
1639c2c66affSColin Finck       strcpy (pout, "*&");
1640c2c66affSColin Finck       pout += 2;
1641c2c66affSColin Finck       ps--;
1642c2c66affSColin Finck       break;
1643c2c66affSColin Finck     case 'p':
1644c2c66affSColin Finck       strcpy (pout, "**");
1645c2c66affSColin Finck       pout += 2;
1646c2c66affSColin Finck       ps--;
1647c2c66affSColin Finck       break;
1648c2c66affSColin Finck     case '&':
1649c2c66affSColin Finck       strcpy (pout, "&");
1650c2c66affSColin Finck       pout += 1;
1651c2c66affSColin Finck       ps--;
1652c2c66affSColin Finck       break;
1653c2c66affSColin Finck     case '*':
1654c2c66affSColin Finck       strcpy (pout, "*");
1655c2c66affSColin Finck       pout += 1;
1656c2c66affSColin Finck       ps--;
1657c2c66affSColin Finck       break;
1658c2c66affSColin Finck     default:
1659c2c66affSColin Finck       strcpy (pout, "!2!");
1660c2c66affSColin Finck       pout += 3;
1661c2c66affSColin Finck       ps--;
1662c2c66affSColin Finck       break;
1663c2c66affSColin Finck     }
1664c2c66affSColin Finck   if (*(pin) && !strchr ("@$%", *(pin)))
1665c2c66affSColin Finck     *pout++ = ',';
1666c2c66affSColin Finck   *ppin = pin;
1667c2c66affSColin Finck   *ppout = pout;
1668c2c66affSColin Finck   *pps = ps;
1669c2c66affSColin Finck }
1670c2c66affSColin Finck 
1671c2c66affSColin Finck 
1672c2c66affSColin Finck //
1673c2c66affSColin Finck // This function is written by sang cho
1674c2c66affSColin Finck //                                                         October 11, 1997
1675c2c66affSColin Finck //
1676c2c66affSColin Finck 
1677c2c66affSColin Finck /* translate parameter part of condensed name */
1678c2c66affSColin Finck BOOL WINAPI
StringExpands(char ** ppin,char ** ppout,char ** pps,Str_P * pcstr)1679c2c66affSColin Finck StringExpands (
1680c2c66affSColin Finck 		char **ppin,	// read-only source
1681c2c66affSColin Finck 		 char **ppout,	// translated result
1682c2c66affSColin Finck 		 char **pps,	// parameter stack
1683c2c66affSColin Finck 		 Str_P * pcstr)	// currently stored string
1684c2c66affSColin Finck  {
1685c2c66affSColin Finck //      int         n;
1686c2c66affSColin Finck   //      char        c;
1687c2c66affSColin Finck   char *pin, *pout, *ps;
1688c2c66affSColin Finck   Str_P c_str;
1689c2c66affSColin Finck   BOOL stringMode = TRUE;
1690c2c66affSColin Finck 
1691c2c66affSColin Finck   pin = *ppin;
1692c2c66affSColin Finck   pout = *ppout;
1693c2c66affSColin Finck   ps = *pps;
1694c2c66affSColin Finck   c_str = *pcstr;
1695c2c66affSColin Finck 
1696c2c66affSColin Finck   if (strncmp (pin, "bctr", 4) == 0)
1697c2c66affSColin Finck     {
1698c2c66affSColin Finck       strncpy (pout, c_str.pos, c_str.length);
1699c2c66affSColin Finck       pout += c_str.length;
1700c2c66affSColin Finck       pin += 4;
1701c2c66affSColin Finck     }
1702c2c66affSColin Finck   else if (strncmp (pin, "bdtr", 4) == 0)
1703c2c66affSColin Finck     {
1704c2c66affSColin Finck       *pout++ = '~';
1705c2c66affSColin Finck       strncpy (pout, c_str.pos, c_str.length);
1706c2c66affSColin Finck       pout += c_str.length;
1707c2c66affSColin Finck       pin += 4;
1708c2c66affSColin Finck     }
1709c2c66affSColin Finck   else if (*pin == 'o')
1710c2c66affSColin Finck     {
1711c2c66affSColin Finck       strcpy (pout, "const ");
1712c2c66affSColin Finck       pout += 6;
1713c2c66affSColin Finck       pin++;
1714c2c66affSColin Finck       stringMode = FALSE;
1715c2c66affSColin Finck     }
1716c2c66affSColin Finck   else if (*pin == 'q')
1717c2c66affSColin Finck     {
1718c2c66affSColin Finck       *pout++ = '(';
1719c2c66affSColin Finck       pin++;
1720c2c66affSColin Finck       *ps++ = 'q';
1721c2c66affSColin Finck       stringMode = FALSE;
1722c2c66affSColin Finck     }
1723c2c66affSColin Finck   else if (*pin == 't')
1724c2c66affSColin Finck     {
1725c2c66affSColin Finck       //if (*(ps-1) == 't') { *pout++ = ','; pin++; }       // this also got me...
1726c2c66affSColin Finck       //else                                                                                          october 12  .. sang
1727c2c66affSColin Finck       {
1728c2c66affSColin Finck 	*pout++ = '<';
1729c2c66affSColin Finck 	pin++;
1730c2c66affSColin Finck 	*ps++ = 't';
1731c2c66affSColin Finck       }
1732c2c66affSColin Finck       stringMode = FALSE;
1733c2c66affSColin Finck     }
1734c2c66affSColin Finck   else if (strncmp (pin, "xq", 2) == 0)
1735c2c66affSColin Finck     {
1736c2c66affSColin Finck       *pout++ = '(';
1737c2c66affSColin Finck       pin += 2;
1738c2c66affSColin Finck       *ps++ = 'x';
1739c2c66affSColin Finck       *ps++ = 'q';
1740c2c66affSColin Finck       stringMode = FALSE;
1741c2c66affSColin Finck     }
1742c2c66affSColin Finck   else if (strncmp (pin, "bcall", 5) == 0)
1743c2c66affSColin Finck     {
1744c2c66affSColin Finck       strcpy (pout, "operator ()");
1745c2c66affSColin Finck       pout += 11;
1746c2c66affSColin Finck       pin += 5;
1747c2c66affSColin Finck     }
1748c2c66affSColin Finck   else if (strncmp (pin, "bsubs", 5) == 0)
1749c2c66affSColin Finck     {
1750c2c66affSColin Finck       strcpy (pout, "operator []");
1751c2c66affSColin Finck       pout += 11;
1752c2c66affSColin Finck       pin += 5;
1753c2c66affSColin Finck     }
1754c2c66affSColin Finck   else if (strncmp (pin, "bnwa", 4) == 0)
1755c2c66affSColin Finck     {
1756c2c66affSColin Finck       strcpy (pout, "operator new[]");
1757c2c66affSColin Finck       pout += 14;
1758c2c66affSColin Finck       pin += 4;
1759c2c66affSColin Finck     }
1760c2c66affSColin Finck   else if (strncmp (pin, "bdla", 4) == 0)
1761c2c66affSColin Finck     {
1762c2c66affSColin Finck       strcpy (pout, "operator delete[]");
1763c2c66affSColin Finck       pout += 17;
1764c2c66affSColin Finck       pin += 4;
1765c2c66affSColin Finck     }
1766c2c66affSColin Finck   else if (strncmp (pin, "bnew", 4) == 0)
1767c2c66affSColin Finck     {
1768c2c66affSColin Finck       strcpy (pout, "operator new");
1769c2c66affSColin Finck       pout += 12;
1770c2c66affSColin Finck       pin += 4;
1771c2c66affSColin Finck     }
1772c2c66affSColin Finck   else if (strncmp (pin, "bdele", 5) == 0)
1773c2c66affSColin Finck     {
1774c2c66affSColin Finck       strcpy (pout, "operator delete");
1775c2c66affSColin Finck       pout += 15;
1776c2c66affSColin Finck       pin += 5;
1777c2c66affSColin Finck     }
1778c2c66affSColin Finck   else if (strncmp (pin, "blsh", 4) == 0)
1779c2c66affSColin Finck     {
1780c2c66affSColin Finck       strcpy (pout, "operator <<");
1781c2c66affSColin Finck       pout += 11;
1782c2c66affSColin Finck       pin += 4;
1783c2c66affSColin Finck     }
1784c2c66affSColin Finck   else if (strncmp (pin, "brsh", 4) == 0)
1785c2c66affSColin Finck     {
1786c2c66affSColin Finck       strcpy (pout, "operator >>");
1787c2c66affSColin Finck       pout += 11;
1788c2c66affSColin Finck       pin += 4;
1789c2c66affSColin Finck     }
1790c2c66affSColin Finck   else if (strncmp (pin, "binc", 4) == 0)
1791c2c66affSColin Finck     {
1792c2c66affSColin Finck       strcpy (pout, "operator ++");
1793c2c66affSColin Finck       pout += 11;
1794c2c66affSColin Finck       pin += 4;
1795c2c66affSColin Finck     }
1796c2c66affSColin Finck   else if (strncmp (pin, "bdec", 4) == 0)
1797c2c66affSColin Finck     {
1798c2c66affSColin Finck       strcpy (pout, "operator --");
1799c2c66affSColin Finck       pout += 11;
1800c2c66affSColin Finck       pin += 4;
1801c2c66affSColin Finck     }
1802c2c66affSColin Finck   else if (strncmp (pin, "badd", 4) == 0)
1803c2c66affSColin Finck     {
1804c2c66affSColin Finck       strcpy (pout, "operator +");
1805c2c66affSColin Finck       pout += 10;
1806c2c66affSColin Finck       pin += 4;
1807c2c66affSColin Finck     }
1808c2c66affSColin Finck   else if (strncmp (pin, "brplu", 5) == 0)
1809c2c66affSColin Finck     {
1810c2c66affSColin Finck       strcpy (pout, "operator +=");
1811c2c66affSColin Finck       pout += 11;
1812c2c66affSColin Finck       pin += 5;
1813c2c66affSColin Finck     }
1814c2c66affSColin Finck   else if (strncmp (pin, "bdiv", 4) == 0)
1815c2c66affSColin Finck     {
1816c2c66affSColin Finck       strcpy (pout, "operator /");
1817c2c66affSColin Finck       pout += 10;
1818c2c66affSColin Finck       pin += 4;
1819c2c66affSColin Finck     }
1820c2c66affSColin Finck   else if (strncmp (pin, "brdiv", 5) == 0)
1821c2c66affSColin Finck     {
1822c2c66affSColin Finck       strcpy (pout, "operator /=");
1823c2c66affSColin Finck       pout += 11;
1824c2c66affSColin Finck       pin += 5;
1825c2c66affSColin Finck     }
1826c2c66affSColin Finck   else if (strncmp (pin, "bmul", 4) == 0)
1827c2c66affSColin Finck     {
1828c2c66affSColin Finck       strcpy (pout, "operator *");
1829c2c66affSColin Finck       pout += 10;
1830c2c66affSColin Finck       pin += 4;
1831c2c66affSColin Finck     }
1832c2c66affSColin Finck   else if (strncmp (pin, "brmul", 5) == 0)
1833c2c66affSColin Finck     {
1834c2c66affSColin Finck       strcpy (pout, "operator *=");
1835c2c66affSColin Finck       pout += 11;
1836c2c66affSColin Finck       pin += 5;
1837c2c66affSColin Finck     }
1838c2c66affSColin Finck   else if (strncmp (pin, "basg", 4) == 0)
1839c2c66affSColin Finck     {
1840c2c66affSColin Finck       strcpy (pout, "operator =");
1841c2c66affSColin Finck       pout += 10;
1842c2c66affSColin Finck       pin += 4;
1843c2c66affSColin Finck     }
1844c2c66affSColin Finck   else if (strncmp (pin, "beql", 4) == 0)
1845c2c66affSColin Finck     {
1846c2c66affSColin Finck       strcpy (pout, "operator ==");
1847c2c66affSColin Finck       pout += 11;
1848c2c66affSColin Finck       pin += 4;
1849c2c66affSColin Finck     }
1850c2c66affSColin Finck   else if (strncmp (pin, "bneq", 4) == 0)
1851c2c66affSColin Finck     {
1852c2c66affSColin Finck       strcpy (pout, "operator !=");
1853c2c66affSColin Finck       pout += 11;
1854c2c66affSColin Finck       pin += 4;
1855c2c66affSColin Finck     }
1856c2c66affSColin Finck   else if (strncmp (pin, "bor", 3) == 0)
1857c2c66affSColin Finck     {
1858c2c66affSColin Finck       strcpy (pout, "operator |");
1859c2c66affSColin Finck       pout += 10;
1860c2c66affSColin Finck       pin += 3;
1861c2c66affSColin Finck     }
1862c2c66affSColin Finck   else if (strncmp (pin, "bror", 4) == 0)
1863c2c66affSColin Finck     {
1864c2c66affSColin Finck       strcpy (pout, "operator |=");
1865c2c66affSColin Finck       pout += 11;
1866c2c66affSColin Finck       pin += 4;
1867c2c66affSColin Finck     }
1868c2c66affSColin Finck   else if (strncmp (pin, "bcmp", 4) == 0)
1869c2c66affSColin Finck     {
1870c2c66affSColin Finck       strcpy (pout, "operator ~");
1871c2c66affSColin Finck       pout += 10;
1872c2c66affSColin Finck       pin += 4;
1873c2c66affSColin Finck     }
1874c2c66affSColin Finck   else if (strncmp (pin, "bnot", 4) == 0)
1875c2c66affSColin Finck     {
1876c2c66affSColin Finck       strcpy (pout, "operator !");
1877c2c66affSColin Finck       pout += 10;
1878c2c66affSColin Finck       pin += 4;
1879c2c66affSColin Finck     }
1880c2c66affSColin Finck   else if (strncmp (pin, "band", 4) == 0)
1881c2c66affSColin Finck     {
1882c2c66affSColin Finck       strcpy (pout, "operator &");
1883c2c66affSColin Finck       pout += 10;
1884c2c66affSColin Finck       pin += 4;
1885c2c66affSColin Finck     }
1886c2c66affSColin Finck   else if (strncmp (pin, "brand", 5) == 0)
1887c2c66affSColin Finck     {
1888c2c66affSColin Finck       strcpy (pout, "operator &=");
1889c2c66affSColin Finck       pout += 11;
1890c2c66affSColin Finck       pin += 5;
1891c2c66affSColin Finck     }
1892c2c66affSColin Finck   else if (strncmp (pin, "bxor", 4) == 0)
1893c2c66affSColin Finck     {
1894c2c66affSColin Finck       strcpy (pout, "operator ^");
1895c2c66affSColin Finck       pout += 10;
1896c2c66affSColin Finck       pin += 4;
1897c2c66affSColin Finck     }
1898c2c66affSColin Finck   else if (strncmp (pin, "brxor", 5) == 0)
1899c2c66affSColin Finck     {
1900c2c66affSColin Finck       strcpy (pout, "operator ^=");
1901c2c66affSColin Finck       pout += 11;
1902c2c66affSColin Finck       pin += 5;
1903c2c66affSColin Finck     }
1904c2c66affSColin Finck   else
1905c2c66affSColin Finck     {
1906c2c66affSColin Finck       strcpy (pout, "!$$$!");
1907c2c66affSColin Finck       pout += 5;
1908c2c66affSColin Finck     }
1909c2c66affSColin Finck   *ppin = pin;
1910c2c66affSColin Finck   *ppout = pout;
1911c2c66affSColin Finck   *pps = ps;
1912c2c66affSColin Finck   return stringMode;
1913c2c66affSColin Finck }				// end of '$' processing
1914c2c66affSColin Finck 
1915c2c66affSColin Finck 
1916c2c66affSColin Finck 
1917c2c66affSColin Finck //----------------------------------------------------------------------
1918c2c66affSColin Finck // structure to store string tokens
1919c2c66affSColin Finck //----------------------------------------------------------------------
1920c2c66affSColin Finck //typedef struct _Str_P {
1921c2c66affSColin Finck //    char    flag;               // string_flag '@' or '%' or '#'
1922c2c66affSColin Finck //    char    *pos;               // starting postion of string
1923c2c66affSColin Finck //    int     length;     // length of string
1924c2c66affSColin Finck //      BOOL    wasString;    // if it were stringMode or not
1925c2c66affSColin Finck //} Str_P;
1926c2c66affSColin Finck //----------------------------------------------------------------------
1927c2c66affSColin Finck //
1928c2c66affSColin Finck // I think I knocked it down finally. But who knows?
1929c2c66affSColin Finck //                            october 12, 1997 ... sang
1930c2c66affSColin Finck //
1931c2c66affSColin Finck // well I have to rewrite whole part of TranslateFunctionName..
1932c2c66affSColin Finck // this time I am a little bit more experienced than 5 days ago.
1933c2c66affSColin Finck // or am i??? anyway i use stacks instead of recurcive calls
1934c2c66affSColin Finck // and i hope this will take care of every symptoms i have experienced..
1935c2c66affSColin Finck //                                                        october 10, 1997 .... sang
1936c2c66affSColin Finck // It took a lot of time for me to figure out what is all about....
1937c2c66affSColin Finck // but still some prefixes like z (static)
1938c2c66affSColin Finck //     -- or some types like b (byte) ,g (long double) ,s (short) --
1939c2c66affSColin Finck //         -- or postfix  like M ( * )
1940c2c66affSColin Finck //     -- or $or ( & ) which is pretty wierd.         .. added.. october 12
1941c2c66affSColin Finck //     -- also $t business is quite tricky too. (templates)
1942c2c66affSColin Finck //             there may be a lot of things undiscovered yet....
1943c2c66affSColin Finck // I am not so sure my interpretation is correct or not
1944c2c66affSColin Finck // If I am wrong please let me know.
1945c2c66affSColin Finck //                             october 8, 1997 .... sang
1946c2c66affSColin Finck //
1947c2c66affSColin Finck //
1948c2c66affSColin Finck // This function is written by sang cho
1949c2c66affSColin Finck //                                                         October 5, 1997
1950c2c66affSColin Finck //
1951c2c66affSColin Finck /* translate condesed import function name */
1952c2c66affSColin Finck char * WINAPI
TranslateFunctionName(char * psz)1953c2c66affSColin Finck TranslateFunctionName (
1954c2c66affSColin Finck 			char *psz)
1955c2c66affSColin Finck {
1956c2c66affSColin Finck 
1957c2c66affSColin Finck 
1958c2c66affSColin Finck   int i, /*j,*/ n;
1959c2c66affSColin Finck   char c = 0;
1960c2c66affSColin Finck   char cc;
1961c2c66affSColin Finck 
1962c2c66affSColin Finck   static char buff[512];	// result of translation
1963c2c66affSColin Finck 
1964c2c66affSColin Finck   int is = 0;
1965c2c66affSColin Finck   char pStack[32];		// parameter processing stack
1966c2c66affSColin Finck 
1967c2c66affSColin Finck   Str_P sStack[32];		// String processing stack
1968c2c66affSColin Finck 
1969c2c66affSColin Finck   Str_P tok;			// String token
1970c2c66affSColin Finck 
1971c2c66affSColin Finck   Str_P c_str;			// current string
1972c2c66affSColin Finck 
1973c2c66affSColin Finck   int iend = 0;
1974c2c66affSColin Finck   char *endTab[8];		// end of string position check
1975c2c66affSColin Finck 
1976c2c66affSColin Finck   char *ps;
1977c2c66affSColin Finck   char *pin, *pout;
1978c2c66affSColin Finck   BOOL stringMode = TRUE;
1979c2c66affSColin Finck 
1980c2c66affSColin Finck   if (*psz != '@')
1981c2c66affSColin Finck     return psz;
1982c2c66affSColin Finck   pin = psz;
1983c2c66affSColin Finck   pout = buff;
1984c2c66affSColin Finck   ps = pStack;
1985c2c66affSColin Finck 
1986c2c66affSColin Finck   //................................................................
1987c2c66affSColin Finck   // serious users may need to run the following code.
1988c2c66affSColin Finck   // so I may need to include some flag options...
1989c2c66affSColin Finck   // If you want to know about how translation is done,
1990c2c66affSColin Finck   // you can just revive following line and you can see it.
1991c2c66affSColin Finck   //                                                 october 6, 1997 ... sang cho
1992c2c66affSColin Finck   //printf ("\n................................... %s", psz); // for debugging...
1993c2c66affSColin Finck 
1994c2c66affSColin Finck   //pa = pb = pout;
1995c2c66affSColin Finck   pin++;
1996c2c66affSColin Finck   tok.flag = 'A';
1997c2c66affSColin Finck   tok.pos = pout;
1998c2c66affSColin Finck   tok.length = 0;
1999c2c66affSColin Finck   tok.wasString = stringMode;
2000c2c66affSColin Finck   sStack[is++] = tok;		// initialize sStack with dummy marker
2001c2c66affSColin Finck 
2002c2c66affSColin Finck   while (*pin)
2003c2c66affSColin Finck     {
2004c2c66affSColin Finck       while (*pin)
2005c2c66affSColin Finck 	{
2006c2c66affSColin Finck 	  c = *pin;
2007c2c66affSColin Finck 
2008c2c66affSColin Finck 	  //---------------------------------------------
2009c2c66affSColin Finck 	  // check for the end of number specified string
2010c2c66affSColin Finck 	  //---------------------------------------------
2011c2c66affSColin Finck 
2012c2c66affSColin Finck 	  if (iend > 0)
2013c2c66affSColin Finck 	    {
2014c2c66affSColin Finck 	      for (i = 0; i < iend; i++)
2015c2c66affSColin Finck 		if (pin == endTab[i])
2016c2c66affSColin Finck 		  break;
2017c2c66affSColin Finck 	      if (i < iend)
2018c2c66affSColin Finck 		{
2019c2c66affSColin Finck 		  // move the end of endTab to ith position
2020c2c66affSColin Finck 		  endTab[i] = endTab[iend - 1];
2021c2c66affSColin Finck 		  iend--;
2022c2c66affSColin Finck 
2023c2c66affSColin Finck 		  // get top of the string stack
2024c2c66affSColin Finck 		  tok = sStack[is - 1];
2025c2c66affSColin Finck 
2026c2c66affSColin Finck 		  // I am expecting '#' token from stack
2027c2c66affSColin Finck 		  if (tok.flag != '#')
2028c2c66affSColin Finck 
2029c2c66affSColin Finck 		    {
2030c2c66affSColin Finck 		      printf ("\n**some serious error1** %c is = %d char = %c",
2031c2c66affSColin Finck 			      tok.flag, is, *pin);
2032c2c66affSColin Finck 		      exit (0);
2033c2c66affSColin Finck 		    }
2034c2c66affSColin Finck 
2035c2c66affSColin Finck 		  // pop '#' token  I am happy now.
2036c2c66affSColin Finck 		  else
2037c2c66affSColin Finck 		    {		//if (c)
2038c2c66affSColin Finck 		      //printf("\n pop # token ... current char = %c", c);
2039c2c66affSColin Finck 		      //else printf("\n pop percent token..next char = NULL");
2040c2c66affSColin Finck 
2041c2c66affSColin Finck 		      is--;
2042c2c66affSColin Finck 		    }
2043c2c66affSColin Finck 
2044c2c66affSColin Finck 		  stringMode = tok.wasString;
2045c2c66affSColin Finck 
2046c2c66affSColin Finck 		  if (!stringMode)
2047c2c66affSColin Finck 		    {
2048c2c66affSColin Finck 		      // need to process postfix finally
2049c2c66affSColin Finck 		      cc = *(ps - 1);
2050c2c66affSColin Finck 		      if (strchr ("qtx", cc))
2051c2c66affSColin Finck 			{
2052c2c66affSColin Finck 			  if (!strchr ("@$%", c))
2053c2c66affSColin Finck 			    *pout++ = ',';
2054c2c66affSColin Finck 			}
2055c2c66affSColin Finck 		      else
2056c2c66affSColin Finck 			{
2057c2c66affSColin Finck 			  switch (cc)
2058c2c66affSColin Finck 			    {
2059c2c66affSColin Finck 			    case 'r':
2060c2c66affSColin Finck 			      strcpy (pout, "*&");
2061c2c66affSColin Finck 			      pout += 2;
2062c2c66affSColin Finck 			      ps--;
2063c2c66affSColin Finck 			      break;
2064c2c66affSColin Finck 			    case 'p':
2065c2c66affSColin Finck 			      strcpy (pout, "**");
2066c2c66affSColin Finck 			      pout += 2;
2067c2c66affSColin Finck 			      ps--;
2068c2c66affSColin Finck 			      break;
2069c2c66affSColin Finck 			    case '&':
2070c2c66affSColin Finck 			      strcpy (pout, "&");
2071c2c66affSColin Finck 			      pout += 1;
2072c2c66affSColin Finck 			      ps--;
2073c2c66affSColin Finck 			      break;
2074c2c66affSColin Finck 			    case '*':
2075c2c66affSColin Finck 			      strcpy (pout, "*");
2076c2c66affSColin Finck 			      pout += 1;
2077c2c66affSColin Finck 			      ps--;
2078c2c66affSColin Finck 			      break;
2079c2c66affSColin Finck 			    default:
2080c2c66affSColin Finck 			      strcpy (pout, "!3!");
2081c2c66affSColin Finck 			      pout += 3;
2082c2c66affSColin Finck 			      ps--;
2083c2c66affSColin Finck 			      break;
2084c2c66affSColin Finck 			    }
2085c2c66affSColin Finck 			  if (!strchr ("@$%", c))
2086c2c66affSColin Finck 			    *pout++ = ',';
2087c2c66affSColin Finck 			}
2088c2c66affSColin Finck 		    }
2089c2c66affSColin Finck 		  // string mode restored...
2090c2c66affSColin Finck 		  else;
2091c2c66affSColin Finck 		}
2092c2c66affSColin Finck 	      else;		// do nothing..
2093c2c66affSColin Finck 
2094c2c66affSColin Finck 	    }
2095c2c66affSColin Finck 
2096c2c66affSColin Finck 	  //------------------------------------------------
2097c2c66affSColin Finck 	  // special control symbol processing:
2098c2c66affSColin Finck 	  //------------------------------------------------
2099c2c66affSColin Finck 
2100c2c66affSColin Finck 	  if (strchr ("@$%", c))
2101c2c66affSColin Finck 	    break;
2102c2c66affSColin Finck 
2103c2c66affSColin Finck 	  //---------------------------------------------------------------
2104c2c66affSColin Finck 	  // string part processing : no '$' met yet
2105c2c66affSColin Finck 	  //                       or inside of '%' block
2106c2c66affSColin Finck 	  //                       or inside of '#' block (numbered string)
2107c2c66affSColin Finck 	  //---------------------------------------------------------------
2108c2c66affSColin Finck 
2109c2c66affSColin Finck 	  else if (stringMode)
2110c2c66affSColin Finck 	    *pout++ = *pin++;
2111c2c66affSColin Finck 	  //else if (is > 1)         *pout++ = *pin++;
2112c2c66affSColin Finck 
2113c2c66affSColin Finck 	  //------------------------------------------------
2114c2c66affSColin Finck 	  // parameter part processing: '$' met
2115c2c66affSColin Finck 	  //------------------------------------------------
2116c2c66affSColin Finck 
2117c2c66affSColin Finck 	  else			// parameter processing
2118c2c66affSColin Finck 
2119c2c66affSColin Finck 	    {
2120c2c66affSColin Finck 	      if (!isdigit (c))
2121c2c66affSColin Finck 		TranslateParameters (&pin, &pout, &ps);
2122c2c66affSColin Finck 	      else		// number specified string processing
2123c2c66affSColin Finck 
2124c2c66affSColin Finck 		{
2125c2c66affSColin Finck 		  n = GetStringLength (pin);
2126c2c66affSColin Finck 		  if (n < 10)
2127c2c66affSColin Finck 		    pin++;
2128c2c66affSColin Finck 		  else
2129c2c66affSColin Finck 		    pin += 2;
2130c2c66affSColin Finck 
2131c2c66affSColin Finck 		  // push '#' token
2132c2c66affSColin Finck 		  //if (*pin)
2133c2c66affSColin Finck 		  //printf("\n push # token .. char = %c", *pin);
2134c2c66affSColin Finck 		  //else printf("\n push percent token..next char = NULL");
2135c2c66affSColin Finck 		  tok.flag = '#';
2136c2c66affSColin Finck 		  tok.pos = pout;
2137c2c66affSColin Finck 		  tok.length = 0;
2138c2c66affSColin Finck 		  tok.wasString = stringMode;
2139c2c66affSColin Finck 		  sStack[is++] = tok;
2140c2c66affSColin Finck 
2141c2c66affSColin Finck 		  // mark end of input string
2142c2c66affSColin Finck 		  endTab[iend++] = pin + n;
2143c2c66affSColin Finck 		  stringMode = TRUE;
2144c2c66affSColin Finck 		}
2145c2c66affSColin Finck 	    }
2146c2c66affSColin Finck 	}			// end of inner while loop
2147c2c66affSColin Finck       //
2148c2c66affSColin Finck       // beginning of new string or end of string ( quotation mark )
2149c2c66affSColin Finck       //
2150c2c66affSColin Finck 
2151c2c66affSColin Finck       if (c == '%')
2152c2c66affSColin Finck 	{
2153c2c66affSColin Finck 	  pin++;		// anyway we have to proceed...
2154c2c66affSColin Finck 
2155c2c66affSColin Finck 	  tok = sStack[is - 1];	// get top of the sStack
2156c2c66affSColin Finck 
2157c2c66affSColin Finck 	  if (tok.flag == '%')
2158c2c66affSColin Finck 	    {
2159c2c66affSColin Finck 	      // pop '%' token and set c_str
2160c2c66affSColin Finck 	      //if (*pin)
2161c2c66affSColin Finck 	      //printf("\n pop percent token..next char = %c", *pin);
2162c2c66affSColin Finck 	      //else printf("\n pop percent token..next char = NULL");
2163c2c66affSColin Finck 	      is--;
2164c2c66affSColin Finck 	      c_str = tok;
2165c2c66affSColin Finck 	      c_str.length = pout - c_str.pos;
2166c2c66affSColin Finck 	      if (*(ps - 1) == 't')
2167c2c66affSColin Finck 		{
2168c2c66affSColin Finck 		  *pout++ = '>';
2169c2c66affSColin Finck 		  ps--;
2170c2c66affSColin Finck 		  stringMode = tok.wasString;
2171c2c66affSColin Finck 		}
2172c2c66affSColin Finck 	      else
2173c2c66affSColin Finck 		{
2174c2c66affSColin Finck 		  printf ("\n**some string error3** stack = %c", *(ps - 1));
2175c2c66affSColin Finck 		  exit (0);
2176c2c66affSColin Finck 		}
2177c2c66affSColin Finck 	    }
2178c2c66affSColin Finck 	  else if (tok.flag == 'A' || tok.flag == '#')
2179c2c66affSColin Finck 	    {
2180c2c66affSColin Finck 	      // push '%' token
2181c2c66affSColin Finck 	      //if (*pin)
2182c2c66affSColin Finck 	      //printf("\n push percent token..next char = %c", *pin);
2183c2c66affSColin Finck 	      //else printf("\n push percent token..next char = NULL");
2184c2c66affSColin Finck 	      tok.flag = '%';
2185c2c66affSColin Finck 	      tok.pos = pout;
2186c2c66affSColin Finck 	      tok.length = 0;
2187c2c66affSColin Finck 	      tok.wasString = stringMode;
2188c2c66affSColin Finck 	      sStack[is++] = tok;
2189c2c66affSColin Finck 	    }
2190c2c66affSColin Finck 	  else
2191c2c66affSColin Finck 	    {
2192c2c66affSColin Finck 	      printf ("\n**some string error5**");
2193c2c66affSColin Finck 	      exit (0);
2194c2c66affSColin Finck 	    }
2195c2c66affSColin Finck 	}
2196c2c66affSColin Finck       //
2197c2c66affSColin Finck       // sometimes we need string to use as constructor name or destructor name
2198c2c66affSColin Finck       //
2199c2c66affSColin Finck       else if (c == '@')	// get string from previous marker  upto here.
2200c2c66affSColin Finck 
2201c2c66affSColin Finck 	{
2202c2c66affSColin Finck 	  pin++;
2203c2c66affSColin Finck 	  tok = sStack[is - 1];
2204c2c66affSColin Finck 	  c_str.flag = 'S';
2205c2c66affSColin Finck 	  c_str.pos = tok.pos;
2206c2c66affSColin Finck 	  c_str.length = pout - tok.pos;
2207c2c66affSColin Finck 	  c_str.wasString = stringMode;
2208c2c66affSColin Finck 	  *pout++ = ':';
2209c2c66affSColin Finck 	  *pout++ = ':';
2210c2c66affSColin Finck 	}
2211c2c66affSColin Finck       //
2212c2c66affSColin Finck       // we need to take care of parameter control sequence
2213c2c66affSColin Finck       //
2214c2c66affSColin Finck       else if (c == '$')	// need to precess template or parameter part
2215c2c66affSColin Finck 
2216c2c66affSColin Finck 	{
2217c2c66affSColin Finck 	  pin++;
2218c2c66affSColin Finck 	  if (stringMode)
2219c2c66affSColin Finck 	    stringMode = StringExpands (&pin, &pout, &ps, &c_str);
2220c2c66affSColin Finck 	  else
2221c2c66affSColin Finck 	    {			// template parameter mode I guess  "$t"
2222c2c66affSColin Finck 
2223c2c66affSColin Finck 	      if (is > 1)
2224c2c66affSColin Finck 		{
2225c2c66affSColin Finck 		  if (*pin == 't')
2226c2c66affSColin Finck 		    pin++;
2227c2c66affSColin Finck 		  else
2228c2c66affSColin Finck 		    {
2229c2c66affSColin Finck 		      printf ("\nMYGOODNESS1 %c", *pin);
2230c2c66affSColin Finck 		      exit (0);
2231c2c66affSColin Finck 		    }
2232c2c66affSColin Finck 		  //ps--;
2233c2c66affSColin Finck 		  //if (*ps == 't') *pout++ = '>';
2234c2c66affSColin Finck 		  //else { printf("\nMYGOODNESS2"); exit(0);}
2235c2c66affSColin Finck 		  *pout++ = ',';	//pin++; ..this almost blowed me....
2236c2c66affSColin Finck 
2237c2c66affSColin Finck 		}
2238c2c66affSColin Finck 	      // real parameter mode I guess
2239c2c66affSColin Finck 	      // unexpected case is found ... humm what can I do...
2240c2c66affSColin Finck 	      else
2241c2c66affSColin Finck 		{
2242c2c66affSColin Finck 		  // this is newly found twist.. it really hurts.
2243c2c66affSColin Finck 		  if (ps <= pStack)
2244c2c66affSColin Finck 		    {
2245c2c66affSColin Finck 		      if (*pin == 'q')
2246c2c66affSColin Finck 			{
2247c2c66affSColin Finck 			  *ps++ = 'q';
2248c2c66affSColin Finck 			  *pout++ = '(';
2249c2c66affSColin Finck 			  pin++;
2250c2c66affSColin Finck 			}
2251c2c66affSColin Finck 		      else
2252c2c66affSColin Finck 			{
2253c2c66affSColin Finck 			  printf ("\n** I GIVEUP ***");
2254c2c66affSColin Finck 			  exit (0);
2255c2c66affSColin Finck 			}
2256c2c66affSColin Finck 		      continue;
2257c2c66affSColin Finck 		    }
2258c2c66affSColin Finck 		  ps--;
2259c2c66affSColin Finck 		  while (*ps != 'q')
2260c2c66affSColin Finck 		    {
2261c2c66affSColin Finck 		      if (*ps == '*')
2262c2c66affSColin Finck 			*pout++ = '*';
2263c2c66affSColin Finck 		      else if (*ps == '&')
2264c2c66affSColin Finck 			*pout++ = '&';
2265c2c66affSColin Finck 		      else if (*ps == 'p')
2266c2c66affSColin Finck 			{
2267c2c66affSColin Finck 			  *pout++ = '*';
2268c2c66affSColin Finck 			  *pout++ = '*';
2269c2c66affSColin Finck 			}
2270c2c66affSColin Finck 		      else if (*ps == 'r')
2271c2c66affSColin Finck 			{
2272c2c66affSColin Finck 			  *pout++ = '*';
2273c2c66affSColin Finck 			  *pout++ = '&';
2274c2c66affSColin Finck 			}
2275c2c66affSColin Finck 		      else
2276c2c66affSColin Finck 			{
2277c2c66affSColin Finck 			  printf ("\n*** SOMETHING IS WRONG1*** char= %c", *pin);
2278c2c66affSColin Finck 			  exit (0);
2279c2c66affSColin Finck 			}
2280c2c66affSColin Finck 		      ps--;
2281c2c66affSColin Finck 		    }
2282c2c66affSColin Finck 		  *pout++ = ')';
2283c2c66affSColin Finck 		  ps--;
2284c2c66affSColin Finck 		  while (*ps != 'q')
2285c2c66affSColin Finck 		    {
2286c2c66affSColin Finck 		      if (*ps == '*')
2287c2c66affSColin Finck 			*pout++ = '*';
2288c2c66affSColin Finck 		      else if (*ps == '&')
2289c2c66affSColin Finck 			*pout++ = '&';
2290c2c66affSColin Finck 		      else if (*ps == 'p')
2291c2c66affSColin Finck 			{
2292c2c66affSColin Finck 			  *pout++ = '*';
2293c2c66affSColin Finck 			  *pout++ = '*';
2294c2c66affSColin Finck 			}
2295c2c66affSColin Finck 		      else if (*ps == 'r')
2296c2c66affSColin Finck 			{
2297c2c66affSColin Finck 			  *pout++ = '*';
2298c2c66affSColin Finck 			  *pout++ = '&';
2299c2c66affSColin Finck 			}
2300c2c66affSColin Finck 		      else
2301c2c66affSColin Finck 			{
2302c2c66affSColin Finck 			  printf ("\n*** SOMETHING IS WRONG2***");
2303c2c66affSColin Finck 			  exit (0);
2304c2c66affSColin Finck 			}
2305c2c66affSColin Finck 		      ps--;
2306c2c66affSColin Finck 		    }
2307c2c66affSColin Finck 		  ps++;
2308c2c66affSColin Finck 		  *pout++ = ',';
2309c2c66affSColin Finck 		}
2310c2c66affSColin Finck 	    }
2311c2c66affSColin Finck 	}			// end of '$' processing
2312c2c66affSColin Finck 
2313c2c66affSColin Finck     }				// end of outer while loop
2314c2c66affSColin Finck   //
2315c2c66affSColin Finck   // need to process remaining parameter stack
2316c2c66affSColin Finck   //
2317c2c66affSColin Finck 
2318c2c66affSColin Finck   while (ps > pStack)
2319c2c66affSColin Finck     {
2320c2c66affSColin Finck       ps--;
2321c2c66affSColin Finck       switch (*ps)
2322c2c66affSColin Finck 	{
2323c2c66affSColin Finck 	case 't':
2324c2c66affSColin Finck 	  *pout++ = '>';
2325c2c66affSColin Finck 	  break;
2326c2c66affSColin Finck 	case 'q':
2327c2c66affSColin Finck 	  *pout++ = ')';
2328c2c66affSColin Finck 	  break;
2329c2c66affSColin Finck 	case 'x':
2330c2c66affSColin Finck 	  strcpy (pout, " const");
2331c2c66affSColin Finck 	  pout += 6;
2332c2c66affSColin Finck 	  break;
2333c2c66affSColin Finck 	case 'r':
2334c2c66affSColin Finck 	  strcpy (pout, "*&");
2335c2c66affSColin Finck 	  pout += 2;
2336c2c66affSColin Finck 	  break;
2337c2c66affSColin Finck 	case 'p':
2338c2c66affSColin Finck 	  strcpy (pout, "**");
2339c2c66affSColin Finck 	  pout += 2;
2340c2c66affSColin Finck 	  break;
2341c2c66affSColin Finck 	case '&':
2342c2c66affSColin Finck 	  *pout++ = '&';
2343c2c66affSColin Finck 	  break;
2344c2c66affSColin Finck 	case '*':
2345c2c66affSColin Finck 	  *pout++ = '*';
2346c2c66affSColin Finck 	  break;
2347c2c66affSColin Finck 	default:
2348c2c66affSColin Finck 	  strcpy (pout, "!4!");
2349c2c66affSColin Finck 	  pout += 3;
2350c2c66affSColin Finck 	  *pout++ = *ps;
2351c2c66affSColin Finck 	}
2352c2c66affSColin Finck     }
2353c2c66affSColin Finck   *pout = 0;
2354c2c66affSColin Finck   return buff;
2355c2c66affSColin Finck }
2356c2c66affSColin Finck 
2357c2c66affSColin Finck 
2358c2c66affSColin Finck 
2359c2c66affSColin Finck //
2360c2c66affSColin Finck // This function is written by sang cho
2361c2c66affSColin Finck //
2362c2c66affSColin Finck //
2363c2c66affSColin Finck /* get exported function names separated by null terminators, return count of functions */
2364c2c66affSColin Finck int WINAPI
GetExportFunctionNames(LPVOID lpFile,char ** pszFunctions)2365c2c66affSColin Finck GetExportFunctionNames (
2366c2c66affSColin Finck 			 LPVOID lpFile,
2367c2c66affSColin Finck 			 char **pszFunctions)
2368c2c66affSColin Finck {
2369c2c66affSColin Finck   //PIMAGE_SECTION_HEADER      psh;
2370c2c66affSColin Finck   PIMAGE_EXPORT_DIRECTORY ped;
2371c2c66affSColin Finck   //DWORD                      dwBase;
2372c2c66affSColin Finck   DWORD imageBase;		//===========================
2373c2c66affSColin Finck 
2374c2c66affSColin Finck   char *pfns[8192] =
2375c2c66affSColin Finck   {NULL,};			// maximum number of functions
2376c2c66affSColin Finck   //=============================
2377c2c66affSColin Finck 
2378c2c66affSColin Finck   char buff[256];		// enough for any string ??
2379c2c66affSColin Finck 
2380c2c66affSColin Finck   char *psz = NULL;			//===============================
2381c2c66affSColin Finck 
2382c2c66affSColin Finck   DWORD *pdwAddress;
2383c2c66affSColin Finck   DWORD *pdw1;
2384c2c66affSColin Finck   DWORD *pdwNames;
2385c2c66affSColin Finck   WORD *pwOrd;
2386c2c66affSColin Finck   int i, nCnt = 0, ntmp = 0;
2387c2c66affSColin Finck   int enid = 0, ordBase = 1;	// usally ordBase is 1....
2388c2c66affSColin Finck 
2389c2c66affSColin Finck   int enames = 0;
2390c2c66affSColin Finck 
2391c2c66affSColin Finck   /* get section header and pointer to data directory for .edata section */
2392c2c66affSColin Finck   ped = (PIMAGE_EXPORT_DIRECTORY)
2393c2c66affSColin Finck     ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2394c2c66affSColin Finck 
2395c2c66affSColin Finck   if (ped == NULL)
2396c2c66affSColin Finck     return 0;
2397c2c66affSColin Finck 
2398c2c66affSColin Finck   //
2399c2c66affSColin Finck   // sometimes there may be no section for idata or edata
2400c2c66affSColin Finck   // instead rdata or data section may contain these sections ..
2401c2c66affSColin Finck   // or even module names or function names are in different section.
2402c2c66affSColin Finck   // so that's why we need to get actual address each time.
2403c2c66affSColin Finck   //         ...................sang cho..................
2404c2c66affSColin Finck   //
2405c2c66affSColin Finck   //psh = (PIMAGE_SECTION_HEADER)
2406c2c66affSColin Finck   //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2407c2c66affSColin Finck 
2408c2c66affSColin Finck   //if (psh == NULL) return 0;
2409c2c66affSColin Finck 
2410c2c66affSColin Finck   //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2411c2c66affSColin Finck 
2412c2c66affSColin Finck 
2413c2c66affSColin Finck   /* determine the offset of the export function names */
2414c2c66affSColin Finck 
2415c2c66affSColin Finck   pdwAddress = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfFunctions);
2416c2c66affSColin Finck 
2417c2c66affSColin Finck   imageBase = (DWORD) GetImageBase (lpFile);
2418c2c66affSColin Finck 
2419c2c66affSColin Finck   ordBase = ped->Base;
2420c2c66affSColin Finck 
2421c2c66affSColin Finck   if (ped->NumberOfNames > 0)
2422c2c66affSColin Finck     {
2423c2c66affSColin Finck       pdwNames = (DWORD *)
2424c2c66affSColin Finck 	GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2425c2c66affSColin Finck       pwOrd = (WORD *)
2426c2c66affSColin Finck 	GetActualAddress (lpFile, (DWORD) ped->AddressOfNameOrdinals);
2427c2c66affSColin Finck       pdw1 = pdwAddress;
2428c2c66affSColin Finck 
2429c2c66affSColin Finck       /* figure out how much memory to allocate for all strings */
2430c2c66affSColin Finck       for (i = 0; i < (int) ped->NumberOfNames; i++)
2431c2c66affSColin Finck 	{
2432c2c66affSColin Finck 	  nCnt += strlen ((char *)
2433c2c66affSColin Finck 		    GetActualAddress (lpFile, *(DWORD *) pdwNames)) + 1 + 6;
2434c2c66affSColin Finck 	  pdwNames++;
2435c2c66affSColin Finck 	}
2436c2c66affSColin Finck       // get the number of unnamed functions
2437c2c66affSColin Finck       for (i = 0; i < (int) ped->NumberOfFunctions; i++)
2438c2c66affSColin Finck 	if (*pdw1++)
2439c2c66affSColin Finck 	  ntmp++;
2440c2c66affSColin Finck       // add memory required to show unnamed functions.
2441c2c66affSColin Finck       if (ntmp > (int) ped->NumberOfNames)
2442c2c66affSColin Finck 	nCnt += 18 * (ntmp - (int) ped->NumberOfNames);
2443c2c66affSColin Finck 
2444c2c66affSColin Finck       /* allocate memory  for function names */
2445c2c66affSColin Finck 
2446c2c66affSColin Finck       *pszFunctions = (char *) calloc (nCnt, 1);
2447c2c66affSColin Finck       pdwNames = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2448c2c66affSColin Finck 
2449c2c66affSColin Finck       /* copy string pointer to buffer */
2450c2c66affSColin Finck 
2451c2c66affSColin Finck       for (i = 0; i < (int) ped->NumberOfNames; i++)
2452c2c66affSColin Finck 	{
2453c2c66affSColin Finck 	  pfns[(int) (*pwOrd) + ordBase] =
2454c2c66affSColin Finck 	    (char *) GetActualAddress (lpFile, *(DWORD *) pdwNames);
2455c2c66affSColin Finck 	  pdwNames++;
2456c2c66affSColin Finck 	  pwOrd++;
2457c2c66affSColin Finck 	}
2458c2c66affSColin Finck 
2459c2c66affSColin Finck       psz = *pszFunctions;
2460c2c66affSColin Finck     }
2461c2c66affSColin Finck 
2462c2c66affSColin Finck   for (i = ordBase; i < (int) ped->NumberOfFunctions + ordBase; i++)
2463c2c66affSColin Finck     {
2464c2c66affSColin Finck       if (*pdwAddress > 0)
2465c2c66affSColin Finck 	{
2466c2c66affSColin Finck 	  *(DWORD *) psz = imageBase + *pdwAddress;
2467c2c66affSColin Finck 	  psz += 4;
2468c2c66affSColin Finck 	  *(WORD *) psz = (WORD) (i);
2469c2c66affSColin Finck 	  psz += 2;
2470c2c66affSColin Finck 	  if (pfns[i])
2471c2c66affSColin Finck 	    {
2472c2c66affSColin Finck 	      strcpy (psz, pfns[i]);
2473c2c66affSColin Finck 	      psz += strlen (psz) + 1;
2474c2c66affSColin Finck 	    }
2475c2c66affSColin Finck 	  else
2476c2c66affSColin Finck 	    {
2477c2c66affSColin Finck 	      sprintf (buff, "ExpFn%04d()", enid++);
2478c2c66affSColin Finck 	      strcpy (psz, buff);
2479c2c66affSColin Finck 	      psz += 12;
2480c2c66affSColin Finck 	    }
2481c2c66affSColin Finck 	  enames++;
2482c2c66affSColin Finck 	}
2483c2c66affSColin Finck       pdwAddress++;
2484c2c66affSColin Finck     }
2485c2c66affSColin Finck 
2486c2c66affSColin Finck   return enames;
2487c2c66affSColin Finck 
2488c2c66affSColin Finck }
2489c2c66affSColin Finck 
2490c2c66affSColin Finck 
2491c2c66affSColin Finck /* determine the total number of resources in the section */
2492c2c66affSColin Finck int WINAPI
GetNumberOfResources(LPVOID lpFile)2493c2c66affSColin Finck GetNumberOfResources (
2494c2c66affSColin Finck 		       LPVOID lpFile)
2495c2c66affSColin Finck {
2496c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY prdRoot, prdType;
2497c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2498c2c66affSColin Finck   int nCnt = 0, i;
2499c2c66affSColin Finck 
2500c2c66affSColin Finck 
2501c2c66affSColin Finck   /* get root directory of resource tree */
2502c2c66affSColin Finck   if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2503c2c66affSColin Finck        (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2504c2c66affSColin Finck     return 0;
2505c2c66affSColin Finck 
2506c2c66affSColin Finck   /* set pointer to first resource type entry */
2507c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2508c2c66affSColin Finck 
2509c2c66affSColin Finck   /* loop through all resource directory entry types */
2510c2c66affSColin Finck   for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2511c2c66affSColin Finck     {
2512c2c66affSColin Finck       /* locate directory or each resource type */
2513c2c66affSColin Finck       prdType = (PIMAGE_RESOURCE_DIRECTORY) ((int) prdRoot + (int) prde->OffsetToData);
2514c2c66affSColin Finck 
2515c2c66affSColin Finck       /* mask off most significant bit of the data offset */
2516c2c66affSColin Finck       prdType = (PIMAGE_RESOURCE_DIRECTORY) ((DWORD) prdType ^ 0x80000000);
2517c2c66affSColin Finck 
2518c2c66affSColin Finck       /* increment count of name'd and ID'd resources in directory */
2519c2c66affSColin Finck       nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
2520c2c66affSColin Finck 
2521c2c66affSColin Finck       /* increment to next entry */
2522c2c66affSColin Finck       prde++;
2523c2c66affSColin Finck     }
2524c2c66affSColin Finck 
2525c2c66affSColin Finck   return nCnt;
2526c2c66affSColin Finck }
2527c2c66affSColin Finck 
2528c2c66affSColin Finck 
2529c2c66affSColin Finck 
2530c2c66affSColin Finck //
2531c2c66affSColin Finck // This function is rewritten by sang cho
2532c2c66affSColin Finck //
2533c2c66affSColin Finck //
2534c2c66affSColin Finck /* name each type of resource in the section */
2535c2c66affSColin Finck int WINAPI
GetListOfResourceTypes(LPVOID lpFile,char ** pszResTypes)2536c2c66affSColin Finck GetListOfResourceTypes (
2537c2c66affSColin Finck 			 LPVOID lpFile,
2538c2c66affSColin Finck 			 char **pszResTypes)
2539c2c66affSColin Finck {
2540c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY prdRoot;
2541c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2542c2c66affSColin Finck   char *pMem;
2543c2c66affSColin Finck   char buff[32];
2544c2c66affSColin Finck   int nCnt, i;
2545c2c66affSColin Finck   DWORD prdeName;
2546c2c66affSColin Finck 
2547c2c66affSColin Finck 
2548c2c66affSColin Finck   /* get root directory of resource tree */
2549c2c66affSColin Finck   if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2550c2c66affSColin Finck        (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2551c2c66affSColin Finck     return 0;
2552c2c66affSColin Finck 
2553c2c66affSColin Finck   /* allocate enuff space  to cover all types */
2554c2c66affSColin Finck   nCnt = prdRoot->NumberOfIdEntries * (MAXRESOURCENAME + 1);
2555c2c66affSColin Finck   *pszResTypes = (char *) calloc (nCnt, 1);
2556c2c66affSColin Finck   if ((pMem = *pszResTypes) == NULL)
2557c2c66affSColin Finck     return 0;
2558c2c66affSColin Finck 
2559c2c66affSColin Finck   /* set pointer to first resource type entry */
2560c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2561c2c66affSColin Finck 
2562c2c66affSColin Finck   /* loop through all resource directory entry types */
2563c2c66affSColin Finck   for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2564c2c66affSColin Finck     {
2565c2c66affSColin Finck       prdeName = prde->Name;
2566c2c66affSColin Finck 
2567c2c66affSColin Finck       //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
2568c2c66affSColin Finck       //    pMem += strlen (pMem) + 1;
2569c2c66affSColin Finck       //
2570c2c66affSColin Finck       // modified by ...................................Sang Cho..
2571c2c66affSColin Finck       // I can't user M/S provied funcitons here so I have to figure out
2572c2c66affSColin Finck       // how to do above functions. But I can settle down with the following
2573c2c66affSColin Finck       // code, which works pretty good for me.
2574c2c66affSColin Finck       //
2575c2c66affSColin Finck       if (prdeName == 1)
2576c2c66affSColin Finck 	{
2577c2c66affSColin Finck 	  strcpy (pMem, "RT_CURSOR");
2578c2c66affSColin Finck 	  pMem += 10;
2579c2c66affSColin Finck 	}
2580c2c66affSColin Finck       else if (prdeName == 2)
2581c2c66affSColin Finck 	{
2582c2c66affSColin Finck 	  strcpy (pMem, "RT_BITMAP");
2583c2c66affSColin Finck 	  pMem += 10;
2584c2c66affSColin Finck 	}
2585c2c66affSColin Finck       else if (prdeName == 3)
2586c2c66affSColin Finck 	{
2587c2c66affSColin Finck 	  strcpy (pMem, "RT_ICON  ");
2588c2c66affSColin Finck 	  pMem += 10;
2589c2c66affSColin Finck 	}
2590c2c66affSColin Finck       else if (prdeName == 4)
2591c2c66affSColin Finck 	{
2592c2c66affSColin Finck 	  strcpy (pMem, "RT_MENU  ");
2593c2c66affSColin Finck 	  pMem += 10;
2594c2c66affSColin Finck 	}
2595c2c66affSColin Finck       else if (prdeName == 5)
2596c2c66affSColin Finck 	{
2597c2c66affSColin Finck 	  strcpy (pMem, "RT_DIALOG");
2598c2c66affSColin Finck 	  pMem += 10;
2599c2c66affSColin Finck 	}
2600c2c66affSColin Finck       else if (prdeName == 6)
2601c2c66affSColin Finck 	{
2602c2c66affSColin Finck 	  strcpy (pMem, "RT_STRING");
2603c2c66affSColin Finck 	  pMem += 10;
2604c2c66affSColin Finck 	}
2605c2c66affSColin Finck       else if (prdeName == 7)
2606c2c66affSColin Finck 	{
2607c2c66affSColin Finck 	  strcpy (pMem, "RT_FONTDIR");
2608c2c66affSColin Finck 	  pMem += 11;
2609c2c66affSColin Finck 	}
2610c2c66affSColin Finck       else if (prdeName == 8)
2611c2c66affSColin Finck 	{
2612c2c66affSColin Finck 	  strcpy (pMem, "RT_FONT  ");
2613c2c66affSColin Finck 	  pMem += 10;
2614c2c66affSColin Finck 	}
2615c2c66affSColin Finck       else if (prdeName == 9)
2616c2c66affSColin Finck 	{
2617c2c66affSColin Finck 	  strcpy (pMem, "RT_ACCELERATORS");
2618c2c66affSColin Finck 	  pMem += 16;
2619c2c66affSColin Finck 	}
2620c2c66affSColin Finck       else if (prdeName == 10)
2621c2c66affSColin Finck 	{
2622c2c66affSColin Finck 	  strcpy (pMem, "RT_RCDATA");
2623c2c66affSColin Finck 	  pMem += 10;
2624c2c66affSColin Finck 	}
2625c2c66affSColin Finck       else if (prdeName == 11)
2626c2c66affSColin Finck 	{
2627c2c66affSColin Finck 	  strcpy (pMem, "RT_MESSAGETABLE");
2628c2c66affSColin Finck 	  pMem += 16;
2629c2c66affSColin Finck 	}
2630c2c66affSColin Finck       else if (prdeName == 12)
2631c2c66affSColin Finck 	{
2632c2c66affSColin Finck 	  strcpy (pMem, "RT_GROUP_CURSOR");
2633c2c66affSColin Finck 	  pMem += 16;
2634c2c66affSColin Finck 	}
2635c2c66affSColin Finck       else if (prdeName == 14)
2636c2c66affSColin Finck 	{
2637c2c66affSColin Finck 	  strcpy (pMem, "RT_GROUP_ICON  ");
2638c2c66affSColin Finck 	  pMem += 16;
2639c2c66affSColin Finck 	}
2640c2c66affSColin Finck       else if (prdeName == 16)
2641c2c66affSColin Finck 	{
2642c2c66affSColin Finck 	  strcpy (pMem, "RT_VERSION");
2643c2c66affSColin Finck 	  pMem += 11;
2644c2c66affSColin Finck 	}
2645c2c66affSColin Finck       else if (prdeName == 17)
2646c2c66affSColin Finck 	{
2647c2c66affSColin Finck 	  strcpy (pMem, "RT_DLGINCLUDE  ");
2648c2c66affSColin Finck 	  pMem += 16;
2649c2c66affSColin Finck 	}
2650c2c66affSColin Finck       else if (prdeName == 19)
2651c2c66affSColin Finck 	{
2652c2c66affSColin Finck 	  strcpy (pMem, "RT_PLUGPLAY    ");
2653c2c66affSColin Finck 	  pMem += 16;
2654c2c66affSColin Finck 	}
2655c2c66affSColin Finck       else if (prdeName == 20)
2656c2c66affSColin Finck 	{
2657c2c66affSColin Finck 	  strcpy (pMem, "RT_VXD   ");
2658c2c66affSColin Finck 	  pMem += 10;
2659c2c66affSColin Finck 	}
2660c2c66affSColin Finck       else if (prdeName == 21)
2661c2c66affSColin Finck 	{
2662c2c66affSColin Finck 	  strcpy (pMem, "RT_ANICURSOR   ");
2663c2c66affSColin Finck 	  pMem += 16;
2664c2c66affSColin Finck 	}
2665c2c66affSColin Finck       else if (prdeName == 22)
2666c2c66affSColin Finck 	{
2667c2c66affSColin Finck 	  strcpy (pMem, "RT_ANIICON");
2668c2c66affSColin Finck 	  pMem += 11;
2669c2c66affSColin Finck 	}
2670c2c66affSColin Finck       else if (prdeName == 0x2002)
2671c2c66affSColin Finck 	{
2672c2c66affSColin Finck 	  strcpy (pMem, "RT_NEWBITMAP");
2673c2c66affSColin Finck 	  pMem += 13;
2674c2c66affSColin Finck 	}
2675c2c66affSColin Finck       else if (prdeName == 0x2004)
2676c2c66affSColin Finck 	{
2677c2c66affSColin Finck 	  strcpy (pMem, "RT_NEWMENU");
2678c2c66affSColin Finck 	  pMem += 11;
2679c2c66affSColin Finck 	}
2680c2c66affSColin Finck       else if (prdeName == 0x2005)
2681c2c66affSColin Finck 	{
2682c2c66affSColin Finck 	  strcpy (pMem, "RT_NEWDIALOG");
2683c2c66affSColin Finck 	  pMem += 13;
2684c2c66affSColin Finck 	}
2685c2c66affSColin Finck       else if (prdeName == 0x7fff)
2686c2c66affSColin Finck 	{
2687c2c66affSColin Finck 	  strcpy (pMem, "RT_ERROR ");
2688c2c66affSColin Finck 	  pMem += 10;
2689c2c66affSColin Finck 	}
2690c2c66affSColin Finck       else
2691c2c66affSColin Finck 	{
2692c2c66affSColin Finck 	  sprintf (buff, "RT_UNKNOWN:%08lX", prdeName);
2693c2c66affSColin Finck 	  strcpy (pMem, buff);
2694c2c66affSColin Finck 	  pMem += 20;
2695c2c66affSColin Finck 	}
2696c2c66affSColin Finck       prde++;
2697c2c66affSColin Finck     }
2698c2c66affSColin Finck 
2699c2c66affSColin Finck   return prdRoot->NumberOfIdEntries;
2700c2c66affSColin Finck }
2701c2c66affSColin Finck 
2702c2c66affSColin Finck 
2703c2c66affSColin Finck 
2704c2c66affSColin Finck //
2705c2c66affSColin Finck // This function is written by sang cho
2706c2c66affSColin Finck //                                                         October 12, 1997
2707c2c66affSColin Finck //
2708c2c66affSColin Finck /* copy menu information */
2709c2c66affSColin Finck void WINAPI
StrangeMenuFill(char ** psz,WORD ** pMenu,int size)2710c2c66affSColin Finck StrangeMenuFill (
2711c2c66affSColin Finck 		  char **psz,	// results
2712c2c66affSColin Finck 		   WORD ** pMenu,	// read-only
2713c2c66affSColin Finck 		   int size)
2714c2c66affSColin Finck {
2715c2c66affSColin Finck   WORD *pwd;
2716c2c66affSColin Finck   WORD *ptr, *pmax;
2717c2c66affSColin Finck 
2718c2c66affSColin Finck   pwd = *pMenu;
2719c2c66affSColin Finck   pmax = (WORD *) ((DWORD) pwd + size);
2720c2c66affSColin Finck   ptr = (WORD *) (*psz);
2721c2c66affSColin Finck 
2722c2c66affSColin Finck   while (pwd < pmax)
2723c2c66affSColin Finck     {
2724c2c66affSColin Finck       *ptr++ = *pwd++;
2725c2c66affSColin Finck     }
2726c2c66affSColin Finck   *psz = (char *) ptr;
2727c2c66affSColin Finck   *pMenu = pwd;
2728c2c66affSColin Finck }
2729c2c66affSColin Finck 
2730c2c66affSColin Finck 
2731c2c66affSColin Finck 
2732c2c66affSColin Finck //
2733c2c66affSColin Finck // This function is written by sang cho
2734c2c66affSColin Finck //                                                         October 1, 1997
2735c2c66affSColin Finck //
2736c2c66affSColin Finck /* obtain menu information */
2737c2c66affSColin Finck int WINAPI
MenuScan(int * len,WORD ** pMenu)2738c2c66affSColin Finck MenuScan (
2739c2c66affSColin Finck 	   int *len,
2740c2c66affSColin Finck 	   WORD ** pMenu)
2741c2c66affSColin Finck {
2742c2c66affSColin Finck   //int num = 0;
2743c2c66affSColin Finck   //int ndetails;
2744c2c66affSColin Finck   WORD *pwd;
2745c2c66affSColin Finck   WORD flag, flag1;
2746c2c66affSColin Finck   WORD id, ispopup;
2747c2c66affSColin Finck 
2748c2c66affSColin Finck 
2749c2c66affSColin Finck   pwd = *pMenu;
2750c2c66affSColin Finck 
2751c2c66affSColin Finck   flag = *pwd;			// so difficult to correctly code this so let's try this
2752c2c66affSColin Finck 
2753c2c66affSColin Finck   pwd++;
2754c2c66affSColin Finck   (*len) += 2;			// flag store
2755c2c66affSColin Finck 
2756c2c66affSColin Finck   if ((flag & 0x0010) == 0)
2757c2c66affSColin Finck     {
2758c2c66affSColin Finck       ispopup = flag;
2759c2c66affSColin Finck       id = *pwd;
2760c2c66affSColin Finck       pwd++;
2761c2c66affSColin Finck       (*len) += 2;		// id store
2762c2c66affSColin Finck 
2763c2c66affSColin Finck     }
2764c2c66affSColin Finck   else
2765c2c66affSColin Finck     {
2766c2c66affSColin Finck       ispopup = flag;
2767c2c66affSColin Finck     }
2768c2c66affSColin Finck 
2769c2c66affSColin Finck   while (*pwd)
2770c2c66affSColin Finck     {
2771c2c66affSColin Finck       (*len)++;
2772c2c66affSColin Finck       pwd++;
2773c2c66affSColin Finck     }
2774c2c66affSColin Finck   (*len)++;			// name and null character
2775c2c66affSColin Finck 
2776c2c66affSColin Finck   pwd++;			// skip double null
2777c2c66affSColin Finck 
2778c2c66affSColin Finck   if ((flag & 0x0010) == 0)	// normal node: done
2779c2c66affSColin Finck 
2780c2c66affSColin Finck     {
2781c2c66affSColin Finck       *pMenu = pwd;
2782c2c66affSColin Finck       return (int) flag;
2783c2c66affSColin Finck     }
2784c2c66affSColin Finck   // popup node: need to go on...
2785c2c66affSColin Finck   while (1)
2786c2c66affSColin Finck     {
2787c2c66affSColin Finck       *pMenu = pwd;
2788c2c66affSColin Finck       flag1 = (WORD) MenuScan (len, pMenu);
2789c2c66affSColin Finck       pwd = *pMenu;
2790c2c66affSColin Finck       if (flag1 & 0x0080)
2791c2c66affSColin Finck 	break;
2792c2c66affSColin Finck     }
2793c2c66affSColin Finck //  fill # of details to num above
2794c2c66affSColin Finck   //(*len) += 2;
2795c2c66affSColin Finck   *pMenu = pwd;
2796c2c66affSColin Finck   return flag;
2797c2c66affSColin Finck }
2798c2c66affSColin Finck 
2799c2c66affSColin Finck 
2800c2c66affSColin Finck //
2801c2c66affSColin Finck // This function is written by sang cho
2802c2c66affSColin Finck //                                                         October 2, 1997
2803c2c66affSColin Finck //
2804c2c66affSColin Finck /* copy menu information */
2805c2c66affSColin Finck int WINAPI
MenuFill(char ** psz,WORD ** pMenu)2806c2c66affSColin Finck MenuFill (
2807c2c66affSColin Finck 	   char **psz,
2808c2c66affSColin Finck 	   WORD ** pMenu)
2809c2c66affSColin Finck {
2810c2c66affSColin Finck   //int num = 0;
2811c2c66affSColin Finck   //int ndetails;
2812c2c66affSColin Finck   char *ptr/*, *pTemp*/;
2813c2c66affSColin Finck   WORD *pwd;
2814c2c66affSColin Finck   WORD flag, flag1;
2815c2c66affSColin Finck   WORD id/*, ispopup*/;
2816c2c66affSColin Finck 
2817c2c66affSColin Finck   ptr = *psz;
2818c2c66affSColin Finck   pwd = *pMenu;
2819c2c66affSColin Finck   //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags;
2820c2c66affSColin Finck   flag = *pwd;			// so difficult to correctly code this so let's try this
2821c2c66affSColin Finck 
2822c2c66affSColin Finck   pwd++;
2823c2c66affSColin Finck   if ((flag & 0x0010) == 0)
2824c2c66affSColin Finck     {
2825c2c66affSColin Finck       *(WORD *) ptr = flag;	// flag store
2826c2c66affSColin Finck 
2827c2c66affSColin Finck       ptr += 2;
2828c2c66affSColin Finck       *(WORD *) ptr = id = *pwd;	// id store
2829c2c66affSColin Finck 
2830c2c66affSColin Finck       ptr += 2;
2831c2c66affSColin Finck       pwd++;
2832c2c66affSColin Finck     }
2833c2c66affSColin Finck   else
2834c2c66affSColin Finck     {
2835c2c66affSColin Finck       *(WORD *) ptr = flag;	// flag store
2836c2c66affSColin Finck 
2837c2c66affSColin Finck       ptr += 2;
2838c2c66affSColin Finck     }
2839c2c66affSColin Finck 
2840c2c66affSColin Finck   while (*pwd)			// name extract
2841c2c66affSColin Finck 
2842c2c66affSColin Finck     {
2843c2c66affSColin Finck       *ptr = *(char *) pwd;
2844c2c66affSColin Finck       ptr++;
2845c2c66affSColin Finck       pwd++;
2846c2c66affSColin Finck     }				//name and null character
2847c2c66affSColin Finck 
2848c2c66affSColin Finck   *ptr = 0;
2849c2c66affSColin Finck   ptr++;
2850c2c66affSColin Finck   pwd++;			// skip double null
2851c2c66affSColin Finck 
2852c2c66affSColin Finck   if ((flag & 0x0010) == 0)	// normal node: done
2853c2c66affSColin Finck 
2854c2c66affSColin Finck     {
2855c2c66affSColin Finck       *pMenu = pwd;
2856c2c66affSColin Finck       *psz = ptr;
2857c2c66affSColin Finck       return (int) flag;
2858c2c66affSColin Finck     }
2859c2c66affSColin Finck   //pTemp = ptr;
2860c2c66affSColin Finck   //ptr += 2;
2861c2c66affSColin Finck   // popup node: need to go on...
2862c2c66affSColin Finck   while (1)
2863c2c66affSColin Finck     {
2864c2c66affSColin Finck       //num++;
2865c2c66affSColin Finck       *pMenu = pwd;
2866c2c66affSColin Finck       *psz = ptr;
2867c2c66affSColin Finck       flag1 = (WORD) MenuFill (psz, pMenu);
2868c2c66affSColin Finck       pwd = *pMenu;
2869c2c66affSColin Finck       ptr = *psz;
2870c2c66affSColin Finck       if (flag1 & 0x0080)
2871c2c66affSColin Finck 	break;
2872c2c66affSColin Finck     }
2873c2c66affSColin Finck //  fill # of details to num above
2874c2c66affSColin Finck   //*(WORD *)pTemp = (WORD)num;
2875c2c66affSColin Finck   *pMenu = pwd;
2876c2c66affSColin Finck   *psz = ptr;
2877c2c66affSColin Finck   return flag;
2878c2c66affSColin Finck }
2879c2c66affSColin Finck 
2880c2c66affSColin Finck 
2881c2c66affSColin Finck //
2882c2c66affSColin Finck //==============================================================================
2883c2c66affSColin Finck // The following program is based on preorder-tree-traversal.
2884c2c66affSColin Finck // once you understand how to traverse.....
2885c2c66affSColin Finck // the rest is pretty straight forward.
2886c2c66affSColin Finck // still we need to scan it first and fill it next time.
2887c2c66affSColin Finck // and finally we can print it.
2888c2c66affSColin Finck //
2889c2c66affSColin Finck // This function is written by sang cho
2890c2c66affSColin Finck //                                                         September 29, 1997
2891c2c66affSColin Finck //                                                         revised october 2, 1997
2892c2c66affSColin Finck //                             revised october 12, 1997
2893c2c66affSColin Finck // ..............................................................................
2894c2c66affSColin Finck // ------------------------------------------------------------------------------
2895c2c66affSColin Finck // I use same structure - which is used in P.E. programs - for my reporting.
2896c2c66affSColin Finck // So, my structure is as follows:
2897c2c66affSColin Finck //        # of menu name is stored else where ( in directory I suppose )
2898c2c66affSColin Finck //     supermenuname                    null terminated string, only ascii is considered.
2899c2c66affSColin Finck //         flag                 tells : node is a leaf or a internal node.
2900c2c66affSColin Finck //         popupname                    null terminated string
2901c2c66affSColin Finck //
2902c2c66affSColin Finck //              flag                normal menu flag (leaf node)
2903c2c66affSColin Finck //                      id                                  normal menu id
2904c2c66affSColin Finck //              name                    normal menu name
2905c2c66affSColin Finck //         or                            or
2906c2c66affSColin Finck //              flag                        popup menu flag (internal node)
2907c2c66affSColin Finck //              popupname                   popup menu name
2908c2c66affSColin Finck //
2909c2c66affSColin Finck //                 flag                             it may folows
2910c2c66affSColin Finck //                         id                                   normal menu id
2911c2c66affSColin Finck //                 name                                 normal menu name
2912c2c66affSColin Finck //             or                                 or
2913c2c66affSColin Finck //                 flag                                 popup menu
2914c2c66affSColin Finck //                 popupname                    popup menu name
2915c2c66affSColin Finck //                                 .........
2916c2c66affSColin Finck //                                it goes on like this,
2917c2c66affSColin Finck //                                 but usually, it only goes a few steps,...
2918c2c66affSColin Finck // ------------------------------------------------------------------------------
2919c2c66affSColin Finck /* scan menu and copy menu */
2920c2c66affSColin Finck int WINAPI
GetContentsOfMenu(LPVOID lpFile,char ** pszResTypes)2921c2c66affSColin Finck GetContentsOfMenu (
2922c2c66affSColin Finck 		    LPVOID lpFile,
2923c2c66affSColin Finck 		    char **pszResTypes)
2924c2c66affSColin Finck {
2925c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage;
2926c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1;
2927c2c66affSColin Finck   PIMAGE_RESOURCE_DIR_STRING_U pMenuName;
2928c2c66affSColin Finck   PIMAGE_RESOURCE_DATA_ENTRY prData;
2929c2c66affSColin Finck   //PIMAGE_SECTION_HEADER              psh = (PIMAGE_SECTION_HEADER)
2930c2c66affSColin Finck   //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE);
2931c2c66affSColin Finck   PIMAGE_MENU_HEADER pMenuHeader;
2932c2c66affSColin Finck   //PIMAGE_POPUP_MENU_ITEM pPopup;
2933c2c66affSColin Finck   WORD* pPopup;
2934c2c66affSColin Finck   //PIMAGE_NORMAL_MENU_ITEM pNormal;
2935c2c66affSColin Finck   char buff[32];
2936c2c66affSColin Finck   int /*nCnt = 0,*/ i, j;
2937c2c66affSColin Finck   //int num = 0;
2938c2c66affSColin Finck   int size;
2939c2c66affSColin Finck   int sLength, nMenus;
2940c2c66affSColin Finck   WORD flag;
2941c2c66affSColin Finck   WORD *pwd;
2942c2c66affSColin Finck   //DWORD prdeName;
2943c2c66affSColin Finck   //DWORD                   dwBase;    obsolete
2944c2c66affSColin Finck   char *pMem/*, *pTemp*/;
2945c2c66affSColin Finck   //BOOL isStrange = FALSE;
2946c2c66affSColin Finck 
2947c2c66affSColin Finck 
2948c2c66affSColin Finck   /* get root directory of resource tree */
2949c2c66affSColin Finck   if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2950c2c66affSColin Finck        (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2951c2c66affSColin Finck     return 0;
2952c2c66affSColin Finck 
2953c2c66affSColin Finck   /* set pointer to first resource type entry */
2954c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2955c2c66affSColin Finck     ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
2956c2c66affSColin Finck 
2957c2c66affSColin Finck   for (i = 0; i < prdType->NumberOfIdEntries; i++)
2958c2c66affSColin Finck     {
2959c2c66affSColin Finck       if (prde->Name == RT_MENU)
2960c2c66affSColin Finck 	break;
2961c2c66affSColin Finck       prde++;
2962c2c66affSColin Finck     }
2963c2c66affSColin Finck   if (prde->Name != RT_MENU)
2964c2c66affSColin Finck     return 0;
2965c2c66affSColin Finck 
2966c2c66affSColin Finck   prdName = (PIMAGE_RESOURCE_DIRECTORY)
2967c2c66affSColin Finck     ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2968c2c66affSColin Finck   if (prdName == NULL)
2969c2c66affSColin Finck     return 0;
2970c2c66affSColin Finck 
2971c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2972c2c66affSColin Finck     ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
2973c2c66affSColin Finck 
2974c2c66affSColin Finck   // sometimes previous code tells you lots of things hidden underneath
2975c2c66affSColin Finck   // I wish I could save all the revisions I made ... but again .... sigh.
2976c2c66affSColin Finck   //                                  october 12, 1997    sang
2977c2c66affSColin Finck   //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2978c2c66affSColin Finck 
2979c2c66affSColin Finck   nMenus = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
2980c2c66affSColin Finck   sLength = 0;
2981c2c66affSColin Finck 
2982c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfNamedEntries; i++)
2983c2c66affSColin Finck     {
2984c2c66affSColin Finck       pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
2985c2c66affSColin Finck 	((DWORD) prdType + (prde->Name ^ 0x80000000));
2986c2c66affSColin Finck       sLength += pMenuName->Length + 1;
2987c2c66affSColin Finck 
2988c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
2989c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2990c2c66affSColin Finck       if (prdLanguage == NULL)
2991c2c66affSColin Finck 	continue;
2992c2c66affSColin Finck 
2993c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2994c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
2995c2c66affSColin Finck 
2996c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
2997c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
2998c2c66affSColin Finck       if (prData == NULL)
2999c2c66affSColin Finck 	continue;
3000c2c66affSColin Finck 
3001c2c66affSColin Finck       pMenuHeader = (PIMAGE_MENU_HEADER)
3002c2c66affSColin Finck 	GetActualAddress (lpFile, prData->OffsetToData);
3003c2c66affSColin Finck 
3004c2c66affSColin Finck       //
3005c2c66affSColin Finck       // normally wVersion and cbHeaderSize should be zero
3006c2c66affSColin Finck       // but if it is not then nothing is known to us...
3007c2c66affSColin Finck       // so let's do our best ... namely guessing .... and trying ....
3008c2c66affSColin Finck       //                      ... and suffering   ...
3009c2c66affSColin Finck       // it gave me many sleepless (not exactly but I like to say this) nights.
3010c2c66affSColin Finck       //
3011c2c66affSColin Finck 
3012c2c66affSColin Finck       // strange case
3013c2c66affSColin Finck       if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3014c2c66affSColin Finck 	{
3015c2c66affSColin Finck 	  //isStrange = TRUE;
3016c2c66affSColin Finck 	  pwd = (WORD *) ((DWORD) pMenuHeader + 16);
3017c2c66affSColin Finck 	  size = prData->Size;
3018c2c66affSColin Finck 	  // expect to return the length needed to report.
3019c2c66affSColin Finck 	  // sixteen more bytes to do something
3020c2c66affSColin Finck 	  sLength += 16 + size;
3021c2c66affSColin Finck 	  //StrangeMenuScan (&sLength, &pwd, size);
3022c2c66affSColin Finck 	}
3023c2c66affSColin Finck       // normal case
3024c2c66affSColin Finck       else
3025c2c66affSColin Finck 	{
3026c2c66affSColin Finck 	  pPopup = (WORD*)
3027c2c66affSColin Finck 	    ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3028c2c66affSColin Finck 	  while (1)
3029c2c66affSColin Finck 	    {
3030c2c66affSColin Finck 	      flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3031c2c66affSColin Finck 	      if (flag & 0x0080)
3032c2c66affSColin Finck 		break;
3033c2c66affSColin Finck 	    }
3034c2c66affSColin Finck 	}
3035c2c66affSColin Finck       prde++;
3036c2c66affSColin Finck     }
3037c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfIdEntries; i++)
3038c2c66affSColin Finck     {
3039c2c66affSColin Finck       sLength += 12;
3040c2c66affSColin Finck 
3041c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3042c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3043c2c66affSColin Finck       if (prdLanguage == NULL)
3044c2c66affSColin Finck 	continue;
3045c2c66affSColin Finck 
3046c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3047c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3048c2c66affSColin Finck 
3049c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3050c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
3051c2c66affSColin Finck       if (prData == NULL)
3052c2c66affSColin Finck 	continue;
3053c2c66affSColin Finck 
3054c2c66affSColin Finck       pMenuHeader = (PIMAGE_MENU_HEADER)
3055c2c66affSColin Finck 	GetActualAddress (lpFile, prData->OffsetToData);
3056c2c66affSColin Finck       // strange case
3057c2c66affSColin Finck       if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3058c2c66affSColin Finck 	{
3059c2c66affSColin Finck 	  pwd = (WORD *) ((DWORD) pMenuHeader + 16);
3060c2c66affSColin Finck 	  size = prData->Size;
3061c2c66affSColin Finck 	  // expect to return the length needed to report.
3062c2c66affSColin Finck 	  // sixteen more bytes to do something
3063c2c66affSColin Finck 	  sLength += 16 + size;
3064c2c66affSColin Finck 	  //StrangeMenuScan (&sLength, &pwd, size);
3065c2c66affSColin Finck 	}
3066c2c66affSColin Finck       // normal case
3067c2c66affSColin Finck       else
3068c2c66affSColin Finck 	{
3069c2c66affSColin Finck 	  pPopup = (WORD*)
3070c2c66affSColin Finck 	    ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3071c2c66affSColin Finck 	  while (1)
3072c2c66affSColin Finck 	    {
3073c2c66affSColin Finck 	      flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3074c2c66affSColin Finck 	      if (flag & 0x0080)
3075c2c66affSColin Finck 		break;
3076c2c66affSColin Finck 	    }
3077c2c66affSColin Finck 	}
3078c2c66affSColin Finck       prde++;
3079c2c66affSColin Finck     }
3080c2c66affSColin Finck   //
3081c2c66affSColin Finck   // allocate memory for menu names
3082c2c66affSColin Finck   //
3083c2c66affSColin Finck   *pszResTypes = (char *) calloc (sLength, 1);
3084c2c66affSColin Finck 
3085c2c66affSColin Finck   pMem = *pszResTypes;
3086c2c66affSColin Finck   //
3087c2c66affSColin Finck   // and start all over again
3088c2c66affSColin Finck   //
3089c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3090c2c66affSColin Finck     ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3091c2c66affSColin Finck 
3092c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3093c2c66affSColin Finck     {
3094c2c66affSColin Finck       pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
3095c2c66affSColin Finck 	((DWORD) prdType + (prde->Name ^ 0x80000000));
3096c2c66affSColin Finck 
3097c2c66affSColin Finck 
3098c2c66affSColin Finck       for (j = 0; j < pMenuName->Length; j++)
3099c2c66affSColin Finck 	*pMem++ = (char) (pMenuName->NameString[j]);
3100c2c66affSColin Finck       *pMem = 0;
3101c2c66affSColin Finck       pMem++;
3102c2c66affSColin Finck 
3103c2c66affSColin Finck 
3104c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3105c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3106c2c66affSColin Finck       if (prdLanguage == NULL)
3107c2c66affSColin Finck 	continue;
3108c2c66affSColin Finck 
3109c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3110c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3111c2c66affSColin Finck 
3112c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3113c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
3114c2c66affSColin Finck       if (prData == NULL)
3115c2c66affSColin Finck 	continue;
3116c2c66affSColin Finck 
3117c2c66affSColin Finck       pMenuHeader = (PIMAGE_MENU_HEADER)
3118c2c66affSColin Finck 	GetActualAddress (lpFile, prData->OffsetToData);
3119c2c66affSColin Finck       // strange case
3120c2c66affSColin Finck       if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3121c2c66affSColin Finck 	{
3122c2c66affSColin Finck 	  pwd = (WORD *) ((DWORD) pMenuHeader);
3123c2c66affSColin Finck 	  size = prData->Size;
3124c2c66affSColin Finck 	  strcpy (pMem, ":::::::::::");
3125c2c66affSColin Finck 	  pMem += 12;
3126c2c66affSColin Finck 	  *(int *) pMem = size;
3127c2c66affSColin Finck 	  pMem += 4;
3128c2c66affSColin Finck 	  StrangeMenuFill (&pMem, &pwd, size);
3129c2c66affSColin Finck 	}
3130c2c66affSColin Finck       // normal case
3131c2c66affSColin Finck       else
3132c2c66affSColin Finck 	{
3133c2c66affSColin Finck 	  pPopup = (WORD*)
3134c2c66affSColin Finck 	    ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3135c2c66affSColin Finck 	  while (1)
3136c2c66affSColin Finck 	    {
3137c2c66affSColin Finck 	      flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3138c2c66affSColin Finck 	      if (flag & 0x0080)
3139c2c66affSColin Finck 		break;
3140c2c66affSColin Finck 	    }
3141c2c66affSColin Finck 	}
3142c2c66affSColin Finck       prde++;
3143c2c66affSColin Finck     }
3144c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfIdEntries; i++)
3145c2c66affSColin Finck     {
3146c2c66affSColin Finck 
3147c2c66affSColin Finck       sprintf (buff, "MenuId_%04lX", (prde->Name));
3148c2c66affSColin Finck       strcpy (pMem, buff);
3149c2c66affSColin Finck       pMem += strlen (buff) + 1;
3150c2c66affSColin Finck 
3151c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3152c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3153c2c66affSColin Finck       if (prdLanguage == NULL)
3154c2c66affSColin Finck 	continue;
3155c2c66affSColin Finck 
3156c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3157c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3158c2c66affSColin Finck 
3159c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3160c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
3161c2c66affSColin Finck       if (prData == NULL)
3162c2c66affSColin Finck 	continue;
3163c2c66affSColin Finck 
3164c2c66affSColin Finck       pMenuHeader = (PIMAGE_MENU_HEADER)
3165c2c66affSColin Finck 	GetActualAddress (lpFile, prData->OffsetToData);
3166c2c66affSColin Finck       // strange case
3167c2c66affSColin Finck       if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3168c2c66affSColin Finck 	{
3169c2c66affSColin Finck 	  pwd = (WORD *) ((DWORD) pMenuHeader);
3170c2c66affSColin Finck 	  size = prData->Size;
3171c2c66affSColin Finck 	  strcpy (pMem, ":::::::::::");
3172c2c66affSColin Finck 	  pMem += 12;
3173c2c66affSColin Finck 	  *(int *) pMem = size;
3174c2c66affSColin Finck 	  pMem += 4;
3175c2c66affSColin Finck 	  StrangeMenuFill (&pMem, &pwd, size);
3176c2c66affSColin Finck 	}
3177c2c66affSColin Finck       // normal case
3178c2c66affSColin Finck       else
3179c2c66affSColin Finck 	{
3180c2c66affSColin Finck 	  pPopup = (WORD*)
3181c2c66affSColin Finck 	    ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3182c2c66affSColin Finck 	  while (1)
3183c2c66affSColin Finck 	    {
3184c2c66affSColin Finck 	      flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3185c2c66affSColin Finck 	      if (flag & 0x0080)
3186c2c66affSColin Finck 		break;
3187c2c66affSColin Finck 	    }
3188c2c66affSColin Finck 	}
3189c2c66affSColin Finck       prde++;
3190c2c66affSColin Finck     }
3191c2c66affSColin Finck 
3192c2c66affSColin Finck   return nMenus;
3193c2c66affSColin Finck }
3194c2c66affSColin Finck 
3195c2c66affSColin Finck 
3196c2c66affSColin Finck //
3197c2c66affSColin Finck // This function is written by sang cho
3198c2c66affSColin Finck //                                                         October 12, 1997
3199c2c66affSColin Finck //
3200c2c66affSColin Finck /* print contents of menu */
3201c2c66affSColin Finck int WINAPI
PrintStrangeMenu(char ** psz)3202c2c66affSColin Finck PrintStrangeMenu (
3203c2c66affSColin Finck 		   char **psz)
3204c2c66affSColin Finck {
3205c2c66affSColin Finck 
3206c2c66affSColin Finck   //int i, j, k, l;
3207c2c66affSColin Finck   int num;
3208c2c66affSColin Finck   //WORD flag1, flag2;
3209c2c66affSColin Finck   //char buff[128];
3210c2c66affSColin Finck   char *ptr, *pmax;
3211c2c66affSColin Finck 
3212c2c66affSColin Finck   //return dumpMenu (psz, size);
3213c2c66affSColin Finck 
3214c2c66affSColin Finck   ptr = *psz;
3215c2c66affSColin Finck 
3216c2c66affSColin Finck   if (strncmp (ptr, ":::::::::::", 11) != 0)
3217c2c66affSColin Finck     {
3218c2c66affSColin Finck       printf ("\n#### I don't know why!!!");
3219c2c66affSColin Finck       dumpMenu (psz, 1024);
3220c2c66affSColin Finck       exit (0);
3221c2c66affSColin Finck     }
3222c2c66affSColin Finck 
3223c2c66affSColin Finck   ptr += 12;
3224c2c66affSColin Finck   num = *(int *) ptr;
3225c2c66affSColin Finck   ptr += 4;
3226c2c66affSColin Finck   pmax = ptr + num;
3227c2c66affSColin Finck 
3228c2c66affSColin Finck   *psz = ptr;
3229c2c66affSColin Finck   return dumpMenu (psz, num);
3230c2c66affSColin Finck 
3231c2c66affSColin Finck   // I will write some code later...
3232c2c66affSColin Finck 
3233c2c66affSColin Finck }
3234c2c66affSColin Finck 
3235c2c66affSColin Finck 
3236c2c66affSColin Finck 
3237c2c66affSColin Finck 
3238c2c66affSColin Finck //
3239c2c66affSColin Finck // This function is written by sang cho
3240c2c66affSColin Finck //                                                         October 2, 1997
3241c2c66affSColin Finck //
3242c2c66affSColin Finck /* print contents of menu */
3243c2c66affSColin Finck int WINAPI
PrintMenu(int indent,char ** psz)3244c2c66affSColin Finck PrintMenu (
3245c2c66affSColin Finck 	    int indent,
3246c2c66affSColin Finck 	    char **psz)
3247c2c66affSColin Finck {
3248c2c66affSColin Finck 
3249c2c66affSColin Finck   int /*i, */ j, k, l;
3250c2c66affSColin Finck   WORD id /*, num */ ;
3251c2c66affSColin Finck   WORD flag;
3252c2c66affSColin Finck   char buff[128];
3253c2c66affSColin Finck   char *ptr;
3254c2c66affSColin Finck 
3255c2c66affSColin Finck 
3256c2c66affSColin Finck   ptr = *psz;
3257c2c66affSColin Finck   //num = *(WORD *)ptr;
3258c2c66affSColin Finck   //ptr += 2;
3259c2c66affSColin Finck   while (1)
3260c2c66affSColin Finck     {
3261c2c66affSColin Finck       flag = *(WORD *) ptr;
3262c2c66affSColin Finck       if (flag & 0x0010)	// flag == popup
3263c2c66affSColin Finck 
3264c2c66affSColin Finck 	{
3265c2c66affSColin Finck 	  printf ("\n\n");
3266c2c66affSColin Finck 	  for (j = 0; j < indent; j++)
3267c2c66affSColin Finck 	    printf (" ");
3268c2c66affSColin Finck 	  ptr += 2;
3269c2c66affSColin Finck 	  printf ("%s  {Popup}\n", ptr);
3270c2c66affSColin Finck 	  ptr += strlen (ptr) + 1;
3271c2c66affSColin Finck 	  *psz = ptr;
3272c2c66affSColin Finck 	  PrintMenu (indent + 5, psz);
3273c2c66affSColin Finck 	  ptr = *psz;
3274c2c66affSColin Finck 	}
3275c2c66affSColin Finck       else			// ispopup == 0
3276c2c66affSColin Finck 
3277c2c66affSColin Finck 	{
3278c2c66affSColin Finck 	  printf ("\n");
3279c2c66affSColin Finck 	  for (j = 0; j < indent; j++)
3280c2c66affSColin Finck 	    printf (" ");
3281c2c66affSColin Finck 	  ptr += 2;
3282c2c66affSColin Finck 	  id = *(WORD *) ptr;
3283c2c66affSColin Finck 	  ptr += 2;
3284c2c66affSColin Finck 	  strcpy (buff, ptr);
3285c2c66affSColin Finck 	  l = strlen (ptr);
3286c2c66affSColin Finck 	  ptr += l + 1;
3287c2c66affSColin Finck 	  if (strchr (buff, 0x09) != NULL)
3288c2c66affSColin Finck 	    {
3289c2c66affSColin Finck 	      for (k = 0; k < l; k++)
3290c2c66affSColin Finck 		if (buff[k] == 0x09)
3291c2c66affSColin Finck 		  break;
3292c2c66affSColin Finck 	      for (j = 0; j < l - k; j++)
3293c2c66affSColin Finck 		buff[31 - j] = buff[l - j];
3294c2c66affSColin Finck 	      for (j = k; j < 32 + k - l; j++)
3295c2c66affSColin Finck 		buff[j] = 32;
3296c2c66affSColin Finck 	    }
3297c2c66affSColin Finck 	  if (strchr (buff, 0x08) != NULL)
3298c2c66affSColin Finck 	    {
3299c2c66affSColin Finck 	      for (k = 0; k < l; k++)
3300c2c66affSColin Finck 		if (buff[k] == 0x08)
3301c2c66affSColin Finck 		  break;
3302c2c66affSColin Finck 	      for (j = 0; j < l - k; j++)
3303c2c66affSColin Finck 		buff[31 - j] = buff[l - j];
3304c2c66affSColin Finck 	      for (j = k; j < 32 + k - l; j++)
3305c2c66affSColin Finck 		buff[j] = 32;
3306c2c66affSColin Finck 	    }
3307c2c66affSColin Finck 	  printf ("%s", buff);
3308c2c66affSColin Finck 	  l = strlen (buff);
3309c2c66affSColin Finck 	  for (j = l; j < 32; j++)
3310c2c66affSColin Finck 	    printf (" ");
3311c2c66affSColin Finck 	  printf ("[ID=%04Xh]", id);
3312c2c66affSColin Finck 	  *psz = ptr;
3313c2c66affSColin Finck 	}
3314c2c66affSColin Finck       if (flag & 0x0080)
3315c2c66affSColin Finck 	break;
3316c2c66affSColin Finck     }
3317c2c66affSColin Finck   return 0;
3318c2c66affSColin Finck }
3319c2c66affSColin Finck 
3320c2c66affSColin Finck 
3321c2c66affSColin Finck //
3322c2c66affSColin Finck // This function is written by sang cho
3323c2c66affSColin Finck //                                                         October 2, 1997
3324c2c66affSColin Finck //
3325c2c66affSColin Finck /* the format of menu is not known so I'll do my best */
3326c2c66affSColin Finck int WINAPI
dumpMenu(char ** psz,int size)3327c2c66affSColin Finck dumpMenu (
3328c2c66affSColin Finck 	   char **psz,
3329c2c66affSColin Finck 	   int size)
3330c2c66affSColin Finck {
3331c2c66affSColin Finck 
3332c2c66affSColin Finck   int i, j, k, n, l, c;
3333c2c66affSColin Finck   char buff[32];
3334c2c66affSColin Finck   char *ptr, *pmax;
3335c2c66affSColin Finck 
3336c2c66affSColin Finck   ptr = *psz;
3337c2c66affSColin Finck   pmax = ptr + size;
3338c2c66affSColin Finck   for (i = 0; i < (size / 16) + 1; i++)
3339c2c66affSColin Finck     {
3340c2c66affSColin Finck       n = 0;
3341c2c66affSColin Finck       for (j = 0; j < 16; j++)
3342c2c66affSColin Finck 	{
3343c2c66affSColin Finck 	  c = (int) (*ptr);
3344c2c66affSColin Finck 	  if (c < 0)
3345c2c66affSColin Finck 	    c += 256;
3346c2c66affSColin Finck 	  buff[j] = c;
3347c2c66affSColin Finck 	  printf ("%02X", c);
3348c2c66affSColin Finck 	  ptr++;
3349c2c66affSColin Finck 	  if (ptr >= pmax)
3350c2c66affSColin Finck 	    break;
3351c2c66affSColin Finck 	  n++;
3352c2c66affSColin Finck 	  if (n % 4 == 0)
3353c2c66affSColin Finck 	    printf (" ");
3354c2c66affSColin Finck 	}
3355c2c66affSColin Finck       n++;
3356c2c66affSColin Finck       if (n % 4 == 0)
3357c2c66affSColin Finck 	printf (" ");
3358c2c66affSColin Finck       l = j;
3359c2c66affSColin Finck       j++;
3360c2c66affSColin Finck       for (; j < 16; j++)
3361c2c66affSColin Finck 	{
3362c2c66affSColin Finck 	  n++;
3363c2c66affSColin Finck 	  if (n % 4 == 0)
3364c2c66affSColin Finck 	    printf ("   ");
3365c2c66affSColin Finck 	  else
3366c2c66affSColin Finck 	    printf ("  ");
3367c2c66affSColin Finck 	}
3368c2c66affSColin Finck       printf ("   ");
3369c2c66affSColin Finck       for (k = 0; k < l; k++)
3370c2c66affSColin Finck 	if (isprint (c = buff[k]))
3371c2c66affSColin Finck 	  printf ("%c", c);
3372c2c66affSColin Finck 	else
3373c2c66affSColin Finck 	  printf (".");
3374c2c66affSColin Finck       printf ("\n");
3375c2c66affSColin Finck       if (ptr >= pmax)
3376c2c66affSColin Finck 	break;
3377c2c66affSColin Finck     }
3378c2c66affSColin Finck 
3379c2c66affSColin Finck   *psz = ptr;
3380c2c66affSColin Finck   return 0;
3381c2c66affSColin Finck }
3382c2c66affSColin Finck 
3383c2c66affSColin Finck 
3384c2c66affSColin Finck 
3385c2c66affSColin Finck 
3386c2c66affSColin Finck //
3387c2c66affSColin Finck // This function is written by sang cho
3388c2c66affSColin Finck //                                                         October 13, 1997
3389c2c66affSColin Finck //
3390c2c66affSColin Finck /* scan dialog box and copy dialog box */
3391c2c66affSColin Finck int WINAPI
GetContentsOfDialog(LPVOID lpFile,char ** pszResTypes)3392c2c66affSColin Finck GetContentsOfDialog (
3393c2c66affSColin Finck 		      LPVOID lpFile,
3394c2c66affSColin Finck 		      char **pszResTypes)
3395c2c66affSColin Finck {
3396c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage;
3397c2c66affSColin Finck   PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1;
3398c2c66affSColin Finck   PIMAGE_RESOURCE_DIR_STRING_U pDialogName;
3399c2c66affSColin Finck   PIMAGE_RESOURCE_DATA_ENTRY prData;
3400c2c66affSColin Finck   PIMAGE_DIALOG_HEADER pDialogHeader;
3401c2c66affSColin Finck   //PIMAGE_CONTROL_DATA pControlData;
3402c2c66affSColin Finck   char buff[32];
3403c2c66affSColin Finck   int /*nCnt = 0,*/ i, j;
3404c2c66affSColin Finck   //int num = 0;
3405c2c66affSColin Finck   int size;
3406c2c66affSColin Finck   int sLength, nDialogs;
3407c2c66affSColin Finck   //WORD flag;
3408c2c66affSColin Finck   WORD *pwd;
3409c2c66affSColin Finck   //DWORD prdeName;
3410c2c66affSColin Finck   char *pMem/*, *pTemp*/;
3411c2c66affSColin Finck   //BOOL isStrange = FALSE;
3412c2c66affSColin Finck 
3413c2c66affSColin Finck 
3414c2c66affSColin Finck   /* get root directory of resource tree */
3415c2c66affSColin Finck   if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
3416c2c66affSColin Finck        (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
3417c2c66affSColin Finck     return 0;
3418c2c66affSColin Finck 
3419c2c66affSColin Finck   /* set pointer to first resource type entry */
3420c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3421c2c66affSColin Finck     ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
3422c2c66affSColin Finck 
3423c2c66affSColin Finck   for (i = 0; i < prdType->NumberOfIdEntries; i++)
3424c2c66affSColin Finck     {
3425c2c66affSColin Finck       if (prde->Name == RT_DIALOG)
3426c2c66affSColin Finck 	break;
3427c2c66affSColin Finck       prde++;
3428c2c66affSColin Finck     }
3429c2c66affSColin Finck   if (prde->Name != RT_DIALOG)
3430c2c66affSColin Finck     return 0;
3431c2c66affSColin Finck 
3432c2c66affSColin Finck   prdName = (PIMAGE_RESOURCE_DIRECTORY)
3433c2c66affSColin Finck     ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3434c2c66affSColin Finck   if (prdName == NULL)
3435c2c66affSColin Finck     return 0;
3436c2c66affSColin Finck 
3437c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3438c2c66affSColin Finck     ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3439c2c66affSColin Finck 
3440c2c66affSColin Finck 
3441c2c66affSColin Finck   nDialogs = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
3442c2c66affSColin Finck   sLength = 0;
3443c2c66affSColin Finck 
3444c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3445c2c66affSColin Finck     {
3446c2c66affSColin Finck       pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3447c2c66affSColin Finck 	((DWORD) prdType + (prde->Name ^ 0x80000000));
3448c2c66affSColin Finck       sLength += pDialogName->Length + 1;
3449c2c66affSColin Finck 
3450c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3451c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3452c2c66affSColin Finck       if (prdLanguage == NULL)
3453c2c66affSColin Finck 	continue;
3454c2c66affSColin Finck 
3455c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3456c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3457c2c66affSColin Finck 
3458c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3459c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
3460c2c66affSColin Finck       if (prData == NULL)
3461c2c66affSColin Finck 	continue;
3462c2c66affSColin Finck 
3463c2c66affSColin Finck       size = prData->Size;
3464c2c66affSColin Finck       sLength += 4 + size;
3465c2c66affSColin Finck       prde++;
3466c2c66affSColin Finck     }
3467c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfIdEntries; i++)
3468c2c66affSColin Finck     {
3469c2c66affSColin Finck       sLength += 14;
3470c2c66affSColin Finck 
3471c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3472c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3473c2c66affSColin Finck       if (prdLanguage == NULL)
3474c2c66affSColin Finck 	continue;
3475c2c66affSColin Finck 
3476c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3477c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3478c2c66affSColin Finck 
3479c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3480c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
3481c2c66affSColin Finck       if (prData == NULL)
3482c2c66affSColin Finck 	continue;
3483c2c66affSColin Finck 
3484c2c66affSColin Finck       size = prData->Size;
3485c2c66affSColin Finck       sLength += 4 + size;
3486c2c66affSColin Finck       prde++;
3487c2c66affSColin Finck     }
3488c2c66affSColin Finck   //
3489c2c66affSColin Finck   // allocate memory for menu names
3490c2c66affSColin Finck   //
3491c2c66affSColin Finck   *pszResTypes = (char *) calloc (sLength, 1);
3492c2c66affSColin Finck 
3493c2c66affSColin Finck   pMem = *pszResTypes;
3494c2c66affSColin Finck   //
3495c2c66affSColin Finck   // and start all over again
3496c2c66affSColin Finck   //
3497c2c66affSColin Finck   prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3498c2c66affSColin Finck     ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3499c2c66affSColin Finck 
3500c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3501c2c66affSColin Finck     {
3502c2c66affSColin Finck       pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3503c2c66affSColin Finck 	((DWORD) prdType + (prde->Name ^ 0x80000000));
3504c2c66affSColin Finck 
3505c2c66affSColin Finck 
3506c2c66affSColin Finck       for (j = 0; j < pDialogName->Length; j++)
3507c2c66affSColin Finck 	*pMem++ = (char) (pDialogName->NameString[j]);
3508c2c66affSColin Finck       *pMem = 0;
3509c2c66affSColin Finck       pMem++;
3510c2c66affSColin Finck 
3511c2c66affSColin Finck 
3512c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3513c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3514c2c66affSColin Finck       if (prdLanguage == NULL)
3515c2c66affSColin Finck 	continue;
3516c2c66affSColin Finck 
3517c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3518c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3519c2c66affSColin Finck 
3520c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3521c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
3522c2c66affSColin Finck       if (prData == NULL)
3523c2c66affSColin Finck 	continue;
3524c2c66affSColin Finck 
3525c2c66affSColin Finck       pDialogHeader = (PIMAGE_DIALOG_HEADER)
3526c2c66affSColin Finck 	GetActualAddress (lpFile, prData->OffsetToData);
3527c2c66affSColin Finck 
3528c2c66affSColin Finck 
3529c2c66affSColin Finck 
3530c2c66affSColin Finck       pwd = (WORD *) ((DWORD) pDialogHeader);
3531c2c66affSColin Finck       size = prData->Size;
3532c2c66affSColin Finck       *(int *) pMem = size;
3533c2c66affSColin Finck       pMem += 4;
3534c2c66affSColin Finck       StrangeMenuFill (&pMem, &pwd, size);
3535c2c66affSColin Finck 
3536c2c66affSColin Finck       prde++;
3537c2c66affSColin Finck     }
3538c2c66affSColin Finck   for (i = 0; i < prdName->NumberOfIdEntries; i++)
3539c2c66affSColin Finck     {
3540c2c66affSColin Finck 
3541c2c66affSColin Finck       sprintf (buff, "DialogId_%04lX", (prde->Name));
3542c2c66affSColin Finck       strcpy (pMem, buff);
3543c2c66affSColin Finck       pMem += strlen (buff) + 1;
3544c2c66affSColin Finck 
3545c2c66affSColin Finck       prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3546c2c66affSColin Finck 	((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3547c2c66affSColin Finck       if (prdLanguage == NULL)
3548c2c66affSColin Finck 	{
3549c2c66affSColin Finck 	  printf ("\nprdLanguage = NULL");
3550c2c66affSColin Finck 	  exit (0);
3551c2c66affSColin Finck 	}
3552c2c66affSColin Finck 
3553c2c66affSColin Finck       prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3554c2c66affSColin Finck 	((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3555c2c66affSColin Finck 
3556c2c66affSColin Finck       prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3557c2c66affSColin Finck 	((DWORD) prdType + prde1->OffsetToData);
3558c2c66affSColin Finck       if (prData == NULL)
3559c2c66affSColin Finck 	{
3560c2c66affSColin Finck 	  printf ("\nprData = NULL");
3561c2c66affSColin Finck 	  exit (0);
3562c2c66affSColin Finck 	}
3563c2c66affSColin Finck 
3564c2c66affSColin Finck       pDialogHeader = (PIMAGE_DIALOG_HEADER)
3565c2c66affSColin Finck 	GetActualAddress (lpFile, prData->OffsetToData);
3566c2c66affSColin Finck 
3567c2c66affSColin Finck 
3568c2c66affSColin Finck       pwd = (WORD *) ((DWORD) pDialogHeader);
3569c2c66affSColin Finck       size = prData->Size;
3570c2c66affSColin Finck       *(int *) pMem = size;
3571c2c66affSColin Finck       pMem += 4;
3572c2c66affSColin Finck       StrangeMenuFill (&pMem, &pwd, size);
3573c2c66affSColin Finck 
3574c2c66affSColin Finck       prde++;
3575c2c66affSColin Finck     }
3576c2c66affSColin Finck 
3577c2c66affSColin Finck   return nDialogs;
3578c2c66affSColin Finck }
3579c2c66affSColin Finck 
3580c2c66affSColin Finck 
3581c2c66affSColin Finck //
3582c2c66affSColin Finck // This function is written by sang cho
3583c2c66affSColin Finck //                                                         October 14, 1997
3584c2c66affSColin Finck //
3585c2c66affSColin Finck /* print contents of dialog */
3586c2c66affSColin Finck void WINAPI
PrintNameOrOrdinal(char ** psz)3587c2c66affSColin Finck PrintNameOrOrdinal (
3588c2c66affSColin Finck 		     char **psz)
3589c2c66affSColin Finck {
3590c2c66affSColin Finck   char *ptr;
3591c2c66affSColin Finck 
3592c2c66affSColin Finck   ptr = *psz;
3593c2c66affSColin Finck   if (*(WORD *) ptr == 0xFFFF)
3594c2c66affSColin Finck     {
3595c2c66affSColin Finck       ptr += 2;
3596c2c66affSColin Finck       printf ("%04X", *(WORD *) ptr);
3597c2c66affSColin Finck       ptr += 2;
3598c2c66affSColin Finck     }
3599c2c66affSColin Finck   else
3600c2c66affSColin Finck     {
3601c2c66affSColin Finck       printf ("%c", '"');
3602c2c66affSColin Finck       while (*(WORD *) ptr)
3603c2c66affSColin Finck 	{
3604c2c66affSColin Finck 	  printf ("%c", *ptr);
3605c2c66affSColin Finck 	  ptr += 2;
3606c2c66affSColin Finck 	}
3607c2c66affSColin Finck       ptr += 2;
3608c2c66affSColin Finck       printf ("%c", '"');
3609c2c66affSColin Finck     }
3610c2c66affSColin Finck   *psz = ptr;
3611c2c66affSColin Finck }
3612c2c66affSColin Finck 
3613c2c66affSColin Finck 
3614c2c66affSColin Finck //
3615c2c66affSColin Finck // This function is written by sang cho
3616c2c66affSColin Finck //                                                         October 14, 1997
3617c2c66affSColin Finck //
3618c2c66affSColin Finck /* print contents of dialog */
3619c2c66affSColin Finck void WINAPI
PrintDialog(char ** psz)3620c2c66affSColin Finck PrintDialog (
3621c2c66affSColin Finck 	      char **psz)
3622c2c66affSColin Finck {
3623c2c66affSColin Finck   int i/*, j, k, l, n, c*/;
3624c2c66affSColin Finck   int num, size;
3625c2c66affSColin Finck   DWORD flag;
3626c2c66affSColin Finck   WORD class;
3627c2c66affSColin Finck   //char buff[32];
3628c2c66affSColin Finck   char *ptr, *pmax;
3629c2c66affSColin Finck   BOOL isStrange = FALSE;
3630c2c66affSColin Finck 
3631c2c66affSColin Finck   ptr = *psz;
3632c2c66affSColin Finck   size = *(int *) ptr;
3633c2c66affSColin Finck   ptr += 4;
3634c2c66affSColin Finck   pmax = ptr + size;
3635c2c66affSColin Finck 
3636c2c66affSColin Finck   // IStype of Dialog Header
3637c2c66affSColin Finck   flag = *(DWORD *) ptr;
3638c2c66affSColin Finck   //
3639c2c66affSColin Finck   // check if flag is right or not
3640c2c66affSColin Finck   // it has been observed that some dialog information is strange
3641c2c66affSColin Finck   // and extra work is needed to fix that ... so let's try something
3642c2c66affSColin Finck   //
3643c2c66affSColin Finck 
3644c2c66affSColin Finck   if ((flag & 0xFFFF0000) == 0xFFFF0000)
3645c2c66affSColin Finck     {
3646c2c66affSColin Finck       flag = *(DWORD *) (ptr + 12);
3647c2c66affSColin Finck       num = *(short *) (ptr + 16);
3648c2c66affSColin Finck       isStrange = TRUE;
3649c2c66affSColin Finck       ptr += 26;
3650c2c66affSColin Finck     }
3651c2c66affSColin Finck   else
3652c2c66affSColin Finck     {
3653c2c66affSColin Finck       num = *(short *) (ptr + 8);
3654c2c66affSColin Finck       ptr += 18;
3655c2c66affSColin Finck     }
3656c2c66affSColin Finck   printf (", # of Controls=%03d, Caption:%c", num, '"');
3657c2c66affSColin Finck 
3658c2c66affSColin Finck   // Menu name
3659c2c66affSColin Finck   if (*(WORD *) ptr == 0xFFFF)
3660c2c66affSColin Finck     ptr += 4;			// ordinal
3661c2c66affSColin Finck 
3662c2c66affSColin Finck   else
3663c2c66affSColin Finck     {
3664c2c66affSColin Finck       while (*(WORD *) ptr)
3665c2c66affSColin Finck 	ptr += 2;
3666c2c66affSColin Finck       ptr += 2;
3667c2c66affSColin Finck     }				// name
3668c2c66affSColin Finck 
3669c2c66affSColin Finck   // Class name
3670c2c66affSColin Finck   if (*(WORD *) ptr == 0xFFFF)
3671c2c66affSColin Finck     ptr += 4;			// ordinal
3672c2c66affSColin Finck 
3673c2c66affSColin Finck   else
3674c2c66affSColin Finck     {
3675c2c66affSColin Finck       while (*(WORD *) ptr)
3676c2c66affSColin Finck 	ptr += 2;
3677c2c66affSColin Finck       ptr += 2;
3678c2c66affSColin Finck     }				// name
3679c2c66affSColin Finck 
3680c2c66affSColin Finck   // Caption
3681c2c66affSColin Finck   while (*(WORD *) ptr)
3682c2c66affSColin Finck     {
3683c2c66affSColin Finck       printf ("%c", *ptr);
3684c2c66affSColin Finck       ptr += 2;
3685c2c66affSColin Finck     }
3686c2c66affSColin Finck   ptr += 2;
3687c2c66affSColin Finck   printf ("%c", '"');
3688c2c66affSColin Finck 
3689c2c66affSColin Finck   // FONT present
3690c2c66affSColin Finck   if (flag & 0x00000040)
3691c2c66affSColin Finck     {
3692c2c66affSColin Finck       if (isStrange)
3693c2c66affSColin Finck 	ptr += 6;
3694c2c66affSColin Finck       else
3695c2c66affSColin Finck 	ptr += 2;		// FONT size
3696c2c66affSColin Finck 
3697c2c66affSColin Finck       while (*(WORD *) ptr)
3698c2c66affSColin Finck 	ptr += 2;		// WCHARs
3699c2c66affSColin Finck 
3700c2c66affSColin Finck       ptr += 2;			// double null
3701c2c66affSColin Finck 
3702c2c66affSColin Finck     }
3703c2c66affSColin Finck 
3704c2c66affSColin Finck   // strange case adjust
3705c2c66affSColin Finck   if (isStrange)
3706c2c66affSColin Finck     ptr += 8;
3707c2c66affSColin Finck 
3708c2c66affSColin Finck   // DWORD padding
3709c2c66affSColin Finck   if ((ptr - *psz) % 4)
3710c2c66affSColin Finck     ptr += 4 - ((ptr - *psz) % 4);
3711c2c66affSColin Finck 
3712c2c66affSColin Finck   // start reporting .. finally
3713c2c66affSColin Finck   for (i = 0; i < num; i++)
3714c2c66affSColin Finck     {
3715c2c66affSColin Finck       flag = *(DWORD *) ptr;
3716c2c66affSColin Finck       if (isStrange)
3717c2c66affSColin Finck 	ptr += 14;
3718c2c66affSColin Finck       else
3719c2c66affSColin Finck 	ptr += 16;
3720c2c66affSColin Finck       printf ("\n     Control::%03d - ID:", i + 1);
3721c2c66affSColin Finck 
3722c2c66affSColin Finck       // Control ID
3723c2c66affSColin Finck       printf ("%04X, Class:", *(WORD *) ptr);
3724c2c66affSColin Finck       ptr += 2;
3725c2c66affSColin Finck 
3726c2c66affSColin Finck       // Control Class
3727c2c66affSColin Finck       if (*(WORD *) ptr == 0xFFFF)
3728c2c66affSColin Finck 	{
3729c2c66affSColin Finck 	  ptr += 2;
3730c2c66affSColin Finck 	  class = *(WORD *) ptr;
3731c2c66affSColin Finck 	  ptr += 2;
3732c2c66affSColin Finck 	  switch (class)
3733c2c66affSColin Finck 	    {
3734c2c66affSColin Finck 	    case 0x80:
3735c2c66affSColin Finck 	      printf ("BUTTON   ");
3736c2c66affSColin Finck 	      break;
3737c2c66affSColin Finck 	    case 0x81:
3738c2c66affSColin Finck 	      printf ("EDIT     ");
3739c2c66affSColin Finck 	      break;
3740c2c66affSColin Finck 	    case 0x82:
3741c2c66affSColin Finck 	      printf ("STATIC   ");
3742c2c66affSColin Finck 	      break;
3743c2c66affSColin Finck 	    case 0x83:
3744c2c66affSColin Finck 	      printf ("LISTBOX  ");
3745c2c66affSColin Finck 	      break;
3746c2c66affSColin Finck 	    case 0x84:
3747c2c66affSColin Finck 	      printf ("SCROLLBAR");
3748c2c66affSColin Finck 	      break;
3749c2c66affSColin Finck 	    case 0x85:
3750c2c66affSColin Finck 	      printf ("COMBOBOX ");
3751c2c66affSColin Finck 	      break;
3752c2c66affSColin Finck 	    default:
3753c2c66affSColin Finck 	      printf ("%04X     ", class);
3754c2c66affSColin Finck 	      break;
3755c2c66affSColin Finck 	    }
3756c2c66affSColin Finck 	}
3757c2c66affSColin Finck       else
3758c2c66affSColin Finck 	PrintNameOrOrdinal (&ptr);
3759c2c66affSColin Finck 
3760c2c66affSColin Finck       printf (" Text:");
3761c2c66affSColin Finck 
3762c2c66affSColin Finck       // Text
3763c2c66affSColin Finck       PrintNameOrOrdinal (&ptr);
3764c2c66affSColin Finck 
3765c2c66affSColin Finck       // nExtraStuff
3766c2c66affSColin Finck       ptr += 2;
3767c2c66affSColin Finck 
3768c2c66affSColin Finck       // strange case adjust
3769c2c66affSColin Finck       if (isStrange)
3770c2c66affSColin Finck 	ptr += 8;
3771c2c66affSColin Finck 
3772c2c66affSColin Finck       // DWORD padding
3773c2c66affSColin Finck       if ((ptr - *psz) % 4)
3774c2c66affSColin Finck 	ptr += 4 - ((ptr - *psz) % 4);
3775c2c66affSColin Finck     }
3776c2c66affSColin Finck 
3777c2c66affSColin Finck   /*
3778c2c66affSColin Finck      ptr = *psz;
3779c2c66affSColin Finck      printf("\n");
3780c2c66affSColin Finck 
3781c2c66affSColin Finck      for (i=0; i<(size/16)+1; i++)
3782c2c66affSColin Finck      {
3783c2c66affSColin Finck      n = 0;
3784c2c66affSColin Finck      for (j=0; j<16; j++)
3785c2c66affSColin Finck      {
3786c2c66affSColin Finck      c = (int)(*ptr);
3787c2c66affSColin Finck      if (c<0) c+=256;
3788c2c66affSColin Finck      buff[j] = c;
3789c2c66affSColin Finck      printf ("%02X",c);
3790c2c66affSColin Finck      ptr++;
3791c2c66affSColin Finck      if (ptr >= pmax) break;
3792c2c66affSColin Finck      n++;
3793c2c66affSColin Finck      if (n%4 == 0) printf (" ");
3794c2c66affSColin Finck      }
3795c2c66affSColin Finck      n++; if (n%4 == 0) printf (" ");
3796c2c66affSColin Finck      l = j;
3797c2c66affSColin Finck      j++;
3798c2c66affSColin Finck      for (; j<16; j++)
3799c2c66affSColin Finck      { n++; if (n%4 == 0) printf ("   "); else printf ("  "); }
3800c2c66affSColin Finck      printf ("   ");
3801c2c66affSColin Finck      for (k=0; k<l; k++)
3802c2c66affSColin Finck      if (isprint(c=buff[k])) printf("%c", c); else printf(".");
3803c2c66affSColin Finck      printf ("\n");
3804c2c66affSColin Finck      if (ptr >= pmax) break;
3805c2c66affSColin Finck      }
3806c2c66affSColin Finck    */
3807c2c66affSColin Finck 
3808c2c66affSColin Finck   *psz = pmax;
3809c2c66affSColin Finck 
3810c2c66affSColin Finck }
3811c2c66affSColin Finck 
3812c2c66affSColin Finck 
3813c2c66affSColin Finck 
3814c2c66affSColin Finck 
3815c2c66affSColin Finck 
3816c2c66affSColin Finck 
3817c2c66affSColin Finck /* function indicates whether debug  info has been stripped from file */
3818c2c66affSColin Finck BOOL WINAPI
IsDebugInfoStripped(LPVOID lpFile)3819c2c66affSColin Finck IsDebugInfoStripped (
3820c2c66affSColin Finck 		      LPVOID lpFile)
3821c2c66affSColin Finck {
3822c2c66affSColin Finck   PIMAGE_FILE_HEADER pfh;
3823c2c66affSColin Finck 
3824c2c66affSColin Finck   pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
3825c2c66affSColin Finck 
3826c2c66affSColin Finck   return (pfh->Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
3827c2c66affSColin Finck }
3828c2c66affSColin Finck 
3829c2c66affSColin Finck 
3830c2c66affSColin Finck 
3831c2c66affSColin Finck 
3832c2c66affSColin Finck /* retrieve the module name from the debug misc. structure */
3833c2c66affSColin Finck int WINAPI
RetrieveModuleName(LPVOID lpFile,char ** pszModule)3834c2c66affSColin Finck RetrieveModuleName (
3835c2c66affSColin Finck 		     LPVOID lpFile,
3836c2c66affSColin Finck 		     char **pszModule)
3837c2c66affSColin Finck {
3838c2c66affSColin Finck 
3839c2c66affSColin Finck   PIMAGE_DEBUG_DIRECTORY pdd;
3840c2c66affSColin Finck   PIMAGE_DEBUG_MISC pdm = NULL;
3841c2c66affSColin Finck   int nCnt;
3842c2c66affSColin Finck 
3843c2c66affSColin Finck   if (!(pdd = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_DEBUG)))
3844c2c66affSColin Finck     return 0;
3845c2c66affSColin Finck 
3846c2c66affSColin Finck   while (pdd->SizeOfData)
3847c2c66affSColin Finck     {
3848c2c66affSColin Finck       if (pdd->Type == IMAGE_DEBUG_TYPE_MISC)
3849c2c66affSColin Finck 	{
3850c2c66affSColin Finck 	  pdm = (PIMAGE_DEBUG_MISC) ((DWORD) pdd->PointerToRawData + (DWORD) lpFile);
3851c2c66affSColin Finck 	  *pszModule = (char *) calloc ((nCnt = (strlen ((char *)pdm->Data))) + 1, 1);
3852c2c66affSColin Finck 	  // may need some unicode business here...above
3853c2c66affSColin Finck 	  bcopy (pdm->Data, *pszModule, nCnt);
3854c2c66affSColin Finck 
3855c2c66affSColin Finck 	  break;
3856c2c66affSColin Finck 	}
3857c2c66affSColin Finck 
3858c2c66affSColin Finck       pdd++;
3859c2c66affSColin Finck     }
3860c2c66affSColin Finck 
3861c2c66affSColin Finck   if (pdm != NULL)
3862c2c66affSColin Finck     return nCnt;
3863c2c66affSColin Finck   else
3864c2c66affSColin Finck     return 0;
3865c2c66affSColin Finck }
3866c2c66affSColin Finck 
3867c2c66affSColin Finck 
3868c2c66affSColin Finck 
3869c2c66affSColin Finck 
3870c2c66affSColin Finck 
3871c2c66affSColin Finck /* determine if this is a valid debug file */
3872c2c66affSColin Finck BOOL WINAPI
IsDebugFile(LPVOID lpFile)3873c2c66affSColin Finck IsDebugFile (
3874c2c66affSColin Finck 	      LPVOID lpFile)
3875c2c66affSColin Finck {
3876c2c66affSColin Finck   PIMAGE_SEPARATE_DEBUG_HEADER psdh;
3877c2c66affSColin Finck 
3878c2c66affSColin Finck   psdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3879c2c66affSColin Finck 
3880c2c66affSColin Finck   return (psdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE);
3881c2c66affSColin Finck }
3882c2c66affSColin Finck 
3883c2c66affSColin Finck 
3884c2c66affSColin Finck 
3885c2c66affSColin Finck 
3886c2c66affSColin Finck /* copy separate debug header structure from debug file */
3887c2c66affSColin Finck BOOL WINAPI
GetSeparateDebugHeader(LPVOID lpFile,PIMAGE_SEPARATE_DEBUG_HEADER psdh)3888c2c66affSColin Finck GetSeparateDebugHeader (
3889c2c66affSColin Finck 			 LPVOID lpFile,
3890c2c66affSColin Finck 			 PIMAGE_SEPARATE_DEBUG_HEADER psdh)
3891c2c66affSColin Finck {
3892c2c66affSColin Finck   PIMAGE_SEPARATE_DEBUG_HEADER pdh;
3893c2c66affSColin Finck 
3894c2c66affSColin Finck   pdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3895c2c66affSColin Finck 
3896c2c66affSColin Finck   if (pdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
3897c2c66affSColin Finck     {
3898c2c66affSColin Finck       bcopy ((LPVOID) pdh, (LPVOID) psdh, sizeof (IMAGE_SEPARATE_DEBUG_HEADER));
3899c2c66affSColin Finck       return TRUE;
3900c2c66affSColin Finck     }
3901c2c66affSColin Finck 
3902c2c66affSColin Finck   return FALSE;
3903c2c66affSColin Finck }
3904c2c66affSColin Finck 
3905c2c66affSColin Finck //
3906c2c66affSColin Finck // I tried to immitate the output of w32dasm disassembler.
3907c2c66affSColin Finck // which is a pretty good program.
3908c2c66affSColin Finck // but I am disappointed with this program and I myself
3909*9f784c65SRatin Gao // am writing a disassembler.
3910c2c66affSColin Finck // This PEdump program is a byproduct of that project.
3911c2c66affSColin Finck // so enjoy this program and I hope we will have a little more
3912c2c66affSColin Finck // knowledge on windows programming world.
3913c2c66affSColin Finck //                                                        .... sang cho
3914c2c66affSColin Finck 
3915c2c66affSColin Finck #define  MAXSECTIONNUMBER 16
3916c2c66affSColin Finck #define  MAXNAMESTRNUMBER 40
3917c2c66affSColin Finck int
main(int argc,char ** argv)3918c2c66affSColin Finck main (
3919c2c66affSColin Finck        int argc,
3920c2c66affSColin Finck        char **argv
3921c2c66affSColin Finck )
3922c2c66affSColin Finck {
3923c2c66affSColin Finck   DWORD fileType;
3924c2c66affSColin Finck   LPVOID lpFile;
3925c2c66affSColin Finck   FILE *my_fp;
3926c2c66affSColin Finck   IMAGE_DOS_HEADER dosHdr;
3927c2c66affSColin Finck   PIMAGE_FILE_HEADER pfh;
3928c2c66affSColin Finck   PIMAGE_OPTIONAL_HEADER poh;
3929c2c66affSColin Finck   PIMAGE_SECTION_HEADER psh;
3930c2c66affSColin Finck   //IMAGE_SECTION_HEADER idsh;
3931c2c66affSColin Finck   IMAGE_SECTION_HEADER shdr[MAXSECTIONNUMBER];
3932c2c66affSColin Finck   //PIMAGE_IMPORT_MODULE_DIRECTORY pid;
3933c2c66affSColin Finck 
3934c2c66affSColin Finck   int nSections;		// number of sections
3935c2c66affSColin Finck 
3936c2c66affSColin Finck   int nResources;		// number of resources
3937c2c66affSColin Finck 
3938c2c66affSColin Finck   int nMenus;			// number of menus
3939c2c66affSColin Finck 
3940c2c66affSColin Finck   int nDialogs;			// number of dialogs
3941c2c66affSColin Finck 
3942c2c66affSColin Finck   int nImportedModules;		// number of imported modules
3943c2c66affSColin Finck 
3944c2c66affSColin Finck   int nFunctions;		// number of functions in the imported module
3945c2c66affSColin Finck 
3946c2c66affSColin Finck   int nExportedFunctions;	// number of exported funcions
3947c2c66affSColin Finck 
3948c2c66affSColin Finck   int imageBase;
3949c2c66affSColin Finck   int entryPoint;
3950c2c66affSColin Finck 
3951c2c66affSColin Finck   int i, j, /*k,*/ n;
3952c2c66affSColin Finck   //int mnsize;
3953c2c66affSColin Finck   //int nCnt;
3954c2c66affSColin Finck   //int nSize;
3955c2c66affSColin Finck   int fsize;
3956c2c66affSColin Finck   char *pnstr;
3957c2c66affSColin Finck   char *pst;
3958c2c66affSColin Finck   char *piNameBuff;		// import module name buffer
3959c2c66affSColin Finck 
3960c2c66affSColin Finck   char *pfNameBuff;		// import functions in the module name buffer
3961c2c66affSColin Finck 
3962c2c66affSColin Finck   char *peNameBuff;		// export function name buffer
3963c2c66affSColin Finck 
3964c2c66affSColin Finck   char *pmNameBuff;		// menu name buffer
3965c2c66affSColin Finck 
3966c2c66affSColin Finck   char *pdNameBuff;		// dialog name buffer
3967c2c66affSColin Finck 
3968c2c66affSColin Finck   /*
3969c2c66affSColin Finck    * Check user arguments.
3970c2c66affSColin Finck    */
3971c2c66affSColin Finck   if (2 == argc)
3972c2c66affSColin Finck     {
3973c2c66affSColin Finck       my_fp = fopen (argv[1], "rb");
3974c2c66affSColin Finck       if (my_fp == NULL)
3975c2c66affSColin Finck 	{
3976c2c66affSColin Finck 	  printf (
3977c2c66affSColin Finck 		   "%s: can not open input file \"%s\".\n",
3978c2c66affSColin Finck 		   argv[0],
3979c2c66affSColin Finck 		   argv[1]
3980c2c66affSColin Finck 	    );
3981c2c66affSColin Finck 	  exit (0);
3982c2c66affSColin Finck 	}
3983c2c66affSColin Finck     }
3984c2c66affSColin Finck   else
3985c2c66affSColin Finck     {
3986c2c66affSColin Finck       printf (
3987c2c66affSColin Finck 	       "%s - PE/COFF file dumper\n"
3988c2c66affSColin Finck 	       "Copyright (c) 1993 Randy Kath (MSDN Technology Group)\n"
3989c2c66affSColin Finck       "Copyright (c) 1997 Sang Cho (CS & Engineering - Chongju University)\n"
3990c2c66affSColin Finck       "Copyright (c) 2000 Emanuele Aliberti (ReactOS Development Team)\n\n",
3991c2c66affSColin Finck 	       argv[0]
3992c2c66affSColin Finck 	);
3993c2c66affSColin Finck       printf (
3994c2c66affSColin Finck 	       "usage: %s input_file_name\n",
3995c2c66affSColin Finck 	       argv[0]
3996c2c66affSColin Finck 	);
3997c2c66affSColin Finck       exit (0);
3998c2c66affSColin Finck     }
3999c2c66affSColin Finck   /*
4000c2c66affSColin Finck    * Get input file's size.
4001c2c66affSColin Finck    */
4002c2c66affSColin Finck   /* argv [0], */
4003c2c66affSColin Finck   fseek (my_fp, 0L, SEEK_END);
4004c2c66affSColin Finck   fsize = ftell (my_fp);
4005c2c66affSColin Finck   rewind (my_fp);
4006c2c66affSColin Finck   /*
4007c2c66affSColin Finck    * Buffer the file in memory.
4008c2c66affSColin Finck    */
4009c2c66affSColin Finck   lpFile = (void *) calloc (fsize, 1);
4010c2c66affSColin Finck   if (lpFile == NULL)
4011c2c66affSColin Finck     {
4012c2c66affSColin Finck       printf (
4013c2c66affSColin Finck 	       "%s: can not allocate memory.\n",
4014c2c66affSColin Finck 	       argv[0]
4015c2c66affSColin Finck 	);
4016c2c66affSColin Finck       fclose(my_fp);
4017c2c66affSColin Finck       exit (0);
4018c2c66affSColin Finck     }
4019c2c66affSColin Finck   /*
4020c2c66affSColin Finck    * --- Start of report ---
4021c2c66affSColin Finck    */
4022c2c66affSColin Finck   printf ("\n\nDump of file: %s\n\n", argv[1]);
4023c2c66affSColin Finck 
4024c2c66affSColin Finck   n = fread (lpFile, fsize, 1, my_fp);
4025c2c66affSColin Finck   fclose(my_fp);
4026c2c66affSColin Finck 
4027c2c66affSColin Finck   if (n == -1)
4028c2c66affSColin Finck     {
4029c2c66affSColin Finck       printf (
4030c2c66affSColin Finck 	       "%s: failed to read the file \"%s\".\n",
4031c2c66affSColin Finck 	       argv[0],
4032c2c66affSColin Finck 	       argv[1]
4033c2c66affSColin Finck 	);
4034c2c66affSColin Finck       free(lpFile);
4035c2c66affSColin Finck       exit (0);
4036c2c66affSColin Finck     }
4037c2c66affSColin Finck 
4038c2c66affSColin Finck   GetDosHeader (lpFile, &dosHdr);
4039c2c66affSColin Finck 
4040c2c66affSColin Finck   if ((WORD) IMAGE_DOS_SIGNATURE == dosHdr.e_magic)
4041c2c66affSColin Finck     {
4042c2c66affSColin Finck       if ((dosHdr.e_lfanew > 4096)
4043c2c66affSColin Finck 	  || (dosHdr.e_lfanew < 64)
4044c2c66affSColin Finck 	)
4045c2c66affSColin Finck 	{
4046c2c66affSColin Finck 	  printf (
4047c2c66affSColin Finck 		   "%s: This file is not in PE format; it looks like in DOS format.\n",
4048c2c66affSColin Finck 		   argv[0]
4049c2c66affSColin Finck 	    );
4050c2c66affSColin Finck       free(lpFile);
4051c2c66affSColin Finck 	  exit (0);
4052c2c66affSColin Finck 	}
4053c2c66affSColin Finck     }
4054c2c66affSColin Finck   else
4055c2c66affSColin Finck     {
4056c2c66affSColin Finck       printf (
4057c2c66affSColin Finck 	"%s: This doesn't look like an executable file (magic = 0x%04x).\n",
4058c2c66affSColin Finck 	       argv[0],
4059c2c66affSColin Finck 	       dosHdr.e_magic
4060c2c66affSColin Finck 	);
4061c2c66affSColin Finck       free(lpFile);
4062c2c66affSColin Finck       exit (0);
4063c2c66affSColin Finck     }
4064c2c66affSColin Finck 
4065c2c66affSColin Finck   fileType = ImageFileType (lpFile);
4066c2c66affSColin Finck 
4067c2c66affSColin Finck   if (fileType != IMAGE_NT_SIGNATURE)
4068c2c66affSColin Finck     {
4069c2c66affSColin Finck       printf (
4070c2c66affSColin Finck 	       "%s: This file is not in PE format (magic = 0x%08lx).\n",
4071c2c66affSColin Finck 	       argv[0],
4072c2c66affSColin Finck 	       fileType
4073c2c66affSColin Finck 	);
4074c2c66affSColin Finck       free(lpFile);
4075c2c66affSColin Finck       exit (0);
4076c2c66affSColin Finck     }
4077c2c66affSColin Finck 
4078c2c66affSColin Finck   //=====================================
4079c2c66affSColin Finck   // now we can really start processing
4080c2c66affSColin Finck   //=====================================
4081c2c66affSColin Finck 
4082c2c66affSColin Finck   pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
4083c2c66affSColin Finck 
4084c2c66affSColin Finck   poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
4085c2c66affSColin Finck 
4086c2c66affSColin Finck   psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
4087c2c66affSColin Finck 
4088c2c66affSColin Finck   nSections = pfh->NumberOfSections;
4089c2c66affSColin Finck 
4090c2c66affSColin Finck   imageBase = poh->ImageBase;
4091c2c66affSColin Finck 
4092c2c66affSColin Finck   entryPoint = poh->AddressOfEntryPoint;
4093c2c66affSColin Finck 
4094c2c66affSColin Finck   if (psh == NULL)
4095c2c66affSColin Finck   {
4096c2c66affSColin Finck     free(lpFile);
4097c2c66affSColin Finck     return 0;
4098c2c66affSColin Finck   }
4099c2c66affSColin Finck 
4100c2c66affSColin Finck   /* store section headers */
4101c2c66affSColin Finck 
4102c2c66affSColin Finck   for (i = 0;
4103c2c66affSColin Finck        i < nSections;
4104c2c66affSColin Finck        i++
4105c2c66affSColin Finck     )
4106c2c66affSColin Finck     {
4107c2c66affSColin Finck       shdr[i] = *psh++;
4108c2c66affSColin Finck     }
4109c2c66affSColin Finck   /*
4110c2c66affSColin Finck    * Get Code offset and size,
4111c2c66affSColin Finck    * Data offset and size.
4112c2c66affSColin Finck    */
4113c2c66affSColin Finck   for (i = 0;
4114c2c66affSColin Finck        i < nSections;
4115c2c66affSColin Finck        i++
4116c2c66affSColin Finck     )
4117c2c66affSColin Finck     {
4118c2c66affSColin Finck       if (poh->BaseOfCode == shdr[i].VirtualAddress)
4119c2c66affSColin Finck 	{
4120c2c66affSColin Finck 	  printf (
4121c2c66affSColin Finck 		   "Code Offset = %08lX, Code Size = %08lX \n",
4122c2c66affSColin Finck 		   shdr[i].PointerToRawData,
4123c2c66affSColin Finck 		   shdr[i].SizeOfRawData
4124c2c66affSColin Finck 	    );
4125c2c66affSColin Finck 	}
4126c2c66affSColin Finck       if (((shdr[i].Characteristics) & 0xC0000040) == 0xC0000040)
4127c2c66affSColin Finck 	{
4128c2c66affSColin Finck 	  printf (
4129c2c66affSColin Finck 		   "Data Offset = %08lX, Data Size = %08lX \n",
4130c2c66affSColin Finck 		   shdr[i].PointerToRawData,
4131c2c66affSColin Finck 		   shdr[i].SizeOfRawData
4132c2c66affSColin Finck 	    );
4133c2c66affSColin Finck 	  break;
4134c2c66affSColin Finck 	}
4135c2c66affSColin Finck     }
4136c2c66affSColin Finck 
4137c2c66affSColin Finck   printf ("\n");
4138c2c66affSColin Finck 
4139c2c66affSColin Finck   printf (
4140c2c66affSColin Finck 	   "Number of Objects = %04d (dec), Imagebase = %08Xh \n",
4141c2c66affSColin Finck 	   nSections,
4142c2c66affSColin Finck 	   imageBase
4143c2c66affSColin Finck     );
4144c2c66affSColin Finck   /*
4145c2c66affSColin Finck    * Object name alignment.
4146c2c66affSColin Finck    */
4147c2c66affSColin Finck   for (i = 0;
4148c2c66affSColin Finck        i < nSections;
4149c2c66affSColin Finck        i++
4150c2c66affSColin Finck     )
4151c2c66affSColin Finck     {
4152c2c66affSColin Finck       for (j = 0;
4153c2c66affSColin Finck 	   j < 7;
4154c2c66affSColin Finck 	   j++
4155c2c66affSColin Finck 	)
4156c2c66affSColin Finck 	{
4157c2c66affSColin Finck 	  if (shdr[i].Name[j] == 0)
4158c2c66affSColin Finck 	    {
4159c2c66affSColin Finck 	      shdr[i].Name[j] = 32;
4160c2c66affSColin Finck 	    }
4161c2c66affSColin Finck 	}
4162c2c66affSColin Finck       shdr[i].Name[7] = 0;
4163c2c66affSColin Finck     }
4164c2c66affSColin Finck   for (i = 0; i < nSections; i++)
4165c2c66affSColin Finck     printf ("\n   Object%02d: %8s RVA: %08lX Offset: %08lX Size: %08lX Flags: %08lX ",
4166c2c66affSColin Finck       i + 1, shdr[i].Name, shdr[i].VirtualAddress, shdr[i].PointerToRawData,
4167c2c66affSColin Finck 	    shdr[i].SizeOfRawData, shdr[i].Characteristics);
4168c2c66affSColin Finck   /*
4169c2c66affSColin Finck    * Get List of Resources.
4170c2c66affSColin Finck    */
4171c2c66affSColin Finck   nResources = GetListOfResourceTypes (lpFile, &pnstr);
4172c2c66affSColin Finck   pst = pnstr;
4173c2c66affSColin Finck   printf ("\n");
4174c2c66affSColin Finck   printf ("\n+++++++++++++++++++ RESOURCE INFORMATION +++++++++++++++++++");
4175c2c66affSColin Finck   printf ("\n");
4176c2c66affSColin Finck   if (nResources == 0)
4177c2c66affSColin Finck     printf ("\n        There are no Resources in This Application.\n");
4178c2c66affSColin Finck   else
4179c2c66affSColin Finck     {
4180c2c66affSColin Finck       printf ("\nNumber of Resource Types = %4d (decimal)\n", nResources);
4181c2c66affSColin Finck       for (i = 0; i < nResources; i++)
4182c2c66affSColin Finck 	{
4183c2c66affSColin Finck 	  printf ("\n   Resource Type %03d: %s", i + 1, pst);
4184c2c66affSColin Finck 	  pst += strlen ((char *) (pst)) + 1;
4185c2c66affSColin Finck 	}
4186c2c66affSColin Finck       free ((void *) pnstr);
4187c2c66affSColin Finck 
4188c2c66affSColin Finck       printf ("\n");
4189c2c66affSColin Finck       printf ("\n+++++++++++++++++++ MENU INFORMATION +++++++++++++++++++");
4190c2c66affSColin Finck       printf ("\n");
4191c2c66affSColin Finck 
4192c2c66affSColin Finck       nMenus = GetContentsOfMenu (lpFile, &pmNameBuff);
4193c2c66affSColin Finck 
4194c2c66affSColin Finck       if (nMenus == 0)
4195c2c66affSColin Finck 	{
4196c2c66affSColin Finck 	  printf ("\n        There are no Menus in This Application.\n");
4197c2c66affSColin Finck 	}
4198c2c66affSColin Finck       else
4199c2c66affSColin Finck 	{
4200c2c66affSColin Finck 	  pst = pmNameBuff;
4201c2c66affSColin Finck 	  printf ("\nNumber of Menus = %4d (decimal)", nMenus);
4202c2c66affSColin Finck 
4203c2c66affSColin Finck 	  //dumpMenu(&pst, 8096);
4204c2c66affSColin Finck 	  for (i = 0; i < nMenus; i++)
4205c2c66affSColin Finck 	    {
4206c2c66affSColin Finck 	      // menu ID print
4207c2c66affSColin Finck 	      printf ("\n\n%s", pst);
4208c2c66affSColin Finck 	      pst += strlen (pst) + 1;
4209c2c66affSColin Finck 	      printf ("\n-------------");
4210c2c66affSColin Finck 	      if (strncmp (pst, ":::::::::::", 11) == 0)
4211c2c66affSColin Finck 		{
4212c2c66affSColin Finck 		  printf ("\n");
4213c2c66affSColin Finck 		  PrintStrangeMenu (&pst);
4214c2c66affSColin Finck 		}
4215c2c66affSColin Finck 	      else
4216c2c66affSColin Finck 		{
4217c2c66affSColin Finck 		  PrintMenu (6, &pst);
4218c2c66affSColin Finck 		}
4219c2c66affSColin Finck 	      //else PrintStrangeMenu(&pst);
4220c2c66affSColin Finck 	    }
4221c2c66affSColin Finck 	  free ((void *) pmNameBuff);
4222c2c66affSColin Finck 	  printf ("\n");
4223c2c66affSColin Finck 	}
4224c2c66affSColin Finck 
4225c2c66affSColin Finck       printf ("\n");
4226c2c66affSColin Finck       printf ("\n+++++++++++++++++ DIALOG INFORMATION +++++++++++++++++++");
4227c2c66affSColin Finck       printf ("\n");
4228c2c66affSColin Finck 
4229c2c66affSColin Finck       nDialogs = GetContentsOfDialog (lpFile, &pdNameBuff);
4230c2c66affSColin Finck 
4231c2c66affSColin Finck       if (nDialogs == 0)
4232c2c66affSColin Finck 	{
4233c2c66affSColin Finck 	  printf ("\n        There are no Dialogs in This Application.\n");
4234c2c66affSColin Finck 	}
4235c2c66affSColin Finck       else
4236c2c66affSColin Finck 	{
4237c2c66affSColin Finck 	  pst = pdNameBuff;
4238c2c66affSColin Finck 	  printf ("\nNumber of Dialogs = %4d (decimal)", nDialogs);
4239c2c66affSColin Finck 
4240c2c66affSColin Finck 	  printf ("\n");
4241c2c66affSColin Finck 
4242c2c66affSColin Finck 	  for (i = 0; i < nDialogs; i++)
4243c2c66affSColin Finck 	    {
4244c2c66affSColin Finck 	      // Dialog ID print
4245c2c66affSColin Finck 	      printf ("\nName: %s", pst);
4246c2c66affSColin Finck 	      pst += strlen (pst) + 1;
4247c2c66affSColin Finck 	      PrintDialog (&pst);
4248c2c66affSColin Finck 	    }
4249c2c66affSColin Finck 	  free ((void *) pdNameBuff);
4250c2c66affSColin Finck 	  printf ("\n");
4251c2c66affSColin Finck 	}
4252c2c66affSColin Finck     }
4253c2c66affSColin Finck 
4254c2c66affSColin Finck   printf ("\n+++++++++++++++++++ IMPORTED FUNCTIONS +++++++++++++++++++");
4255c2c66affSColin Finck 
4256c2c66affSColin Finck   nImportedModules = GetImportModuleNames (lpFile, &piNameBuff);
4257c2c66affSColin Finck   if (nImportedModules == 0)
4258c2c66affSColin Finck     {
4259c2c66affSColin Finck       printf ("\n        There are no imported Functions in This Application.\n");
4260c2c66affSColin Finck     }
4261c2c66affSColin Finck   else
4262c2c66affSColin Finck     {
4263c2c66affSColin Finck       pnstr = piNameBuff;
4264c2c66affSColin Finck       printf ("\nNumber of Imported Modules = %4d (decimal)\n", nImportedModules);
4265c2c66affSColin Finck       for (i = 0; i < nImportedModules; i++)
4266c2c66affSColin Finck 	{
4267c2c66affSColin Finck 	  printf ("\n   Import Module %03d: %s", i + 1, pnstr);
4268c2c66affSColin Finck 	  pnstr += strlen ((char *) (pnstr)) + 1;
4269c2c66affSColin Finck 	}
4270c2c66affSColin Finck 
4271c2c66affSColin Finck       printf ("\n");
4272c2c66affSColin Finck       printf ("\n+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++++");
4273c2c66affSColin Finck       pnstr = piNameBuff;
4274c2c66affSColin Finck       for (i = 0; i < nImportedModules; i++)
4275c2c66affSColin Finck 	{
4276c2c66affSColin Finck 	  printf ("\n\n   Import Module %03d: %s \n", i + 1, pnstr);
4277c2c66affSColin Finck 	  nFunctions = GetImportFunctionNamesByModule (lpFile, pnstr, &pfNameBuff);
4278c2c66affSColin Finck 	  pnstr += strlen ((char *) (pnstr)) + 1;
4279c2c66affSColin Finck 	  pst = pfNameBuff;
4280c2c66affSColin Finck 	  for (j = 0; j < nFunctions; j++)
4281c2c66affSColin Finck 	    {
4282c2c66affSColin Finck 	      printf ("\nAddr:%08X hint(%04X) Name: %s",
4283c2c66affSColin Finck 		      (*(int *) pst), (*(short *) (pst + 4)),
4284c2c66affSColin Finck 	      //(pst+6));
4285c2c66affSColin Finck 		      TranslateFunctionName (pst + 6));
4286c2c66affSColin Finck 	      pst += strlen ((char *) (pst + 6)) + 1 + 6;
4287c2c66affSColin Finck 	    }
4288c2c66affSColin Finck 	  free ((void *) pfNameBuff);
4289c2c66affSColin Finck 	}
4290c2c66affSColin Finck       free ((void *) piNameBuff);
4291c2c66affSColin Finck     }
4292c2c66affSColin Finck 
4293c2c66affSColin Finck   printf ("\n");
4294c2c66affSColin Finck   printf ("\n+++++++++++++++++++ EXPORTED FUNCTIONS +++++++++++++++++++");
4295c2c66affSColin Finck 
4296c2c66affSColin Finck   nExportedFunctions = GetExportFunctionNames (lpFile, &peNameBuff);
4297c2c66affSColin Finck   printf ("\nNumber of Exported Functions = %4d (decimal)\n", nExportedFunctions);
4298c2c66affSColin Finck 
4299c2c66affSColin Finck   if (nExportedFunctions > 0)
4300c2c66affSColin Finck     {
4301c2c66affSColin Finck       pst = peNameBuff;
4302c2c66affSColin Finck 
4303c2c66affSColin Finck       for (i = 0; i < nExportedFunctions; i++)
4304c2c66affSColin Finck 	{
4305c2c66affSColin Finck 	  printf ("\nAddr:%08X Ord:%4d (%04Xh) Name: %s",
4306c2c66affSColin Finck 	       (*(int *) pst), (*(WORD *) (pst + 4)), (*(WORD *) (pst + 4)),
4307c2c66affSColin Finck 	  //(pst+6));
4308c2c66affSColin Finck 		  TranslateFunctionName (pst + 6));
4309c2c66affSColin Finck 	  pst += strlen ((char *) (pst + 6)) + 6 + 1;
4310c2c66affSColin Finck 	}
4311c2c66affSColin Finck       free ((void *) peNameBuff);
4312c2c66affSColin Finck     }
4313c2c66affSColin Finck 
4314c2c66affSColin Finck   free ((void *) lpFile);
4315c2c66affSColin Finck 
4316c2c66affSColin Finck   return 0;
4317c2c66affSColin Finck }
4318c2c66affSColin Finck 
4319c2c66affSColin Finck 
4320c2c66affSColin Finck /* EOF */
4321