2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
10 #include "selectors.h"
42 typedef struct _UTINFO
53 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
54 LPSTR lpszInitName, LPSTR lpszProcName,
55 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
58 VOID WINAPI UTUnRegister( HMODULE hModule );
61 /****************************************************************************
64 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR translationList[],
65 DWORD (CALLBACK *target)( LPVOID lpBuff, DWORD dwUserDefined ) )
69 /* Convert arguments to flat pointers */
71 if ( translationList )
72 for ( i = 0; translationList[i]; i++ )
74 LPVOID flatPtr = PTR_SEG_TO_LIN( translationList[i] );
75 *(LPVOID *)flatPtr = PTR_SEG_TO_LIN( *(SEGPTR *)flatPtr );
78 /* Call 32-bit routine */
80 return target( lpBuff, dwUserDefined );
83 /****************************************************************************
86 DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined,
87 LPVOID translationList[] )
89 SEGPTR segBuff, *segptrList = NULL;
93 /* Convert arguments to SEGPTRs */
95 if ( translationList )
96 for ( nList = 0; translationList[nList]; nList++ )
101 segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList );
104 FIXME( thunk, "Unable to allocate segptrList!" );
108 for ( i = 0; i < nList; i++ )
109 segptrList[i] = *(SEGPTR *)translationList[i]
110 = MapLS( *(LPVOID *)translationList[i] );
113 segBuff = MapLS( lpBuff );
115 /* Call 16-bit routine */
117 retv = Callbacks->CallUTProc( target, segBuff, dwUserDefined );
119 /* Free temporary selectors */
125 for ( i = 0; i < nList; i++ )
126 UnMapLS( segptrList[i] );
128 HeapFree( GetProcessHeap(), 0, segptrList );
134 /****************************************************************************
137 static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
138 FARPROC16 target16, FARPROC target32 )
140 UTINFO *ut = HeapAlloc( SegptrHeap, HEAP_ZERO_MEMORY, sizeof(UTINFO) );
141 if ( !ut ) return NULL;
143 ut->hModule = hModule;
144 ut->hModule16 = hModule16;
146 ut->ut16.popl_eax = 0x58;
147 ut->ut16.pushl = 0x68;
148 ut->ut16.target = (DWORD)target32;
149 ut->ut16.pushl_eax = 0x50;
150 ut->ut16.ljmp = 0xea;
151 ut->ut16.utglue16 = (DWORD)MODULE_GetWndProcEntry16( "UTGlue16" );
153 ut->ut32.popl_eax = 0x58;
154 ut->ut32.pushl = 0x68;
155 ut->ut32.target = (DWORD)target16;
156 ut->ut32.pushl_eax = 0x50;
158 ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD));
160 ut->next = PROCESS_Current()->UTState;
161 PROCESS_Current()->UTState = ut;
166 /****************************************************************************
169 static void UTFree( UTINFO *ut )
173 for ( ptr = &PROCESS_Current()->UTState; *ptr; ptr = &(*ptr)->next )
180 HeapFree( SegptrHeap, 0, ut );
183 /****************************************************************************
186 static UTINFO *UTFind( HMODULE hModule )
190 for ( ut = PROCESS_Current()->UTState; ut; ut =ut->next )
191 if ( ut->hModule == hModule )
198 /****************************************************************************
199 * UTRegister (KERNEL32.697)
201 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
202 LPSTR lpszInitName, LPSTR lpszProcName,
203 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
208 FARPROC16 target16, init16;
210 /* Load 16-bit DLL and get UTProc16 entry point */
212 if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32
213 || (target16 = WIN32_GetProcAddress16( hModule16, lpszProcName )) == 0 )
216 /* Allocate UTINFO struct */
218 EnterCriticalSection( &PROCESS_Current()->crit_section );
219 if ( (ut = UTFind( hModule )) != NULL )
222 ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
223 LeaveCriticalSection( &PROCESS_Current()->crit_section );
227 FreeLibrary16( hModule16 );
231 /* Call UTInit16 if present */
234 && (init16 = WIN32_GetProcAddress16( hModule16, lpszInitName )) != 0 )
236 SEGPTR callback = SEGPTR_GET( &ut->ut16 );
237 SEGPTR segBuff = MapLS( lpBuff );
239 if ( !Callbacks->CallUTProc( init16, callback, segBuff ) )
242 UTUnRegister( hModule );
248 /* Return 32-bit thunk */
250 *ppfn32Thunk = (FARPROC) &ut->ut32;
255 /****************************************************************************
256 * UTUnRegister (KERNEL32.698)
258 VOID WINAPI UTUnRegister( HMODULE hModule )
261 HMODULE16 hModule16 = 0;
263 EnterCriticalSection( &PROCESS_Current()->crit_section );
264 ut = UTFind( hModule );
267 hModule16 = ut->hModule16;
270 LeaveCriticalSection( &PROCESS_Current()->crit_section );
273 FreeLibrary16( hModule16 );
276 /****************************************************************************
277 * UTInit16 (KERNEL.494)
279 WORD WINAPI UTInit16( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
281 FIXME( thunk, "(%08lx, %08lx, %08lx, %08lx): stub\n", x1, x2, x3, x4 );