annotate loader/pe_image.c @ 15533:ddf15d233d58

Do not switch to audio tracks whose codec private data differs from the main audio track's as this will most likely result in messed up audio output. Patch by Michael Behrisch <list () behrisch ! de>
author mosu
date Sat, 21 May 2005 06:50:08 +0000
parents f5537cc95b02
children 3758536dcef3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
1 /*
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
2 * Copyright 1994 Eric Youndale & Erik Bos
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
3 * Copyright 1995 Martin von Löwis
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
4 * Copyright 1996-98 Marcus Meissner
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
5 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
6 * based on Eric Youndale's pe-test and:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
7 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
8 * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
9 * make that:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
10 * ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP
15166
f5537cc95b02 Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents: 13375
diff changeset
11 *
f5537cc95b02 Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents: 13375
diff changeset
12 * Modified for use with MPlayer, detailed CVS changelog at
f5537cc95b02 Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents: 13375
diff changeset
13 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
f5537cc95b02 Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents: 13375
diff changeset
14 * $Id$
f5537cc95b02 Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents: 13375
diff changeset
15 *
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
16 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
17 /* Notes:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
18 * Before you start changing something in this file be aware of the following:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
19 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
20 * - There are several functions called recursively. In a very subtle and
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
21 * obscure way. DLLs can reference each other recursively etc.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
22 * - If you want to enhance, speed up or clean up something in here, think
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
23 * twice WHY it is implemented in that strange way. There is usually a reason.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
24 * Though sometimes it might just be lazyness ;)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
25 * - In PE_MapImage, right before fixup_imports() all external and internal
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
26 * state MUST be correct since this function can be called with the SAME image
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
27 * AGAIN. (Thats recursion for you.) That means MODREF.module and
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
28 * NE_MODULE.module32.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
29 * - Sometimes, we can't use Linux mmap() to mmap() the images directly.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
30 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
31 * The problem is, that there is not direct 1:1 mapping from a diskimage and
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
32 * a memoryimage. The headers at the start are mapped linear, but the sections
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
33 * are not. Older x86 pe binaries are 512 byte aligned in file and 4096 byte
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
34 * aligned in memory. Linux likes them 4096 byte aligned in memory (due to
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
35 * x86 pagesize, this cannot be fixed without a rather large kernel rewrite)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
36 * and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
37 * and other byte blocksizes, we can't always do this. We *can* do this for
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
38 * newer pe binaries produced by MSVC 5 and later, since they are also aligned
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
39 * to 4096 byte boundaries on disk.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
40 */
2069
ce45cce7f7a5 sync with avifile
arpi
parents: 1411
diff changeset
41 #include "config.h"
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
42
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
43 #include <errno.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
44 #include <assert.h>
1307
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
45 #include <stdio.h>
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
46 #include <stdlib.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
47 #include <string.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
48 #include <unistd.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
49 #include <sys/types.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
50 #include <sys/stat.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
51 #include <fcntl.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
52 #ifdef HAVE_SYS_MMAN_H
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
53 #include <sys/mman.h>
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
54 #endif
7386
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
55 #include "wine/windef.h"
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
56 #include "wine/winbase.h"
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
57 #include "wine/winerror.h"
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
58 #include "wine/heap.h"
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
59 #include "wine/pe_image.h"
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
60 #include "wine/module.h"
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
61 #include "wine/debugtools.h"
2069
ce45cce7f7a5 sync with avifile
arpi
parents: 1411
diff changeset
62 #include "ext.h"
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
63 #include "win32.h"
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
64
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
65 #define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
66
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
67 #define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
68
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
69 extern void* LookupExternal(const char* library, int ordinal);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
70 extern void* LookupExternalByName(const char* library, const char* name);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
71
1307
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
72 static void dump_exports( HMODULE hModule )
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
73 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
74 char *Module;
7386
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
75 unsigned int i, j;
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
76 u_short *ordinal;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
77 u_long *function,*functions;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
78 u_char **name;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
79 unsigned int load_addr = hModule;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
80
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
81 DWORD rva_start = PE_HEADER(hModule)->OptionalHeader
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
82 .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
83 DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
84 .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
85 IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
86
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
87 Module = (char*)RVA(pe_exports->Name);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
88 TRACE("*******EXPORT DATA*******\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
89 TRACE("Module name is %s, %ld functions, %ld names\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
90 Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
91
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
92 ordinal=(u_short*) RVA(pe_exports->AddressOfNameOrdinals);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
93 functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
94 name=(u_char**) RVA(pe_exports->AddressOfNames);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
95
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
96 TRACE(" Ord RVA Addr Name\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
97 for (i=0;i<pe_exports->NumberOfFunctions;i++, function++)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
98 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
99 if (!*function) continue;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
100 if (TRACE_ON(win32))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
101 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
102 DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, RVA(*function) );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
103
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
104 for (j = 0; j < pe_exports->NumberOfNames; j++)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
105 if (ordinal[j] == i)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
106 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
107 DPRINTF( " %s", (char*)RVA(name[j]) );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
108 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
109 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
110 if ((*function >= rva_start) && (*function <= rva_end))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
111 DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
112 DPRINTF("\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
113 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
114 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
115 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
116
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
117 /* Look up the specified function or ordinal in the exportlist:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
118 * If it is a string:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
119 * - look up the name in the Name list.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
120 * - look up the ordinal with that index.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
121 * - use the ordinal as offset into the functionlist
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
122 * If it is a ordinal:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
123 * - use ordinal-pe_export->Base as offset into the functionlist
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
124 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
125 FARPROC PE_FindExportedFunction(
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
126 WINE_MODREF *wm,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
127 LPCSTR funcName,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
128 WIN_BOOL snoop )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
129 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
130 u_short * ordinals;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
131 u_long * function;
7386
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
132 u_char ** name;
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
133 const char *ename = NULL;
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
134 int i, ordinal;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
135 PE_MODREF *pem = &(wm->binfmt.pe);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
136 IMAGE_EXPORT_DIRECTORY *exports = pem->pe_export;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
137 unsigned int load_addr = wm->module;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
138 u_long rva_start, rva_end, addr;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
139 char * forward;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
140
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
141 if (HIWORD(funcName))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
142 TRACE("(%s)\n",funcName);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
143 else
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
144 TRACE("(%d)\n",(int)funcName);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
145 if (!exports) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
146 /* Not a fatal problem, some apps do
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
147 * GetProcAddress(0,"RegisterPenApp") which triggers this
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
148 * case.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
149 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
150 WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
151 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
152 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
153 ordinals= (u_short*) RVA(exports->AddressOfNameOrdinals);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
154 function= (u_long*) RVA(exports->AddressOfFunctions);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
155 name = (u_char **) RVA(exports->AddressOfNames);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
156 forward = NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
157 rva_start = PE_HEADER(wm->module)->OptionalHeader
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
158 .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
159 rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
160 .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
161
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
162 if (HIWORD(funcName))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
163 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
164
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
165 int min = 0, max = exports->NumberOfNames - 1;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
166 while (min <= max)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
167 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
168 int res, pos = (min + max) / 2;
7386
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
169 ename = (const char*) RVA(name[pos]);
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
170 if (!(res = strcmp( ename, funcName )))
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
171 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
172 ordinal = ordinals[pos];
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
173 goto found;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
174 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
175 if (res > 0) max = pos - 1;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
176 else min = pos + 1;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
177 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
178
7386
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
179 for (i = 0; i < exports->NumberOfNames; i++)
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
180 {
7386
174e2a58b4cd avifile sync - 95% cosmetics 5% bug
arpi
parents: 2651
diff changeset
181 ename = (const char*) RVA(name[i]);
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
182 if (!strcmp( ename, funcName ))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
183 {
2069
ce45cce7f7a5 sync with avifile
arpi
parents: 1411
diff changeset
184 ERR( "%s.%s required a linear search\n", wm->modname, funcName );
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
185 ordinal = ordinals[i];
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
186 goto found;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
187 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
188 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
189 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
190 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
191 else
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
192 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
193 ordinal = LOWORD(funcName) - exports->Base;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
194 if (snoop && name)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
195 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
196 for (i = 0; i < exports->NumberOfNames; i++)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
197 if (ordinals[i] == ordinal)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
198 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
199 ename = RVA(name[i]);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
200 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
201 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
202 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
203 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
204
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
205 found:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
206 if (ordinal >= exports->NumberOfFunctions)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
207 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
208 TRACE(" ordinal %ld out of range!\n", ordinal + exports->Base );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
209 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
210 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
211 addr = function[ordinal];
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
212 if (!addr) return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
213 if ((addr < rva_start) || (addr >= rva_end))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
214 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
215 FARPROC proc = RVA(addr);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
216 if (snoop)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
217 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
218 if (!ename) ename = "@";
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
219 // proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
220 TRACE("SNOOP_GetProcAddress n/a\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
221
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
222 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
223 return proc;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
224 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
225 else
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
226 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
227 WINE_MODREF *wm;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
228 char *forward = RVA(addr);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
229 char module[256];
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
230 char *end = strchr(forward, '.');
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
231
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
232 if (!end) return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
233 if (end - forward >= sizeof(module)) return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
234 memcpy( module, forward, end - forward );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
235 module[end-forward] = 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
236 if (!(wm = MODULE_FindModule( module )))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
237 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
238 ERR("module not found for forward '%s'\n", forward );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
239 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
240 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
241 return MODULE_GetProcAddress( wm->module, end + 1, snoop );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
242 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
243 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
244
1307
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
245 static DWORD fixup_imports( WINE_MODREF *wm )
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
246 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
247 IMAGE_IMPORT_DESCRIPTOR *pe_imp;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
248 PE_MODREF *pem;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
249 unsigned int load_addr = wm->module;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
250 int i,characteristics_detection=1;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
251 char *modname;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
252
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
253 assert(wm->type==MODULE32_PE);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
254 pem = &(wm->binfmt.pe);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
255 if (pem->pe_export)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
256 modname = (char*) RVA(pem->pe_export->Name);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
257 else
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
258 modname = "<unknown>";
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
259
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
260
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
261 TRACE("Dumping imports list\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
262
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
263
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
264 pe_imp = pem->pe_import;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
265 if (!pe_imp) return 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
266
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
267 /* We assume that we have at least one import with !0 characteristics and
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
268 * detect broken imports with all characteristsics 0 (notably Borland) and
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
269 * switch the detection off for them.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
270 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
271 for (i = 0; pe_imp->Name ; pe_imp++) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
272 if (!i && !pe_imp->u.Characteristics)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
273 characteristics_detection = 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
274 if (characteristics_detection && !pe_imp->u.Characteristics)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
275 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
276 i++;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
277 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
278 if (!i) return 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
279
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
280
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
281 wm->nDeps = i;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
282 wm->deps = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
283
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
284 /* load the imported modules. They are automatically
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
285 * added to the modref list of the process.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
286 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
287
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
288 for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
289 WINE_MODREF *wmImp;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
290 IMAGE_IMPORT_BY_NAME *pe_name;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
291 PIMAGE_THUNK_DATA import_list,thunk_list;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
292 char *name = (char *) RVA(pe_imp->Name);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
293
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
294 if (characteristics_detection && !pe_imp->u.Characteristics)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
295 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
296
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
297 //#warning FIXME: here we should fill imports
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
298 TRACE("Loading imports for %s.dll\n", name);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
299
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
300 if (pe_imp->u.OriginalFirstThunk != 0) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
301 TRACE("Microsoft style imports used\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
302 import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
303 thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
304
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
305 while (import_list->u1.Ordinal) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
306 if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
307 int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
308
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
309 // TRACE("--- Ordinal %s,%d\n", name, ordinal);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
310
2651
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
311 thunk_list->u1.Function=LookupExternal(name, ordinal);
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
312 } else {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
313 pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
314 // TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
2651
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
315 thunk_list->u1.Function=LookupExternalByName(name, pe_name->Name);
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
316 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
317 import_list++;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
318 thunk_list++;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
319 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
320 } else {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
321 TRACE("Borland style imports used\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
322 thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
323 while (thunk_list->u1.Ordinal) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
324 if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
325
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
326 int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
327
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
328 TRACE("--- Ordinal %s.%d\n",name,ordinal);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
329 thunk_list->u1.Function=LookupExternal(
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
330 name, ordinal);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
331 } else {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
332 pe_name=(PIMAGE_IMPORT_BY_NAME) RVA(thunk_list->u1.AddressOfData);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
333 TRACE("--- %s %s.%d\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
334 pe_name->Name,name,pe_name->Hint);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
335 thunk_list->u1.Function=LookupExternalByName(
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
336 name, pe_name->Name);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
337 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
338 thunk_list++;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
339 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
340 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
341 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
342 return 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
343 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
344
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
345 static int calc_vma_size( HMODULE hModule )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
346 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
347 int i,vma_size = 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
348 IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hModule);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
349
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
350 TRACE("Dump of segment table\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
351 TRACE(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
352 for (i = 0; i< PE_HEADER(hModule)->FileHeader.NumberOfSections; i++)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
353 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
354 TRACE("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
355 pe_seg->Name,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
356 pe_seg->Misc.VirtualSize,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
357 pe_seg->VirtualAddress,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
358 pe_seg->SizeOfRawData,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
359 pe_seg->PointerToRawData,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
360 pe_seg->PointerToRelocations,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
361 pe_seg->PointerToLinenumbers,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
362 pe_seg->NumberOfRelocations,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
363 pe_seg->NumberOfLinenumbers,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
364 pe_seg->Characteristics);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
365 vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->SizeOfRawData);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
366 vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->Misc.VirtualSize);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
367 pe_seg++;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
368 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
369 return vma_size;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
370 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
371
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
372 static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
373 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
374 int delta = load_addr - PE_HEADER(load_addr)->OptionalHeader.ImageBase;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
375 int hdelta = (delta >> 16) & 0xFFFF;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
376 int ldelta = delta & 0xFFFF;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
377
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
378 if(delta == 0)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
379
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
380 return;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
381 while(r->VirtualAddress)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
382 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
383 char *page = (char*) RVA(r->VirtualAddress);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
384 int count = (r->SizeOfBlock - 8)/2;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
385 int i;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
386 TRACE_(fixup)("%x relocations for page %lx\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
387 count, r->VirtualAddress);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
388
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
389 for(i=0;i<count;i++)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
390 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
391 int offset = r->TypeOffset[i] & 0xFFF;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
392 int type = r->TypeOffset[i] >> 12;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
393 // TRACE_(fixup)("patching %x type %x\n", offset, type);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
394 switch(type)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
395 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
396 case IMAGE_REL_BASED_ABSOLUTE: break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
397 case IMAGE_REL_BASED_HIGH:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
398 *(short*)(page+offset) += hdelta;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
399 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
400 case IMAGE_REL_BASED_LOW:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
401 *(short*)(page+offset) += ldelta;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
402 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
403 case IMAGE_REL_BASED_HIGHLOW:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
404 *(int*)(page+offset) += delta;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
405
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
406 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
407 case IMAGE_REL_BASED_HIGHADJ:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
408 FIXME("Don't know what to do with IMAGE_REL_BASED_HIGHADJ\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
409 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
410 case IMAGE_REL_BASED_MIPS_JMPADDR:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
411 FIXME("Is this a MIPS machine ???\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
412 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
413 default:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
414 FIXME("Unknown fixup type\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
415 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
416 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
417 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
418 r = (IMAGE_BASE_RELOCATION*)((char*)r + r->SizeOfBlock);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
419 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
420 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
421
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
422
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
423
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
424
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
425
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
426 /**********************************************************************
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
427 * PE_LoadImage
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
428 * Load one PE format DLL/EXE into memory
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
429 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
430 * Unluckily we can't just mmap the sections where we want them, for
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
431 * (at least) Linux does only support offsets which are page-aligned.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
432 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
433 * BUT we have to map the whole image anyway, for Win32 programs sometimes
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
434 * want to access them. (HMODULE32 point to the start of it)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
435 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
436 HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
437 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
438 HMODULE hModule;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
439 HANDLE mapping;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
440
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
441 IMAGE_NT_HEADERS *nt;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
442 IMAGE_SECTION_HEADER *pe_sec;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
443 IMAGE_DATA_DIRECTORY *dir;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
444 BY_HANDLE_FILE_INFORMATION bhfi;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
445 int i, rawsize, lowest_va, vma_size, file_size = 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
446 DWORD load_addr = 0, aoep, reloc = 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
447 // struct get_read_fd_request *req = get_req_buffer();
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
448 int unix_handle = handle;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
449 int page_size = getpagesize();
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
450
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
451
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
452 // if ( GetFileInformationByHandle( hFile, &bhfi ) )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
453 // file_size = bhfi.nFileSizeLow;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
454 file_size=lseek(handle, 0, SEEK_END);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
455 lseek(handle, 0, SEEK_SET);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
456
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
457 //#warning fix CreateFileMappingA
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
458 mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
459 0, 0, NULL );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
460 if (!mapping)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
461 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
462 WARN("CreateFileMapping error %ld\n", GetLastError() );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
463 return 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
464 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
465 // hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
466 hModule=(HMODULE)mapping;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
467 // CloseHandle( mapping );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
468 if (!hModule)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
469 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
470 WARN("MapViewOfFile error %ld\n", GetLastError() );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
471 return 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
472 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
473 if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
474 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
475 WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
476 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
477 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
478
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
479 nt = PE_HEADER( hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
480
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
481
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
482 if ( nt->Signature != IMAGE_NT_SIGNATURE )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
483 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
484 WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
485 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
486 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
487
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
488
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
489 if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
490 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
491 MESSAGE("Trying to load PE image for unsupported architecture (");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
492 switch (nt->FileHeader.Machine)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
493 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
494 case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
495 case IMAGE_FILE_MACHINE_I860: MESSAGE("I860"); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
496 case IMAGE_FILE_MACHINE_R3000: MESSAGE("R3000"); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
497 case IMAGE_FILE_MACHINE_R4000: MESSAGE("R4000"); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
498 case IMAGE_FILE_MACHINE_R10000: MESSAGE("R10000"); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
499 case IMAGE_FILE_MACHINE_ALPHA: MESSAGE("Alpha"); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
500 case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
501 default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
502 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
503 MESSAGE(")\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
504 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
505 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
506
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
507
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
508 pe_sec = PE_SECTIONS( hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
509 rawsize = 0; lowest_va = 0x10000;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
510 for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
511 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
512 if (lowest_va > pe_sec[i].VirtualAddress)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
513 lowest_va = pe_sec[i].VirtualAddress;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
514 if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
515 continue;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
516 if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
517 rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
518 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
519
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
520
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
521 if ( file_size && file_size < rawsize )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
522 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
523 ERR("PE module is too small (header: %d, filesize: %d), "
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
524 "probably truncated download?\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
525 rawsize, file_size );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
526 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
527 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
528
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
529
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
530 aoep = nt->OptionalHeader.AddressOfEntryPoint;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
531 if (aoep && (aoep < lowest_va))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
532 FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) "
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
533 "below the first virtual address (0x%08x) "
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
534 "(possibly infected by Tchernobyl/SpaceFiller virus)!\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
535 filename, aoep, lowest_va );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
536
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
537
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
538 /* FIXME: Hack! While we don't really support shared sections yet,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
539 * this checks for those special cases where the whole DLL
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
540 * consists only of shared sections and is mapped into the
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
541 * shared address space > 2GB. In this case, we assume that
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
542 * the module got mapped at its base address. Thus we simply
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
543 * check whether the module has actually been mapped there
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
544 * and use it, if so. This is needed to get Win95 USER32.DLL
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
545 * to work (until we support shared sections properly).
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
546 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
547
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
548 if ( nt->OptionalHeader.ImageBase & 0x80000000 )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
549 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
550 HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
551 IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
552 ( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
553
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
554 /* Well, this check is not really comprehensive,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
555 but should be good enough for now ... */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
556 if ( !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
557 && memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
558 && !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
559 && memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
560 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
561 UnmapViewOfFile( (LPVOID)hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
562 return sharedMod;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
563 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
564 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
565
2069
ce45cce7f7a5 sync with avifile
arpi
parents: 1411
diff changeset
566
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
567
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
568 load_addr = nt->OptionalHeader.ImageBase;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
569 vma_size = calc_vma_size( hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
570
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
571 load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
572 MEM_RESERVE | MEM_COMMIT,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
573 PAGE_EXECUTE_READWRITE );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
574 if (load_addr == 0)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
575 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
576
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
577 FIXME("We need to perform base relocations for %s\n", filename);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
578 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
579 if (dir->Size)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
580 reloc = dir->VirtualAddress;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
581 else
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
582 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
583 FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
584 filename,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
585 (nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)?
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
586 "stripped during link" : "unknown reason" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
587 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
588 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
589
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
590 /* FIXME: If we need to relocate a system DLL (base > 2GB) we should
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
591 * really make sure that the *new* base address is also > 2GB.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
592 * Some DLLs really check the MSB of the module handle :-/
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
593 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
594 if ( nt->OptionalHeader.ImageBase & 0x80000000 )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
595 ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
596
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
597 load_addr = (DWORD)VirtualAlloc( NULL, vma_size,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
598 MEM_RESERVE | MEM_COMMIT,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
599 PAGE_EXECUTE_READWRITE );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
600 if (!load_addr) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
601 FIXME_(win32)(
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
602 "FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
603 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
604 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
605 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
606
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
607 TRACE("Load addr is %lx (base %lx), range %x\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
608 load_addr, nt->OptionalHeader.ImageBase, vma_size );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
609 TRACE_(segment)("Loading %s at %lx, range %x\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
610 filename, load_addr, vma_size );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
611
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
612 #if 0
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
613
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
614 *(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
615 *PE_HEADER( load_addr ) = *nt;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
616 memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule),
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
617 sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
618
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
619
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
620 memcpy( load_addr, hModule, lowest_fa );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
621 #endif
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
622
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
623 if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
624 0, 0, PROT_EXEC | PROT_WRITE | PROT_READ,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
625 MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
626 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
627 ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
628 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
629 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
630
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
631
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
632 pe_sec = PE_SECTIONS( hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
633 for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
634 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
635 if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
636 TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
637 filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress),
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
638 pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
639 if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress),
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
640 0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
641 PROT_EXEC | PROT_WRITE | PROT_READ,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
642 MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
643 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
644
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
645 ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
646 goto error;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
647 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
648 if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
649 (pe_sec->SizeOfRawData & (page_size-1)))
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
650 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
651 DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
652 if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
653 TRACE("clearing %p - %p\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
654 RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
655 RVA(pe_sec->VirtualAddress) + end );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
656 memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
657 end - pe_sec->SizeOfRawData );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
658 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
659 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
660
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
661
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
662 if ( reloc )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
663 do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
664
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
665
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
666 *version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
667 | (nt->OptionalHeader.MinorSubsystemVersion & 0xff);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
668
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
669
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
670 UnmapViewOfFile( (LPVOID)hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
671 return (HMODULE)load_addr;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
672
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
673 error:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
674 if (unix_handle != -1) close( unix_handle );
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
675 if (load_addr)
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
676 VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE );
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
677 UnmapViewOfFile( (LPVOID)hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
678 return 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
679 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
680
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
681 /**********************************************************************
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
682 * PE_CreateModule
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
683 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
684 * Create WINE_MODREF structure for loaded HMODULE32, link it into
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
685 * process modref_list, and fixup all imports.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
686 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
687 * Note: hModule must point to a correctly allocated PE image,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
688 * with base relocations applied; the 16-bit dummy module
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
689 * associated to hModule must already exist.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
690 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
691 * Note: This routine must always be called in the context of the
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
692 * process that is to own the module to be created.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
693 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
694 WINE_MODREF *PE_CreateModule( HMODULE hModule,
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
695 LPCSTR filename, DWORD flags, WIN_BOOL builtin )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
696 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
697 DWORD load_addr = (DWORD)hModule;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
698 IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
699 IMAGE_DATA_DIRECTORY *dir;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
700 IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
701 IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
702 IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
703 WINE_MODREF *wm;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
704 int result;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
705
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
706
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
707
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
708
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
709 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
710 if (dir->Size)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
711 pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
712
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
713 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
714 if (dir->Size)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
715 pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
716
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
717 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
718 if (dir->Size)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
719 pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
720
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
721 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
722 if (dir->Size) FIXME("Exception directory ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
723
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
724 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
725 if (dir->Size) FIXME("Security directory ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
726
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
727
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
728
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
729
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
730 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
731 if (dir->Size) TRACE("Debug directory ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
732
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
733 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
734 if (dir->Size) FIXME("Copyright string ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
735
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
736 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
737 if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
738
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
739
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
740
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
741 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
742 if (dir->Size) FIXME("Load Configuration directory ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
743
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
744 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
745 if (dir->Size) TRACE("Bound Import directory ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
746
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
747 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
748 if (dir->Size) TRACE("Import Address Table directory ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
749
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
750 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
751 if (dir->Size)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
752 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
753 TRACE("Delayed import, stub calls LoadLibrary\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
754 /*
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
755 * Nothing to do here.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
756 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
757
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
758 #ifdef ImgDelayDescr
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
759 /*
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
760 * This code is useful to observe what the heck is going on.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
761 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
762 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
763 ImgDelayDescr *pe_delay = NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
764 pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
765 TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
766 TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
767 TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
768 TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
769 TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
770 TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
771 TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
772 TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
773 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
774 #endif
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
775 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
776
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
777 dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
778 if (dir->Size) FIXME("Unknown directory 14 ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
779
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
780 dir = nt->OptionalHeader.DataDirectory+15;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
781 if (dir->Size) FIXME("Unknown directory 15 ignored\n" );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
782
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
783
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
784
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
785
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
786 wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(),
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
787 HEAP_ZERO_MEMORY, sizeof(*wm) );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
788 wm->module = hModule;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
789
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
790 if ( builtin )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
791 wm->flags |= WINE_MODREF_INTERNAL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
792 if ( flags & DONT_RESOLVE_DLL_REFERENCES )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
793 wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
794 if ( flags & LOAD_LIBRARY_AS_DATAFILE )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
795 wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
796
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
797 wm->type = MODULE32_PE;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
798 wm->binfmt.pe.pe_export = pe_export;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
799 wm->binfmt.pe.pe_import = pe_import;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
800 wm->binfmt.pe.pe_resource = pe_resource;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
801 wm->binfmt.pe.tlsindex = -1;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
802
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
803 wm->filename = malloc(strlen(filename)+1);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
804 strcpy(wm->filename, filename );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
805 wm->modname = strrchr( wm->filename, '\\' );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
806 if (!wm->modname) wm->modname = wm->filename;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
807 else wm->modname++;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
808
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
809 if ( pe_export )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
810 dump_exports( hModule );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
811
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
812 /* Fixup Imports */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
813
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
814 if ( pe_import
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
815 && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
816 && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
817 && fixup_imports( wm ) )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
818 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
819 /* remove entry from modref chain */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
820 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
821 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
822
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
823 return wm;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
824
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
825 return wm;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
826 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
827
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
828 /******************************************************************************
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
829 * The PE Library Loader frontend.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
830 * FIXME: handle the flags.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
831 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
832 WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
833 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
834 HMODULE hModule32;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
835 WINE_MODREF *wm;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
836 char filename[256];
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
837 int hFile;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
838 WORD version = 0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
839
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
840
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
841 strncpy(filename, name, sizeof(filename));
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
842 hFile=open(filename, O_RDONLY);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
843 if(hFile==-1)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
844 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
845
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
846
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
847 hModule32 = PE_LoadImage( hFile, filename, &version );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
848 if (!hModule32)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
849 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
850 SetLastError( ERROR_OUTOFMEMORY );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
851 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
852 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
853
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
854 if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
855 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
856 ERR( "can't load %s\n", filename );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
857 SetLastError( ERROR_OUTOFMEMORY );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
858 return NULL;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
859 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
860 close(hFile);
2651
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
861 //printf("^^^^^^^^^^^^^^^^Alloc VM1 %p\n", wm);
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
862 return wm;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
863 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
864
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
865
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
866 /*****************************************************************************
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
867 * PE_UnloadLibrary
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
868 *
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
869 * Unload the library unmapping the image and freeing the modref structure.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
870 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
871 void PE_UnloadLibrary(WINE_MODREF *wm)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
872 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
873 TRACE(" unloading %s\n", wm->filename);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
874
2651
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
875 if (wm->filename)
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
876 free(wm->filename);
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
877 if (wm->short_filename)
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
878 free(wm->short_filename);
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
879 HeapFree( GetProcessHeap(), 0, wm->deps );
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
880 VirtualFree( (LPVOID)wm->module, 0, MEM_RELEASE );
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
881 HeapFree( GetProcessHeap(), 0, wm );
2651
958d10763c34 partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents: 2069
diff changeset
882 //printf("^^^^^^^^^^^^^^^^Free VM1 %p\n", wm);
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
883 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
884
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
885 /*****************************************************************************
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
886 * Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
887 * FIXME: this function should use PE_LoadLibraryExA, but currently can't
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
888 * due to the PROCESS_Create stuff.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
889 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
890
2069
ce45cce7f7a5 sync with avifile
arpi
parents: 1411
diff changeset
891
1307
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
892 /*
1411
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
893 * This is a dirty hack.
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
894 * The win32 DLLs contain an alloca routine, that first probes the soon
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
895 * to be allocated new memory *below* the current stack pointer in 4KByte
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
896 * increments. After the mem probing below the current %esp, the stack
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
897 * pointer is finally decremented to make room for the "alloca"ed memory.
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
898 * Maybe the probing code is intended to extend the stack on a windows box.
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
899 * Anyway, the linux kernel does *not* extend the stack by simply accessing
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
900 * memory below %esp; it segfaults.
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
901 * The extend_stack_for_dll_alloca() routine just preallocates a big chunk
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
902 * of memory on the stack, for use by the DLLs alloca routine.
13375
460281609f28 force compilers not to optimize/inline extend_stack_for_dll_alloca
reimar
parents: 7386
diff changeset
903 * Added the noinline attribute as e.g. gcc 3.2.2 inlines this function
460281609f28 force compilers not to optimize/inline extend_stack_for_dll_alloca
reimar
parents: 7386
diff changeset
904 * in a way that breaks it.
1307
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
905 */
13375
460281609f28 force compilers not to optimize/inline extend_stack_for_dll_alloca
reimar
parents: 7386
diff changeset
906 static void __attribute__((noinline)) extend_stack_for_dll_alloca(void)
1307
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
907 {
2069
ce45cce7f7a5 sync with avifile
arpi
parents: 1411
diff changeset
908 #ifndef __FreeBSD__
13375
460281609f28 force compilers not to optimize/inline extend_stack_for_dll_alloca
reimar
parents: 7386
diff changeset
909 volatile int* mem=alloca(0x20000);
460281609f28 force compilers not to optimize/inline extend_stack_for_dll_alloca
reimar
parents: 7386
diff changeset
910 *mem=0x1234;
2069
ce45cce7f7a5 sync with avifile
arpi
parents: 1411
diff changeset
911 #endif
1307
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
912 }
d8c1b0b38edc Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents: 128
diff changeset
913
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
914 /* Called if the library is loaded or freed.
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
915 * NOTE: if a thread attaches a DLL, the current thread will only do
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
916 * DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
917 * (SDK)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
918 */
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
919 WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
920 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
921 WIN_BOOL retv = TRUE;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
922 assert( wm->type == MODULE32_PE );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
923
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
924
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
925 if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
926 (PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
927 ) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
928 DLLENTRYPROC entry ;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
929 entry = (void*)PE_FindExportedFunction(wm, "DllMain", 0);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
930 if(entry==NULL)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
931 entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
932
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
933 TRACE_(relay)("CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n",
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
934 entry, wm->module, type, lpReserved );
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
935
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
936
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
937 TRACE("Entering DllMain(");
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
938 switch(type)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
939 {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
940 case DLL_PROCESS_DETACH:
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
941 TRACE("DLL_PROCESS_DETACH) ");
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
942 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
943 case DLL_PROCESS_ATTACH:
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
944 TRACE("DLL_PROCESS_ATTACH) ");
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
945 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
946 case DLL_THREAD_DETACH:
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
947 TRACE("DLL_THREAD_DETACH) ");
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
948 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
949 case DLL_THREAD_ATTACH:
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
950 TRACE("DLL_THREAD_ATTACH) ");
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
951 break;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
952 }
128
28091b3caff9 DLL loader updated from avifile-0.60beta4
arpi_esp
parents: 1
diff changeset
953 TRACE("for %s\n", wm->filename);
1411
db849cee5777 Pre-allocate some stack space to work around a problem with DLL alloca() code
jkeil
parents: 1307
diff changeset
954 extend_stack_for_dll_alloca();
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
955 retv = entry( wm->module, type, lpReserved );
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
956 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
957
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
958 return retv;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
959 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
960
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
961 static LPVOID
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
962 _fixup_address(PIMAGE_OPTIONAL_HEADER opt,int delta,LPVOID addr) {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
963 if ( ((DWORD)addr>opt->ImageBase) &&
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
964 ((DWORD)addr<opt->ImageBase+opt->SizeOfImage)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
965 )
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
966
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
967 return (LPVOID)(((DWORD)addr)+delta);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
968 else
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
969
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
970 return addr;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
971 }