2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
7 #include "wine/winbase16.h"
10 #include "debugtools.h"
12 DEFAULT_DEBUG_CHANNEL(thunk);
40 typedef struct _UTINFO
51 static UTINFO *UT_head; /* head of Universal Thunk list */
53 typedef DWORD (CALLBACK *UTGLUEPROC)( LPVOID lpBuff, DWORD dwUserDefined );
55 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
56 LPSTR lpszInitName, LPSTR lpszProcName,
57 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
60 VOID WINAPI UTUnRegister( HMODULE hModule );
62 /* ### start build ### */
63 extern LONG CALLBACK UTTHUNK_CallTo16_long_ll(FARPROC16,LONG,LONG);
64 /* ### stop build ### */
66 /****************************************************************************
67 * UTGlue16 (KERNEL.666) (KERNEL Wine-specific export)
69 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR *translationList,
74 /* Convert arguments to flat pointers */
76 if ( translationList )
77 for ( i = 0; translationList[i]; i++ )
79 LPVOID flatPtr = MapSL( translationList[i] );
80 *(LPVOID *)flatPtr = MapSL( *(SEGPTR *)flatPtr );
83 /* Call 32-bit routine */
85 return target( lpBuff, dwUserDefined );
88 /****************************************************************************
91 static DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined,
92 LPVOID translationList[] )
94 SEGPTR segBuff, *segptrList = NULL;
98 /* Convert arguments to SEGPTRs */
100 if ( translationList )
101 for ( nList = 0; translationList[nList]; nList++ )
106 segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList );
109 FIXME("Unable to allocate segptrList!\n" );
113 for ( i = 0; i < nList; i++ )
114 segptrList[i] = *(SEGPTR *)translationList[i]
115 = MapLS( *(LPVOID *)translationList[i] );
118 segBuff = MapLS( lpBuff );
120 /* Call 16-bit routine */
122 retv = UTTHUNK_CallTo16_long_ll( target, segBuff, dwUserDefined );
124 /* Free temporary selectors */
130 for ( i = 0; i < nList; i++ )
131 UnMapLS( segptrList[i] );
133 HeapFree( GetProcessHeap(), 0, segptrList );
139 /****************************************************************************
142 static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
143 FARPROC16 target16, FARPROC target32 )
145 static FARPROC16 UTGlue16_Segptr = NULL;
148 if ( !UTGlue16_Segptr )
150 HMODULE16 hModule = GetModuleHandle16( "KERNEL" );
151 UTGlue16_Segptr = GetProcAddress16( hModule, "UTGlue16" );
152 if ( !UTGlue16_Segptr ) return NULL;
155 ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UTINFO) );
156 if ( !ut ) return NULL;
158 ut->hModule = hModule;
159 ut->hModule16 = hModule16;
161 ut->ut16.popl_eax = 0x58;
162 ut->ut16.pushl = 0x68;
163 ut->ut16.target = (DWORD)target32;
164 ut->ut16.pushl_eax = 0x50;
165 ut->ut16.ljmp = 0xea;
166 ut->ut16.utglue16 = (DWORD)UTGlue16_Segptr;
168 ut->ut32.popl_eax = 0x58;
169 ut->ut32.pushl = 0x68;
170 ut->ut32.target = (DWORD)target16;
171 ut->ut32.pushl_eax = 0x50;
173 ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD));
181 /****************************************************************************
184 static void UTFree( UTINFO *ut )
188 for ( ptr = &UT_head; *ptr; ptr = &(*ptr)->next )
195 HeapFree( GetProcessHeap(), 0, ut );
198 /****************************************************************************
201 static UTINFO *UTFind( HMODULE hModule )
205 for ( ut = UT_head; ut; ut =ut->next )
206 if ( ut->hModule == hModule )
213 /****************************************************************************
214 * UTRegister (KERNEL32.@)
216 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
217 LPSTR lpszInitName, LPSTR lpszProcName,
218 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
223 FARPROC16 target16, init16;
225 /* Load 16-bit DLL and get UTProc16 entry point */
227 if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32
228 || (target16 = GetProcAddress16( hModule16, lpszProcName )) == 0 )
231 /* Allocate UTINFO struct */
234 if ( (ut = UTFind( hModule )) != NULL )
237 ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
242 FreeLibrary16( hModule16 );
246 /* Call UTInit16 if present */
249 && (init16 = GetProcAddress16( hModule16, lpszInitName )) != 0 )
251 SEGPTR callback = MapLS( &ut->ut16 );
252 SEGPTR segBuff = MapLS( lpBuff );
254 if ( !UTTHUNK_CallTo16_long_ll( init16, callback, segBuff ) )
258 UTUnRegister( hModule );
265 /* Return 32-bit thunk */
267 *ppfn32Thunk = (FARPROC) &ut->ut32;
272 /****************************************************************************
273 * UTUnRegister (KERNEL32.@)
275 VOID WINAPI UTUnRegister( HMODULE hModule )
278 HMODULE16 hModule16 = 0;
281 ut = UTFind( hModule );
284 hModule16 = ut->hModule16;
290 FreeLibrary16( hModule16 );
293 /****************************************************************************
294 * UTInit (KERNEL.493)
296 WORD WINAPI UTInit16( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
298 FIXME("(%08lx, %08lx, %08lx, %08lx): stub\n", x1, x2, x3, x4 );