2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
10 #include "selectors.h"
13 #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 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 UTINFO
*ut
= HeapAlloc( SegptrHeap
, HEAP_ZERO_MEMORY
, sizeof(UTINFO
) );
143 if ( !ut
) return NULL
;
145 ut
->hModule
= hModule
;
146 ut
->hModule16
= hModule16
;
148 ut
->ut16
.popl_eax
= 0x58;
149 ut
->ut16
.pushl
= 0x68;
150 ut
->ut16
.target
= (DWORD
)target32
;
151 ut
->ut16
.pushl_eax
= 0x50;
152 ut
->ut16
.ljmp
= 0xea;
153 ut
->ut16
.utglue16
= (DWORD
)MODULE_GetWndProcEntry16( "UTGlue16" );
155 ut
->ut32
.popl_eax
= 0x58;
156 ut
->ut32
.pushl
= 0x68;
157 ut
->ut32
.target
= (DWORD
)target16
;
158 ut
->ut32
.pushl_eax
= 0x50;
160 ut
->ut32
.utglue32
= (DWORD
)UTGlue32
- ((DWORD
)&ut
->ut32
.utglue32
+ sizeof(DWORD
));
162 ut
->next
= PROCESS_Current()->UTState
;
163 PROCESS_Current()->UTState
= ut
;
168 /****************************************************************************
171 static void UTFree( UTINFO
*ut
)
175 for ( ptr
= &PROCESS_Current()->UTState
; *ptr
; ptr
= &(*ptr
)->next
)
182 HeapFree( SegptrHeap
, 0, ut
);
185 /****************************************************************************
188 static UTINFO
*UTFind( HMODULE hModule
)
192 for ( ut
= PROCESS_Current()->UTState
; ut
; ut
=ut
->next
)
193 if ( ut
->hModule
== hModule
)
200 /****************************************************************************
201 * UTRegister (KERNEL32.697)
203 BOOL WINAPI
UTRegister( HMODULE hModule
, LPSTR lpsz16BITDLL
,
204 LPSTR lpszInitName
, LPSTR lpszProcName
,
205 FARPROC
*ppfn32Thunk
, FARPROC pfnUT32CallBack
,
210 FARPROC16 target16
, init16
;
212 /* Load 16-bit DLL and get UTProc16 entry point */
214 if ( (hModule16
= LoadLibrary16( lpsz16BITDLL
)) <= 32
215 || (target16
= WIN32_GetProcAddress16( hModule16
, lpszProcName
)) == 0 )
218 /* Allocate UTINFO struct */
220 EnterCriticalSection( &PROCESS_Current()->crit_section
);
221 if ( (ut
= UTFind( hModule
)) != NULL
)
224 ut
= UTAlloc( hModule
, hModule16
, target16
, pfnUT32CallBack
);
225 LeaveCriticalSection( &PROCESS_Current()->crit_section
);
229 FreeLibrary16( hModule16
);
233 /* Call UTInit16 if present */
236 && (init16
= WIN32_GetProcAddress16( hModule16
, lpszInitName
)) != 0 )
238 SEGPTR callback
= SEGPTR_GET( &ut
->ut16
);
239 SEGPTR segBuff
= MapLS( lpBuff
);
241 if ( !Callbacks
->CallUTProc( init16
, callback
, segBuff
) )
244 UTUnRegister( hModule
);
250 /* Return 32-bit thunk */
252 *ppfn32Thunk
= (FARPROC
) &ut
->ut32
;
257 /****************************************************************************
258 * UTUnRegister (KERNEL32.698)
260 VOID WINAPI
UTUnRegister( HMODULE hModule
)
263 HMODULE16 hModule16
= 0;
265 EnterCriticalSection( &PROCESS_Current()->crit_section
);
266 ut
= UTFind( hModule
);
269 hModule16
= ut
->hModule16
;
272 LeaveCriticalSection( &PROCESS_Current()->crit_section
);
275 FreeLibrary16( hModule16
);
278 /****************************************************************************
279 * UTInit16 (KERNEL.494)
281 WORD WINAPI
UTInit16( DWORD x1
, DWORD x2
, DWORD x3
, DWORD x4
)
283 FIXME("(%08lx, %08lx, %08lx, %08lx): stub\n", x1
, x2
, x3
, x4
);