2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
7 #include "wine/winbase16.h"
12 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(thunk
);
42 typedef struct _UTINFO
53 static UTINFO
*UT_head
; /* head of Universal Thunk list */
55 typedef DWORD (CALLBACK
*UTGLUEPROC
)( LPVOID lpBuff
, DWORD dwUserDefined
);
57 BOOL WINAPI
UTRegister( HMODULE hModule
, LPSTR lpsz16BITDLL
,
58 LPSTR lpszInitName
, LPSTR lpszProcName
,
59 FARPROC
*ppfn32Thunk
, FARPROC pfnUT32CallBack
,
62 VOID WINAPI
UTUnRegister( HMODULE hModule
);
64 /* ### start build ### */
65 extern LONG CALLBACK
UTTHUNK_CallTo16_long_ll(FARPROC16
,LONG
,LONG
);
66 /* ### stop build ### */
68 /****************************************************************************
69 * UTGlue16 (KERNEL.666) (KERNEL Wine-specific export)
71 DWORD WINAPI
UTGlue16( LPVOID lpBuff
, DWORD dwUserDefined
, SEGPTR
*translationList
,
76 /* Convert arguments to flat pointers */
78 if ( translationList
)
79 for ( i
= 0; translationList
[i
]; i
++ )
81 LPVOID flatPtr
= MapSL( translationList
[i
] );
82 *(LPVOID
*)flatPtr
= MapSL( *(SEGPTR
*)flatPtr
);
85 /* Call 32-bit routine */
87 return target( lpBuff
, dwUserDefined
);
90 /****************************************************************************
93 static DWORD WINAPI
UTGlue32( FARPROC16 target
, LPVOID lpBuff
, DWORD dwUserDefined
,
94 LPVOID translationList
[] )
96 SEGPTR segBuff
, *segptrList
= NULL
;
100 /* Convert arguments to SEGPTRs */
102 if ( translationList
)
103 for ( nList
= 0; translationList
[nList
]; nList
++ )
108 segptrList
= HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR
)*nList
);
111 FIXME("Unable to allocate segptrList!" );
115 for ( i
= 0; i
< nList
; i
++ )
116 segptrList
[i
] = *(SEGPTR
*)translationList
[i
]
117 = MapLS( *(LPVOID
*)translationList
[i
] );
120 segBuff
= MapLS( lpBuff
);
122 /* Call 16-bit routine */
124 retv
= UTTHUNK_CallTo16_long_ll( target
, segBuff
, dwUserDefined
);
126 /* Free temporary selectors */
132 for ( i
= 0; i
< nList
; i
++ )
133 UnMapLS( segptrList
[i
] );
135 HeapFree( GetProcessHeap(), 0, segptrList
);
141 /****************************************************************************
144 static UTINFO
*UTAlloc( HMODULE hModule
, HMODULE16 hModule16
,
145 FARPROC16 target16
, FARPROC target32
)
147 static FARPROC16 UTGlue16_Segptr
= NULL
;
150 if ( !UTGlue16_Segptr
)
152 HMODULE16 hModule
= GetModuleHandle16( "KERNEL" );
153 UTGlue16_Segptr
= GetProcAddress16( hModule
, "UTGlue16" );
154 if ( !UTGlue16_Segptr
) return NULL
;
157 ut
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
|HEAP_WINE_SEGPTR
, sizeof(UTINFO
) );
158 if ( !ut
) return NULL
;
160 ut
->hModule
= hModule
;
161 ut
->hModule16
= hModule16
;
163 ut
->ut16
.popl_eax
= 0x58;
164 ut
->ut16
.pushl
= 0x68;
165 ut
->ut16
.target
= (DWORD
)target32
;
166 ut
->ut16
.pushl_eax
= 0x50;
167 ut
->ut16
.ljmp
= 0xea;
168 ut
->ut16
.utglue16
= (DWORD
)UTGlue16_Segptr
;
170 ut
->ut32
.popl_eax
= 0x58;
171 ut
->ut32
.pushl
= 0x68;
172 ut
->ut32
.target
= (DWORD
)target16
;
173 ut
->ut32
.pushl_eax
= 0x50;
175 ut
->ut32
.utglue32
= (DWORD
)UTGlue32
- ((DWORD
)&ut
->ut32
.utglue32
+ sizeof(DWORD
));
183 /****************************************************************************
186 static void UTFree( UTINFO
*ut
)
190 for ( ptr
= &UT_head
; *ptr
; ptr
= &(*ptr
)->next
)
197 HeapFree( GetProcessHeap(), HEAP_WINE_SEGPTR
, ut
);
200 /****************************************************************************
203 static UTINFO
*UTFind( HMODULE hModule
)
207 for ( ut
= UT_head
; ut
; ut
=ut
->next
)
208 if ( ut
->hModule
== hModule
)
215 /****************************************************************************
216 * UTRegister (KERNEL32.698)
218 BOOL WINAPI
UTRegister( HMODULE hModule
, LPSTR lpsz16BITDLL
,
219 LPSTR lpszInitName
, LPSTR lpszProcName
,
220 FARPROC
*ppfn32Thunk
, FARPROC pfnUT32CallBack
,
225 FARPROC16 target16
, init16
;
227 /* Load 16-bit DLL and get UTProc16 entry point */
229 if ( (hModule16
= LoadLibrary16( lpsz16BITDLL
)) <= 32
230 || (target16
= GetProcAddress16( hModule16
, lpszProcName
)) == 0 )
233 /* Allocate UTINFO struct */
236 if ( (ut
= UTFind( hModule
)) != NULL
)
239 ut
= UTAlloc( hModule
, hModule16
, target16
, pfnUT32CallBack
);
244 FreeLibrary16( hModule16
);
248 /* Call UTInit16 if present */
251 && (init16
= GetProcAddress16( hModule16
, lpszInitName
)) != 0 )
253 SEGPTR callback
= SEGPTR_GET( &ut
->ut16
);
254 SEGPTR segBuff
= MapLS( lpBuff
);
256 if ( !UTTHUNK_CallTo16_long_ll( init16
, callback
, segBuff
) )
259 UTUnRegister( hModule
);
265 /* Return 32-bit thunk */
267 *ppfn32Thunk
= (FARPROC
) &ut
->ut32
;
272 /****************************************************************************
273 * UTUnRegister (KERNEL32.699)
275 VOID WINAPI
UTUnRegister( HMODULE hModule
)
278 HMODULE16 hModule16
= 0;
281 ut
= UTFind( hModule
);
284 hModule16
= ut
->hModule16
;
290 FreeLibrary16( hModule16
);
293 /****************************************************************************
294 * UTInit16 (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
);