2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
10 #include "selectors.h"
41 typedef struct tagUTINFO
43 struct tagUTINFO
*next
;
52 static UTINFO
*utAnchor
;
54 BOOL WINAPI
UTRegister( HMODULE hModule
, LPSTR lpsz16BITDLL
,
55 LPSTR lpszInitName
, LPSTR lpszProcName
,
56 FARPROC
*ppfn32Thunk
, FARPROC pfnUT32CallBack
,
59 VOID WINAPI
UTUnRegister( HMODULE hModule
);
62 /****************************************************************************
65 DWORD WINAPI
UTGlue16( LPVOID lpBuff
, DWORD dwUserDefined
, SEGPTR translationList
[],
66 DWORD (CALLBACK
*target
)( LPVOID lpBuff
, DWORD dwUserDefined
) )
70 /* Convert arguments to flat pointers */
72 if ( translationList
)
73 for ( i
= 0; translationList
[i
]; i
++ )
75 LPVOID flatPtr
= PTR_SEG_TO_LIN( translationList
[i
] );
76 *(LPVOID
*)flatPtr
= PTR_SEG_TO_LIN( *(SEGPTR
*)flatPtr
);
79 /* Call 32-bit routine */
81 return target( lpBuff
, dwUserDefined
);
84 /****************************************************************************
87 DWORD WINAPI
UTGlue32( FARPROC16 target
, LPVOID lpBuff
, DWORD dwUserDefined
,
88 LPVOID translationList
[] )
90 SEGPTR segBuff
, *segptrList
= NULL
;
94 /* Convert arguments to SEGPTRs */
96 if ( translationList
)
97 for ( nList
= 0; translationList
[nList
]; nList
++ )
102 segptrList
= HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR
)*nList
);
105 FIXME( thunk
, "Unable to allocate segptrList!" );
109 for ( i
= 0; i
< nList
; i
++ )
110 segptrList
[i
] = *(SEGPTR
*)translationList
[i
]
111 = MapLS( *(LPVOID
*)translationList
[i
] );
114 segBuff
= MapLS( lpBuff
);
116 /* Call 16-bit routine */
118 retv
= Callbacks
->CallUTProc( target
, segBuff
, dwUserDefined
);
120 /* Free temporary selectors */
126 for ( i
= 0; i
< nList
; i
++ )
127 UnMapLS( segptrList
[i
] );
129 HeapFree( GetProcessHeap(), 0, segptrList
);
135 /****************************************************************************
138 static UTINFO
*UTAlloc( HMODULE hModule
, HMODULE16 hModule16
,
139 FARPROC16 target16
, FARPROC target32
)
141 UTINFO
*ut
= HeapAlloc( SegptrHeap
, HEAP_ZERO_MEMORY
, sizeof(UTINFO
) );
142 if ( !ut
) return NULL
;
144 ut
->hModule
= hModule
;
145 ut
->hModule16
= hModule16
;
147 ut
->ut16
.popl_eax
= 0x58;
148 ut
->ut16
.pushl
= 0x68;
149 ut
->ut16
.target
= (DWORD
)target32
;
150 ut
->ut16
.pushl_eax
= 0x50;
151 ut
->ut16
.ljmp
= 0xea;
152 ut
->ut16
.utglue16
= (DWORD
)MODULE_GetWndProcEntry16( "UTGlue16" );
154 ut
->ut32
.popl_eax
= 0x58;
155 ut
->ut32
.pushl
= 0x68;
156 ut
->ut32
.target
= (DWORD
)target16
;
157 ut
->ut32
.pushl_eax
= 0x50;
159 ut
->ut32
.utglue32
= (DWORD
)UTGlue32
- ((DWORD
)&ut
->ut32
.utglue32
+ sizeof(DWORD
));
167 /****************************************************************************
170 static void UTFree( UTINFO
*ut
)
174 for ( ptr
= &utAnchor
; *ptr
; ptr
= &(*ptr
)->next
)
181 HeapFree( SegptrHeap
, 0, ut
);
184 /****************************************************************************
187 static UTINFO
*UTFind( HMODULE hModule
)
191 for ( ut
= utAnchor
; ut
; ut
=ut
->next
)
192 if ( ut
->hModule
== hModule
)
199 /****************************************************************************
200 * UTRegister (KERNEL32.697)
202 BOOL WINAPI
UTRegister( HMODULE hModule
, LPSTR lpsz16BITDLL
,
203 LPSTR lpszInitName
, LPSTR lpszProcName
,
204 FARPROC
*ppfn32Thunk
, FARPROC pfnUT32CallBack
,
209 FARPROC16 target16
, init16
;
211 /* Load 16-bit DLL and get UTProc16 entry point */
213 if ( (hModule16
= LoadLibrary16( lpsz16BITDLL
)) <= 32
214 || (target16
= WIN32_GetProcAddress16( hModule16
, lpszProcName
)) == 0 )
217 /* Allocate UTINFO struct */
220 if ( (ut
= UTFind( hModule
)) != NULL
)
223 ut
= UTAlloc( hModule
, hModule16
, target16
, pfnUT32CallBack
);
228 FreeLibrary16( hModule16
);
232 /* Call UTInit16 if present */
235 && (init16
= WIN32_GetProcAddress16( hModule16
, lpszInitName
)) != 0 )
237 SEGPTR callback
= SEGPTR_GET( &ut
->ut16
);
238 SEGPTR segBuff
= MapLS( lpBuff
);
240 if ( !Callbacks
->CallUTProc( init16
, callback
, segBuff
) )
243 UTUnRegister( hModule
);
249 /* Return 32-bit thunk */
251 *ppfn32Thunk
= (FARPROC
) &ut
->ut32
;
256 /****************************************************************************
257 * UTUnRegister (KERNEL32.698)
259 VOID WINAPI
UTUnRegister( HMODULE hModule
)
262 HMODULE16 hModule16
= 0;
265 ut
= UTFind( hModule
);
268 hModule16
= ut
->hModule16
;
274 FreeLibrary16( hModule16
);
277 /****************************************************************************
278 * UTInit16 (KERNEL.494)
280 WORD WINAPI
UTInit16( DWORD x1
, DWORD x2
, DWORD x3
, DWORD x4
)
282 FIXME( thunk
, "(%08lx, %08lx, %08lx, %08lx): stub\n", x1
, x2
, x3
, x4
);