Added YUV routines needed for v4l driver, and in the future possibly
[wine/gsoc-2012-control.git] / dlls / kernel / utthunk.c
blob96e2582fe5848656ac69c90127dbf544134fb670
1 /*
2 * Win32s Universal Thunk API
4 * Copyright 1999 Ulrich Weigand
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
23 #include "wine/winbase16.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winreg.h"
27 #include "winternl.h"
28 #include "wownt32.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(thunk);
33 #include "pshpack1.h"
35 typedef struct
37 BYTE popl_eax;
38 BYTE pushl;
39 DWORD target;
40 BYTE pushl_eax;
41 BYTE ljmp;
42 DWORD utglue16;
44 } UT16THUNK;
46 typedef struct
48 BYTE popl_eax;
49 BYTE pushl;
50 DWORD target;
51 BYTE pushl_eax;
52 BYTE jmp;
53 DWORD utglue32;
55 } UT32THUNK;
57 #include "poppack.h"
59 typedef struct _UTINFO
61 struct _UTINFO *next;
62 HMODULE hModule;
63 HMODULE16 hModule16;
65 UT16THUNK ut16;
66 UT32THUNK ut32;
68 } UTINFO;
70 static UTINFO *UT_head; /* head of Universal Thunk list */
72 typedef DWORD (CALLBACK *UTGLUEPROC)( LPVOID lpBuff, DWORD dwUserDefined );
74 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
75 LPSTR lpszInitName, LPSTR lpszProcName,
76 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
77 LPVOID lpBuff );
79 VOID WINAPI UTUnRegister( HMODULE hModule );
82 /****************************************************************************
83 * UTGlue16 (KERNEL.666) (KERNEL Wine-specific export)
85 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR *translationList,
86 UTGLUEPROC target )
88 INT i;
90 /* Convert arguments to flat pointers */
92 if ( translationList )
93 for ( i = 0; translationList[i]; i++ )
95 LPVOID flatPtr = MapSL( translationList[i] );
96 *(LPVOID *)flatPtr = MapSL( *(SEGPTR *)flatPtr );
99 /* Call 32-bit routine */
101 return target( lpBuff, dwUserDefined );
104 /****************************************************************************
105 * UTGlue32
107 static DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined,
108 LPVOID translationList[] )
110 SEGPTR segBuff, *segptrList = NULL;
111 INT i, nList = 0;
112 DWORD retv;
113 WORD args[4];
115 /* Convert arguments to SEGPTRs */
117 if ( translationList )
118 for ( nList = 0; translationList[nList]; nList++ )
121 if ( nList )
123 segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList );
124 if ( !segptrList )
126 FIXME("Unable to allocate segptrList!\n" );
127 return 0;
130 for ( i = 0; i < nList; i++ )
131 segptrList[i] = *(SEGPTR *)translationList[i]
132 = MapLS( *(LPVOID *)translationList[i] );
135 segBuff = MapLS( lpBuff );
137 /* Call 16-bit routine */
139 args[3] = SELECTOROF(segBuff);
140 args[2] = OFFSETOF(segBuff);
141 args[1] = HIWORD(dwUserDefined);
142 args[0] = LOWORD(dwUserDefined);
143 WOWCallback16Ex( (DWORD)target, WCB16_PASCAL, sizeof(args), args, &retv );
145 /* Free temporary selectors */
147 UnMapLS( segBuff );
149 if ( nList )
151 for ( i = 0; i < nList; i++ )
152 UnMapLS( segptrList[i] );
154 HeapFree( GetProcessHeap(), 0, segptrList );
157 return retv;
160 /****************************************************************************
161 * UTAlloc
163 static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
164 FARPROC16 target16, FARPROC target32 )
166 static FARPROC16 UTGlue16_Segptr = NULL;
167 UTINFO *ut;
169 if ( !UTGlue16_Segptr )
171 HMODULE16 hModule = GetModuleHandle16( "KERNEL" );
172 UTGlue16_Segptr = GetProcAddress16( hModule, "UTGlue16" );
173 if ( !UTGlue16_Segptr ) return NULL;
176 ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UTINFO) );
177 if ( !ut ) return NULL;
179 ut->hModule = hModule;
180 ut->hModule16 = hModule16;
182 ut->ut16.popl_eax = 0x58;
183 ut->ut16.pushl = 0x68;
184 ut->ut16.target = (DWORD)target32;
185 ut->ut16.pushl_eax = 0x50;
186 ut->ut16.ljmp = 0xea;
187 ut->ut16.utglue16 = (DWORD)UTGlue16_Segptr;
189 ut->ut32.popl_eax = 0x58;
190 ut->ut32.pushl = 0x68;
191 ut->ut32.target = (DWORD)target16;
192 ut->ut32.pushl_eax = 0x50;
193 ut->ut32.jmp = 0xe9;
194 ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD));
196 ut->next = UT_head;
197 UT_head = ut;
199 return ut;
202 /****************************************************************************
203 * UTFree
205 static void UTFree( UTINFO *ut )
207 UTINFO **ptr;
209 for ( ptr = &UT_head; *ptr; ptr = &(*ptr)->next )
210 if ( *ptr == ut )
212 *ptr = ut->next;
213 break;
216 HeapFree( GetProcessHeap(), 0, ut );
219 /****************************************************************************
220 * UTFind
222 static UTINFO *UTFind( HMODULE hModule )
224 UTINFO *ut;
226 for ( ut = UT_head; ut; ut =ut->next )
227 if ( ut->hModule == hModule )
228 break;
230 return ut;
234 /****************************************************************************
235 * UTRegister (KERNEL32.@)
237 BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
238 LPSTR lpszInitName, LPSTR lpszProcName,
239 FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
240 LPVOID lpBuff )
242 UTINFO *ut;
243 HMODULE16 hModule16;
244 FARPROC16 target16, init16;
246 /* Load 16-bit DLL and get UTProc16 entry point */
248 if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32
249 || (target16 = GetProcAddress16( hModule16, lpszProcName )) == 0 )
250 return FALSE;
252 /* Allocate UTINFO struct */
254 RtlAcquirePebLock();
255 if ( (ut = UTFind( hModule )) != NULL )
256 ut = NULL;
257 else
258 ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
259 RtlReleasePebLock();
261 if ( !ut )
263 FreeLibrary16( hModule16 );
264 return FALSE;
267 /* Call UTInit16 if present */
269 if ( lpszInitName
270 && (init16 = GetProcAddress16( hModule16, lpszInitName )) != 0 )
272 SEGPTR callback = MapLS( &ut->ut16 );
273 SEGPTR segBuff = MapLS( lpBuff );
274 WORD args[4];
275 DWORD ret;
277 args[3] = SELECTOROF(callback);
278 args[2] = OFFSETOF(callback);
279 args[1] = SELECTOROF(segBuff);
280 args[0] = OFFSETOF(segBuff);
281 WOWCallback16Ex( (DWORD)init16, WCB16_PASCAL, sizeof(args), args, &ret );
282 UnMapLS( segBuff );
283 UnMapLS( callback );
284 if (!ret)
286 UTUnRegister( hModule );
287 return FALSE;
291 /* Return 32-bit thunk */
293 *ppfn32Thunk = (FARPROC) &ut->ut32;
295 return TRUE;
298 /****************************************************************************
299 * UTUnRegister (KERNEL32.@)
301 VOID WINAPI UTUnRegister( HMODULE hModule )
303 UTINFO *ut;
304 HMODULE16 hModule16 = 0;
306 RtlAcquirePebLock();
307 ut = UTFind( hModule );
308 if ( !ut )
310 hModule16 = ut->hModule16;
311 UTFree( ut );
313 RtlReleasePebLock();
315 if ( hModule16 )
316 FreeLibrary16( hModule16 );
319 /****************************************************************************
320 * UTInit (KERNEL.493)
322 WORD WINAPI UTInit16( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
324 FIXME("(%08lx, %08lx, %08lx, %08lx): stub\n", x1, x2, x3, x4 );
325 return 0;