2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
7 #include "wine/winbase16.h"
11 #include "selectors.h"
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(thunk
);
44 typedef struct _UTINFO
55 BOOL WINAPI
UTRegister( HMODULE hModule
, LPSTR lpsz16BITDLL
,
56 LPSTR lpszInitName
, LPSTR lpszProcName
,
57 FARPROC
*ppfn32Thunk
, FARPROC pfnUT32CallBack
,
60 VOID WINAPI
UTUnRegister( HMODULE hModule
);
63 /****************************************************************************
66 DWORD WINAPI
UTGlue16( LPVOID lpBuff
, DWORD dwUserDefined
, SEGPTR translationList
[],
67 DWORD (CALLBACK
*target
)( LPVOID lpBuff
, DWORD dwUserDefined
) )
71 /* Convert arguments to flat pointers */
73 if ( translationList
)
74 for ( i
= 0; translationList
[i
]; i
++ )
76 LPVOID flatPtr
= PTR_SEG_TO_LIN( translationList
[i
] );
77 *(LPVOID
*)flatPtr
= PTR_SEG_TO_LIN( *(SEGPTR
*)flatPtr
);
80 /* Call 32-bit routine */
82 return target( lpBuff
, dwUserDefined
);
85 /****************************************************************************
88 static DWORD WINAPI
UTGlue32( FARPROC16 target
, LPVOID lpBuff
, DWORD dwUserDefined
,
89 LPVOID translationList
[] )
91 SEGPTR segBuff
, *segptrList
= NULL
;
95 /* Convert arguments to SEGPTRs */
97 if ( translationList
)
98 for ( nList
= 0; translationList
[nList
]; nList
++ )
103 segptrList
= HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR
)*nList
);
106 FIXME("Unable to allocate segptrList!" );
110 for ( i
= 0; i
< nList
; i
++ )
111 segptrList
[i
] = *(SEGPTR
*)translationList
[i
]
112 = MapLS( *(LPVOID
*)translationList
[i
] );
115 segBuff
= MapLS( lpBuff
);
117 /* Call 16-bit routine */
119 retv
= Callbacks
->CallUTProc( target
, segBuff
, dwUserDefined
);
121 /* Free temporary selectors */
127 for ( i
= 0; i
< nList
; i
++ )
128 UnMapLS( segptrList
[i
] );
130 HeapFree( GetProcessHeap(), 0, segptrList
);
136 /****************************************************************************
139 static UTINFO
*UTAlloc( HMODULE hModule
, HMODULE16 hModule16
,
140 FARPROC16 target16
, FARPROC target32
)
142 static FARPROC16 UTGlue16_Segptr
= NULL
;
145 if ( !UTGlue16_Segptr
)
147 HMODULE16 hModule
= GetModuleHandle16( "WPROCS" );
148 int ordinal
= NE_GetOrdinal( hModule
, "UTGlue16" );
149 if ( hModule
&& ordinal
)
150 UTGlue16_Segptr
= NE_GetEntryPoint( hModule
, ordinal
);
152 if ( !UTGlue16_Segptr
) return NULL
;
155 ut
= HeapAlloc( SegptrHeap
, 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
));
175 ut
->next
= PROCESS_Current()->UTState
;
176 PROCESS_Current()->UTState
= ut
;
181 /****************************************************************************
184 static void UTFree( UTINFO
*ut
)
188 for ( ptr
= &PROCESS_Current()->UTState
; *ptr
; ptr
= &(*ptr
)->next
)
195 HeapFree( SegptrHeap
, 0, ut
);
198 /****************************************************************************
201 static UTINFO
*UTFind( HMODULE hModule
)
205 for ( ut
= PROCESS_Current()->UTState
; ut
; ut
=ut
->next
)
206 if ( ut
->hModule
== hModule
)
213 /****************************************************************************
214 * UTRegister (KERNEL32.697)
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
= WIN32_GetProcAddress16( hModule16
, lpszProcName
)) == 0 )
231 /* Allocate UTINFO struct */
233 EnterCriticalSection( &PROCESS_Current()->crit_section
);
234 if ( (ut
= UTFind( hModule
)) != NULL
)
237 ut
= UTAlloc( hModule
, hModule16
, target16
, pfnUT32CallBack
);
238 LeaveCriticalSection( &PROCESS_Current()->crit_section
);
242 FreeLibrary16( hModule16
);
246 /* Call UTInit16 if present */
249 && (init16
= WIN32_GetProcAddress16( hModule16
, lpszInitName
)) != 0 )
251 SEGPTR callback
= SEGPTR_GET( &ut
->ut16
);
252 SEGPTR segBuff
= MapLS( lpBuff
);
254 if ( !Callbacks
->CallUTProc( init16
, callback
, segBuff
) )
257 UTUnRegister( hModule
);
263 /* Return 32-bit thunk */
265 *ppfn32Thunk
= (FARPROC
) &ut
->ut32
;
270 /****************************************************************************
271 * UTUnRegister (KERNEL32.698)
273 VOID WINAPI
UTUnRegister( HMODULE hModule
)
276 HMODULE16 hModule16
= 0;
278 EnterCriticalSection( &PROCESS_Current()->crit_section
);
279 ut
= UTFind( hModule
);
282 hModule16
= ut
->hModule16
;
285 LeaveCriticalSection( &PROCESS_Current()->crit_section
);
288 FreeLibrary16( hModule16
);
291 /****************************************************************************
292 * UTInit16 (KERNEL.494)
294 WORD WINAPI
UTInit16( DWORD x1
, DWORD x2
, DWORD x3
, DWORD x4
)
296 FIXME("(%08lx, %08lx, %08lx, %08lx): stub\n", x1
, x2
, x3
, x4
);