Added version info to 16-bit shell.dll.
[wine/multimedia.git] / dlls / kernel / utthunk.c
blobba649b6bf6d316035f40f0f2f1fbc8a2cf5034e3
1 /*
2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "wine/winbase16.h"
22 #include "ntddk.h"
23 #include "module.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(thunk);
28 #include "pshpack1.h"
30 typedef struct
32 BYTE popl_eax;
33 BYTE pushl;
34 DWORD target;
35 BYTE pushl_eax;
36 BYTE ljmp;
37 DWORD utglue16;
39 } UT16THUNK;
41 typedef struct
43 BYTE popl_eax;
44 BYTE pushl;
45 DWORD target;
46 BYTE pushl_eax;
47 BYTE jmp;
48 DWORD utglue32;
50 } UT32THUNK;
52 #include "poppack.h"
54 typedef struct _UTINFO
56 struct _UTINFO *next;
57 HMODULE hModule;
58 HMODULE16 hModule16;
60 UT16THUNK ut16;
61 UT32THUNK ut32;
63 } UTINFO;
65 static UTINFO *UT_head; /* head of Universal Thunk list */
67 typedef DWORD (CALLBACK *UTGLUEPROC)( LPVOID lpBuff, DWORD dwUserDefined );
69 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
70 LPSTR lpszInitName, LPSTR lpszProcName,
71 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
72 LPVOID lpBuff );
74 VOID WINAPI UTUnRegister( HMODULE hModule );
76 /* ### start build ### */
77 extern LONG CALLBACK UTTHUNK_CallTo16_long_ll(FARPROC16,LONG,LONG);
78 /* ### stop build ### */
80 /****************************************************************************
81 * UTGlue16 (KERNEL.666) (KERNEL Wine-specific export)
83 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR *translationList,
84 UTGLUEPROC target )
86 INT i;
88 /* Convert arguments to flat pointers */
90 if ( translationList )
91 for ( i = 0; translationList[i]; i++ )
93 LPVOID flatPtr = MapSL( translationList[i] );
94 *(LPVOID *)flatPtr = MapSL( *(SEGPTR *)flatPtr );
97 /* Call 32-bit routine */
99 return target( lpBuff, dwUserDefined );
102 /****************************************************************************
103 * UTGlue32
105 static DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined,
106 LPVOID translationList[] )
108 SEGPTR segBuff, *segptrList = NULL;
109 INT i, nList = 0;
110 DWORD retv;
112 /* Convert arguments to SEGPTRs */
114 if ( translationList )
115 for ( nList = 0; translationList[nList]; nList++ )
118 if ( nList )
120 segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList );
121 if ( !segptrList )
123 FIXME("Unable to allocate segptrList!\n" );
124 return 0;
127 for ( i = 0; i < nList; i++ )
128 segptrList[i] = *(SEGPTR *)translationList[i]
129 = MapLS( *(LPVOID *)translationList[i] );
132 segBuff = MapLS( lpBuff );
134 /* Call 16-bit routine */
136 retv = UTTHUNK_CallTo16_long_ll( target, segBuff, dwUserDefined );
138 /* Free temporary selectors */
140 UnMapLS( segBuff );
142 if ( nList )
144 for ( i = 0; i < nList; i++ )
145 UnMapLS( segptrList[i] );
147 HeapFree( GetProcessHeap(), 0, segptrList );
150 return retv;
153 /****************************************************************************
154 * UTAlloc
156 static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
157 FARPROC16 target16, FARPROC target32 )
159 static FARPROC16 UTGlue16_Segptr = NULL;
160 UTINFO *ut;
162 if ( !UTGlue16_Segptr )
164 HMODULE16 hModule = GetModuleHandle16( "KERNEL" );
165 UTGlue16_Segptr = GetProcAddress16( hModule, "UTGlue16" );
166 if ( !UTGlue16_Segptr ) return NULL;
169 ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UTINFO) );
170 if ( !ut ) return NULL;
172 ut->hModule = hModule;
173 ut->hModule16 = hModule16;
175 ut->ut16.popl_eax = 0x58;
176 ut->ut16.pushl = 0x68;
177 ut->ut16.target = (DWORD)target32;
178 ut->ut16.pushl_eax = 0x50;
179 ut->ut16.ljmp = 0xea;
180 ut->ut16.utglue16 = (DWORD)UTGlue16_Segptr;
182 ut->ut32.popl_eax = 0x58;
183 ut->ut32.pushl = 0x68;
184 ut->ut32.target = (DWORD)target16;
185 ut->ut32.pushl_eax = 0x50;
186 ut->ut32.jmp = 0xe9;
187 ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD));
189 ut->next = UT_head;
190 UT_head = ut;
192 return ut;
195 /****************************************************************************
196 * UTFree
198 static void UTFree( UTINFO *ut )
200 UTINFO **ptr;
202 for ( ptr = &UT_head; *ptr; ptr = &(*ptr)->next )
203 if ( *ptr == ut )
205 *ptr = ut->next;
206 break;
209 HeapFree( GetProcessHeap(), 0, ut );
212 /****************************************************************************
213 * UTFind
215 static UTINFO *UTFind( HMODULE hModule )
217 UTINFO *ut;
219 for ( ut = UT_head; ut; ut =ut->next )
220 if ( ut->hModule == hModule )
221 break;
223 return ut;
227 /****************************************************************************
228 * UTRegister (KERNEL32.@)
230 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
231 LPSTR lpszInitName, LPSTR lpszProcName,
232 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
233 LPVOID lpBuff )
235 UTINFO *ut;
236 HMODULE16 hModule16;
237 FARPROC16 target16, init16;
239 /* Load 16-bit DLL and get UTProc16 entry point */
241 if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32
242 || (target16 = GetProcAddress16( hModule16, lpszProcName )) == 0 )
243 return FALSE;
245 /* Allocate UTINFO struct */
247 RtlAcquirePebLock();
248 if ( (ut = UTFind( hModule )) != NULL )
249 ut = NULL;
250 else
251 ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
252 RtlReleasePebLock();
254 if ( !ut )
256 FreeLibrary16( hModule16 );
257 return FALSE;
260 /* Call UTInit16 if present */
262 if ( lpszInitName
263 && (init16 = GetProcAddress16( hModule16, lpszInitName )) != 0 )
265 SEGPTR callback = MapLS( &ut->ut16 );
266 SEGPTR segBuff = MapLS( lpBuff );
268 if ( !UTTHUNK_CallTo16_long_ll( init16, callback, segBuff ) )
270 UnMapLS( segBuff );
271 UnMapLS( callback );
272 UTUnRegister( hModule );
273 return FALSE;
275 UnMapLS( segBuff );
276 UnMapLS( callback );
279 /* Return 32-bit thunk */
281 *ppfn32Thunk = (FARPROC) &ut->ut32;
283 return TRUE;
286 /****************************************************************************
287 * UTUnRegister (KERNEL32.@)
289 VOID WINAPI UTUnRegister( HMODULE hModule )
291 UTINFO *ut;
292 HMODULE16 hModule16 = 0;
294 RtlAcquirePebLock();
295 ut = UTFind( hModule );
296 if ( !ut )
298 hModule16 = ut->hModule16;
299 UTFree( ut );
301 RtlReleasePebLock();
303 if ( hModule16 )
304 FreeLibrary16( hModule16 );
307 /****************************************************************************
308 * UTInit (KERNEL.493)
310 WORD WINAPI UTInit16( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
312 FIXME("(%08lx, %08lx, %08lx, %08lx): stub\n", x1, x2, x3, x4 );
313 return 0;