Fixed DEBUG_ONLY_THIS_PROCESS again (thanks to Ulrich Weigand).
[wine/multimedia.git] / relay32 / utthunk.c
blob0ed56e83fb7d6bae4d5222a89255c1bbd101c703
1 /*
2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
5 */
7 #include "wine/winbase16.h"
8 #include "windef.h"
9 #include "heap.h"
10 #include "module.h"
11 #include "selectors.h"
12 #include "callback.h"
13 #include "process.h"
14 #include "debugtools.h"
15 #include "debugstr.h"
17 DEFAULT_DEBUG_CHANNEL(thunk)
19 #include "pshpack1.h"
21 typedef struct
23 BYTE popl_eax;
24 BYTE pushl;
25 DWORD target;
26 BYTE pushl_eax;
27 BYTE ljmp;
28 DWORD utglue16;
30 } UT16THUNK;
32 typedef struct
34 BYTE popl_eax;
35 BYTE pushl;
36 DWORD target;
37 BYTE pushl_eax;
38 BYTE jmp;
39 DWORD utglue32;
41 } UT32THUNK;
43 #include "poppack.h"
45 typedef struct _UTINFO
47 struct _UTINFO *next;
48 HMODULE hModule;
49 HMODULE16 hModule16;
51 UT16THUNK ut16;
52 UT32THUNK ut32;
54 } UTINFO;
56 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
57 LPSTR lpszInitName, LPSTR lpszProcName,
58 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
59 LPVOID lpBuff );
61 VOID WINAPI UTUnRegister( HMODULE hModule );
64 /****************************************************************************
65 * UTGlue16 (WPROCS.*)
67 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR translationList[],
68 DWORD (CALLBACK *target)( LPVOID lpBuff, DWORD dwUserDefined ) )
70 INT i;
72 /* Convert arguments to flat pointers */
74 if ( translationList )
75 for ( i = 0; translationList[i]; i++ )
77 LPVOID flatPtr = PTR_SEG_TO_LIN( translationList[i] );
78 *(LPVOID *)flatPtr = PTR_SEG_TO_LIN( *(SEGPTR *)flatPtr );
81 /* Call 32-bit routine */
83 return target( lpBuff, dwUserDefined );
86 /****************************************************************************
87 * UTGlue32
89 static DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined,
90 LPVOID translationList[] )
92 SEGPTR segBuff, *segptrList = NULL;
93 INT i, nList = 0;
94 DWORD retv;
96 /* Convert arguments to SEGPTRs */
98 if ( translationList )
99 for ( nList = 0; translationList[nList]; nList++ )
102 if ( nList )
104 segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList );
105 if ( !segptrList )
107 FIXME("Unable to allocate segptrList!" );
108 return 0;
111 for ( i = 0; i < nList; i++ )
112 segptrList[i] = *(SEGPTR *)translationList[i]
113 = MapLS( *(LPVOID *)translationList[i] );
116 segBuff = MapLS( lpBuff );
118 /* Call 16-bit routine */
120 retv = Callbacks->CallUTProc( target, segBuff, dwUserDefined );
122 /* Free temporary selectors */
124 UnMapLS( segBuff );
126 if ( nList )
128 for ( i = 0; i < nList; i++ )
129 UnMapLS( segptrList[i] );
131 HeapFree( GetProcessHeap(), 0, segptrList );
134 return retv;
137 /****************************************************************************
138 * UTAlloc
140 static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
141 FARPROC16 target16, FARPROC target32 )
143 static FARPROC16 UTGlue16_Segptr = NULL;
144 UTINFO *ut;
146 if ( !UTGlue16_Segptr )
148 HMODULE16 hModule = GetModuleHandle16( "WPROCS" );
149 int ordinal = NE_GetOrdinal( hModule, "UTGlue16" );
150 if ( hModule && ordinal )
151 UTGlue16_Segptr = NE_GetEntryPoint( hModule, ordinal );
153 if ( !UTGlue16_Segptr ) return NULL;
156 ut = HeapAlloc( SegptrHeap, HEAP_ZERO_MEMORY, sizeof(UTINFO) );
157 if ( !ut ) return NULL;
159 ut->hModule = hModule;
160 ut->hModule16 = hModule16;
162 ut->ut16.popl_eax = 0x58;
163 ut->ut16.pushl = 0x68;
164 ut->ut16.target = (DWORD)target32;
165 ut->ut16.pushl_eax = 0x50;
166 ut->ut16.ljmp = 0xea;
167 ut->ut16.utglue16 = (DWORD)UTGlue16_Segptr;
169 ut->ut32.popl_eax = 0x58;
170 ut->ut32.pushl = 0x68;
171 ut->ut32.target = (DWORD)target16;
172 ut->ut32.pushl_eax = 0x50;
173 ut->ut32.jmp = 0xe9;
174 ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD));
176 ut->next = PROCESS_Current()->UTState;
177 PROCESS_Current()->UTState = ut;
179 return ut;
182 /****************************************************************************
183 * UTFree
185 static void UTFree( UTINFO *ut )
187 UTINFO **ptr;
189 for ( ptr = &PROCESS_Current()->UTState; *ptr; ptr = &(*ptr)->next )
190 if ( *ptr == ut )
192 *ptr = ut->next;
193 break;
196 HeapFree( SegptrHeap, 0, ut );
199 /****************************************************************************
200 * UTFind
202 static UTINFO *UTFind( HMODULE hModule )
204 UTINFO *ut;
206 for ( ut = PROCESS_Current()->UTState; ut; ut =ut->next )
207 if ( ut->hModule == hModule )
208 break;
210 return ut;
214 /****************************************************************************
215 * UTRegister (KERNEL32.697)
217 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
218 LPSTR lpszInitName, LPSTR lpszProcName,
219 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
220 LPVOID lpBuff )
222 UTINFO *ut;
223 HMODULE16 hModule16;
224 FARPROC16 target16, init16;
226 /* Load 16-bit DLL and get UTProc16 entry point */
228 if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32
229 || (target16 = WIN32_GetProcAddress16( hModule16, lpszProcName )) == 0 )
230 return FALSE;
232 /* Allocate UTINFO struct */
234 EnterCriticalSection( &PROCESS_Current()->crit_section );
235 if ( (ut = UTFind( hModule )) != NULL )
236 ut = NULL;
237 else
238 ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
239 LeaveCriticalSection( &PROCESS_Current()->crit_section );
241 if ( !ut )
243 FreeLibrary16( hModule16 );
244 return FALSE;
247 /* Call UTInit16 if present */
249 if ( lpszInitName
250 && (init16 = WIN32_GetProcAddress16( hModule16, lpszInitName )) != 0 )
252 SEGPTR callback = SEGPTR_GET( &ut->ut16 );
253 SEGPTR segBuff = MapLS( lpBuff );
255 if ( !Callbacks->CallUTProc( init16, callback, segBuff ) )
257 UnMapLS( segBuff );
258 UTUnRegister( hModule );
259 return FALSE;
261 UnMapLS( segBuff );
264 /* Return 32-bit thunk */
266 *ppfn32Thunk = (FARPROC) &ut->ut32;
268 return TRUE;
271 /****************************************************************************
272 * UTUnRegister (KERNEL32.698)
274 VOID WINAPI UTUnRegister( HMODULE hModule )
276 UTINFO *ut;
277 HMODULE16 hModule16 = 0;
279 EnterCriticalSection( &PROCESS_Current()->crit_section );
280 ut = UTFind( hModule );
281 if ( !ut )
283 hModule16 = ut->hModule16;
284 UTFree( ut );
286 LeaveCriticalSection( &PROCESS_Current()->crit_section );
288 if ( hModule16 )
289 FreeLibrary16( hModule16 );
292 /****************************************************************************
293 * UTInit16 (KERNEL.494)
295 WORD WINAPI UTInit16( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
297 FIXME("(%08lx, %08lx, %08lx, %08lx): stub\n", x1, x2, x3, x4 );
298 return 0;