annotate loader/pe_image.c @ 12022:293141b57c01

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