Got rid of SYSTEM_LOCK macros.
[wine/multimedia.git] / relay32 / utthunk.c
blob18b0ed01ed74d442ac619c1f7c69769aa9cf0180
1 /*
2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
5 */
7 #include "windef.h"
8 #include "heap.h"
9 #include "module.h"
10 #include "selectors.h"
11 #include "callback.h"
12 #include "debug.h"
13 #include "debugstr.h"
15 #pragma pack(1)
17 typedef struct
19 BYTE popl_eax;
20 BYTE pushl;
21 DWORD target;
22 BYTE pushl_eax;
23 BYTE ljmp;
24 DWORD utglue16;
26 } UT16THUNK;
28 typedef struct
30 BYTE popl_eax;
31 BYTE pushl;
32 DWORD target;
33 BYTE pushl_eax;
34 BYTE jmp;
35 DWORD utglue32;
37 } UT32THUNK;
39 #pragma pack(4)
41 typedef struct tagUTINFO
43 struct tagUTINFO *next;
44 HMODULE hModule;
45 HMODULE16 hModule16;
47 UT16THUNK ut16;
48 UT32THUNK ut32;
50 } UTINFO;
52 static UTINFO *utAnchor;
54 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
55 LPSTR lpszInitName, LPSTR lpszProcName,
56 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
57 LPVOID lpBuff );
59 VOID WINAPI UTUnRegister( HMODULE hModule );
62 /****************************************************************************
63 * UTGlue16 (WPROCS.*)
65 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR translationList[],
66 DWORD (CALLBACK *target)( LPVOID lpBuff, DWORD dwUserDefined ) )
68 INT i;
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 /****************************************************************************
85 * UTGlue32
87 DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined,
88 LPVOID translationList[] )
90 SEGPTR segBuff, *segptrList = NULL;
91 INT i, nList = 0;
92 DWORD retv;
94 /* Convert arguments to SEGPTRs */
96 if ( translationList )
97 for ( nList = 0; translationList[nList]; nList++ )
100 if ( nList )
102 segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList );
103 if ( !segptrList )
105 FIXME( thunk, "Unable to allocate segptrList!" );
106 return 0;
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 */
122 UnMapLS( segBuff );
124 if ( nList )
126 for ( i = 0; i < nList; i++ )
127 UnMapLS( segptrList[i] );
129 HeapFree( GetProcessHeap(), 0, segptrList );
132 return retv;
135 /****************************************************************************
136 * UTAlloc
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;
158 ut->ut32.jmp = 0xe9;
159 ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD));
161 ut->next = utAnchor;
162 utAnchor = ut;
164 return ut;
167 /****************************************************************************
168 * UTFree
170 static void UTFree( UTINFO *ut )
172 UTINFO **ptr;
174 for ( ptr = &utAnchor; *ptr; ptr = &(*ptr)->next )
175 if ( *ptr == ut )
177 *ptr = ut->next;
178 break;
181 HeapFree( SegptrHeap, 0, ut );
184 /****************************************************************************
185 * UTFind
187 static UTINFO *UTFind( HMODULE hModule )
189 UTINFO *ut;
191 for ( ut = utAnchor; ut; ut =ut->next )
192 if ( ut->hModule == hModule )
193 break;
195 return ut;
199 /****************************************************************************
200 * UTRegister (KERNEL32.697)
202 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
203 LPSTR lpszInitName, LPSTR lpszProcName,
204 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
205 LPVOID lpBuff )
207 UTINFO *ut;
208 HMODULE16 hModule16;
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 )
215 return FALSE;
217 /* Allocate UTINFO struct */
219 HeapLock( SegptrHeap ); /* FIXME: a bit overkill */
220 if ( (ut = UTFind( hModule )) != NULL )
221 ut = NULL;
222 else
223 ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
224 HeapUnlock( SegptrHeap );
226 if ( !ut )
228 FreeLibrary16( hModule16 );
229 return FALSE;
232 /* Call UTInit16 if present */
234 if ( lpszInitName
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 ) )
242 UnMapLS( segBuff );
243 UTUnRegister( hModule );
244 return FALSE;
246 UnMapLS( segBuff );
249 /* Return 32-bit thunk */
251 *ppfn32Thunk = (FARPROC) &ut->ut32;
253 return TRUE;
256 /****************************************************************************
257 * UTUnRegister (KERNEL32.698)
259 VOID WINAPI UTUnRegister( HMODULE hModule )
261 UTINFO *ut;
262 HMODULE16 hModule16 = 0;
264 HeapLock( SegptrHeap ); /* FIXME: a bit overkill */
265 ut = UTFind( hModule );
266 if ( !ut )
268 hModule16 = ut->hModule16;
269 UTFree( ut );
271 HeapUnlock( SegptrHeap );
273 if ( 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 );
283 return 0;