1 /*
2 * Win32s Universal Thunk API
3 *
4 * Copyright 1999 Ulrich Weigand
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <stdarg.h>
22
23 #include "wine/winbase16.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winternl.h"
27 #include "wownt32.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(thunk);
31
32 #include "pshpack1.h"
33
34 typedef struct
35 {
36 BYTE popl_eax;
37 BYTE pushl;
38 DWORD target;
39 BYTE pushl_eax;
40 BYTE ljmp;
41 DWORD utglue16;
42
43 } UT16THUNK;
44
45 typedef struct
46 {
47 BYTE popl_eax;
48 BYTE pushl;
49 DWORD target;
50 BYTE pushl_eax;
51 BYTE jmp;
52 DWORD utglue32;
53
54 } UT32THUNK;
55
56 #include "poppack.h"
57
58 typedef struct _UTINFO
59 {
60 struct _UTINFO *next;
61 HMODULE hModule;
62 HMODULE16 hModule16;
63
64 UT16THUNK ut16;
65 UT32THUNK ut32;
66
67 } UTINFO;
68
69 static UTINFO *UT_head; /* head of Universal Thunk list */
70
71 typedef DWORD (CALLBACK *UTGLUEPROC)( LPVOID lpBuff, DWORD dwUserDefined );
72
73 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
74 LPSTR lpszInitName, LPSTR lpszProcName,
75 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
76 LPVOID lpBuff );
77
78 VOID WINAPI UTUnRegister( HMODULE hModule );
79
80
81 /****************************************************************************
82 * UTGlue16 (KERNEL.666) (KERNEL Wine-specific export)
83 */
84 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR *translationList,
85 UTGLUEPROC target )
86 {
87 INT i;
88
89 /* Convert arguments to flat pointers */
90
91 if ( translationList )
92 for ( i = 0; translationList[i]; i++ )
93 {
94 LPVOID flatPtr = MapSL( translationList[i] );
95 *(LPVOID *)flatPtr = MapSL( *(SEGPTR *)flatPtr );
96 }
97
98 /* Call 32-bit routine */
99
100 return target( lpBuff, dwUserDefined );
101 }
102
103 /****************************************************************************
104 * UTGlue32
105 */
106 static DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined,
107 LPVOID translationList[] )
108 {
109 SEGPTR segBuff, *segptrList = NULL;
110 INT i, nList = 0;
111 DWORD retv;
112 WORD args[4];
113
114 /* Convert arguments to SEGPTRs */
115
116 if ( translationList )
117 for ( nList = 0; translationList[nList]; nList++ )
118 ;
119
120 if ( nList )
121 {
122 segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList );
123 if ( !segptrList )
124 {
125 FIXME("Unable to allocate segptrList!\n" );
126 return 0;
127 }
128
129 for ( i = 0; i < nList; i++ )
130 segptrList[i] = *(SEGPTR *)translationList[i]
131 = MapLS( *(LPVOID *)translationList[i] );
132 }
133
134 segBuff = MapLS( lpBuff );
135
136 /* Call 16-bit routine */
137
138 args[3] = SELECTOROF(segBuff);
139 args[2] = OFFSETOF(segBuff);
140 args[1] = HIWORD(dwUserDefined);
141 args[0] = LOWORD(dwUserDefined);
142 WOWCallback16Ex( (DWORD)target, WCB16_PASCAL, sizeof(args), args, &retv );
143
144 /* Free temporary selectors */
145
146 UnMapLS( segBuff );
147
148 if ( nList )
149 {
150 for ( i = 0; i < nList; i++ )
151 UnMapLS( segptrList[i] );
152
153 HeapFree( GetProcessHeap(), 0, segptrList );
154 }
155
156 return retv;
157 }
158
159 /****************************************************************************
160 * UTAlloc
161 */
162 static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
163 FARPROC16 target16, FARPROC target32 )
164 {
165 static FARPROC16 UTGlue16_Segptr = NULL;
166 UTINFO *ut;
167
168 if ( !UTGlue16_Segptr )
169 {
170 HMODULE16 hMod = GetModuleHandle16( "KERNEL" );
171 UTGlue16_Segptr = GetProcAddress16( hMod, "UTGlue16" );
172 if ( !UTGlue16_Segptr ) return NULL;
173 }
174
175 ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UTINFO) );
176 if ( !ut ) return NULL;
177
178 ut->hModule = hModule;
179 ut->hModule16 = hModule16;
180
181 ut->ut16.popl_eax = 0x58;
182 ut->ut16.pushl = 0x68;
183 ut->ut16.target = (DWORD)target32;
184 ut->ut16.pushl_eax = 0x50;
185 ut->ut16.ljmp = 0xea;
186 ut->ut16.utglue16 = (DWORD)UTGlue16_Segptr;
187
188 ut->ut32.popl_eax = 0x58;
189 ut->ut32.pushl = 0x68;
190 ut->ut32.target = (DWORD)target16;
191 ut->ut32.pushl_eax = 0x50;
192 ut->ut32.jmp = 0xe9;
193 ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD));
194
195 ut->next = UT_head;
196 UT_head = ut;
197
198 return ut;
199 }
200
201 /****************************************************************************
202 * UTFree
203 */
204 static void UTFree( UTINFO *ut )
205 {
206 UTINFO **ptr;
207
208 for ( ptr = &UT_head; *ptr; ptr = &(*ptr)->next )
209 if ( *ptr == ut )
210 {
211 *ptr = ut->next;
212 break;
213 }
214
215 HeapFree( GetProcessHeap(), 0, ut );
216 }
217
218 /****************************************************************************
219 * UTFind
220 */
221 static UTINFO *UTFind( HMODULE hModule )
222 {
223 UTINFO *ut;
224
225 for ( ut = UT_head; ut; ut =ut->next )
226 if ( ut->hModule == hModule )
227 break;
228
229 return ut;
230 }
231
232
233 /****************************************************************************
234 * UTRegister (KERNEL32.@)
235 */
236 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
237 LPSTR lpszInitName, LPSTR lpszProcName,
238 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
239 LPVOID lpBuff )
240 {
241 UTINFO *ut;
242 HMODULE16 hModule16;
243 FARPROC16 target16, init16;
244 static int done;
245
246 if (!done)
247 {
248 LoadLibrary16( "gdi.exe" );
249 LoadLibrary16( "user.exe" );
250 done = TRUE;
251 }
252
253 /* Load 16-bit DLL and get UTProc16 entry point */
254
255 if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32
256 || (target16 = GetProcAddress16( hModule16, lpszProcName )) == 0 )
257 return FALSE;
258
259 /* Allocate UTINFO struct */
260
261 RtlAcquirePebLock();
262 if ( (ut = UTFind( hModule )) != NULL )
263 ut = NULL;
264 else
265 ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
266 RtlReleasePebLock();
267
268 if ( !ut )
269 {
270 FreeLibrary16( hModule16 );
271 return FALSE;
272 }
273
274 /* Call UTInit16 if present */
275
276 if ( lpszInitName
277 && (init16 = GetProcAddress16( hModule16, lpszInitName )) != 0 )
278 {
279 SEGPTR callback = MapLS( &ut->ut16 );
280 SEGPTR segBuff = MapLS( lpBuff );
281 WORD args[4];
282 DWORD ret;
283
284 args[3] = SELECTOROF(callback);
285 args[2] = OFFSETOF(callback);
286 args[1] = SELECTOROF(segBuff);
287 args[0] = OFFSETOF(segBuff);
288 WOWCallback16Ex( (DWORD)init16, WCB16_PASCAL, sizeof(args), args, &ret );
289 UnMapLS( segBuff );
290 UnMapLS( callback );
291 if (!ret)
292 {
293 UTUnRegister( hModule );
294 return FALSE;
295 }
296 }
297
298 /* Return 32-bit thunk */
299
300 *ppfn32Thunk = (FARPROC) &ut->ut32;
301
302 return TRUE;
303 }
304
305 /****************************************************************************
306 * UTUnRegister (KERNEL32.@)
307 */
308 VOID WINAPI UTUnRegister( HMODULE hModule )
309 {
310 UTINFO *ut;
311 HMODULE16 hModule16 = 0;
312
313 RtlAcquirePebLock();
314 ut = UTFind( hModule );
315 if ( ut )
316 {
317 hModule16 = ut->hModule16;
318 UTFree( ut );
319 }
320 RtlReleasePebLock();
321
322 if ( hModule16 )
323 FreeLibrary16( hModule16 );
324 }
325
326 /****************************************************************************
327 * UTInit (KERNEL.493)
328 */
329 WORD WINAPI UTInit16( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
330 {
331 FIXME("(%08x, %08x, %08x, %08x): stub\n", x1, x2, x3, x4 );
332 return 0;
333 }
334
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.