Release 961222
[wine/gsoc-2012-control.git] / if1632 / thunk.c
blob168f2eb117fb0b108d5c15834aad5776634c0655
1 /*
2 * Emulator thunks
4 * Copyright 1996 Alexandre Julliard
5 */
7 #include "windows.h"
8 #include "callback.h"
9 #include "heap.h"
10 #include "hook.h"
11 #include "module.h"
12 #include "stddebug.h"
13 #include "debug.h"
15 typedef void (*RELAY)();
17 #pragma pack(1)
19 typedef struct tagTHUNK
21 BYTE popl_eax; /* 0x58 popl %eax (return address)*/
22 BYTE pushl_func; /* 0x68 pushl $proc */
23 FARPROC32 proc WINE_PACKED;
24 BYTE pushl_eax; /* 0x50 pushl %eax */
25 BYTE jmp; /* 0xe9 jmp relay (relative jump)*/
26 RELAY relay WINE_PACKED;
27 struct tagTHUNK *next WINE_PACKED;
28 } THUNK;
30 #pragma pack(4)
32 #define DECL_THUNK(name,proc,relay) \
33 THUNK name = { 0x58, 0x68, (FARPROC32)(proc), 0x50, 0xe9, \
34 (RELAY)((char *)(relay) - (char *)(&(name).next)), NULL }
37 static THUNK *firstThunk = NULL;
39 /***********************************************************************
40 * THUNK_Alloc
42 static THUNK *THUNK_Alloc( FARPROC32 func, RELAY relay )
44 THUNK *thunk = HeapAlloc( SystemHeap, 0, sizeof(*thunk) );
45 if (thunk)
47 thunk->popl_eax = 0x58;
48 thunk->pushl_func = 0x68;
49 thunk->proc = func;
50 thunk->pushl_eax = 0x50;
51 thunk->jmp = 0xe9;
52 thunk->relay = (RELAY)((char *)relay - (char *)(&thunk->next));
53 thunk->next = firstThunk;
54 firstThunk = thunk;
56 return thunk;
60 /***********************************************************************
61 * THUNK_Find
63 static THUNK *THUNK_Find( FARPROC32 func )
65 THUNK *thunk = firstThunk;
66 while (thunk && (thunk->proc != func)) thunk = thunk->next;
67 return thunk;
71 /***********************************************************************
72 * THUNK_Free
74 void THUNK_Free( THUNK *thunk )
76 if (HEAP_IsInsideHeap( SystemHeap, 0, thunk ))
78 THUNK **prev = &firstThunk;
79 while (*prev && (*prev != thunk)) prev = &(*prev)->next;
80 if (*prev)
82 *prev = thunk->next;
83 HeapFree( SystemHeap, 0, thunk );
84 return;
87 fprintf( stderr, "THUNK_Free: invalid thunk addr %p\n", thunk );
91 /***********************************************************************
92 * THUNK_EnumObjects16 (GDI.71)
94 INT16 THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
95 GOBJENUMPROC16 func, LPARAM lParam )
97 DECL_THUNK( thunk, func, CallTo16_word_ll );
98 return EnumObjects16( hdc, nObjType, (GOBJENUMPROC16)&thunk, lParam );
102 /***********************************************************************
103 * THUNK_EnumObjects32 (GDI32.89)
105 INT32 THUNK_EnumObjects32( HDC32 hdc, INT32 nObjType,
106 GOBJENUMPROC32 func, LPARAM lParam )
108 DECL_THUNK( thunk, func, CallTo32_2 );
109 return EnumObjects32( hdc, nObjType, (GOBJENUMPROC32)&thunk, lParam );
113 /*************************************************************************
114 * THUNK_EnumFonts16 (GDI.70)
116 INT16 THUNK_EnumFonts16( HDC16 hdc, LPCSTR lpFaceName,
117 FONTENUMPROC16 func, LPARAM lParam )
119 DECL_THUNK( thunk, func, CallTo16_word_llwl );
120 return EnumFonts16( hdc, lpFaceName, (FONTENUMPROC16)&thunk, lParam );
123 /*************************************************************************
124 * THUNK_EnumFonts32A (GDI32.84)
126 INT32 THUNK_EnumFonts32A( HDC32 hdc, LPCSTR lpFaceName,
127 FONTENUMPROC32A func, LPARAM lParam )
129 DECL_THUNK( thunk, func, CallTo32_4 );
130 return EnumFonts32A( hdc, lpFaceName, (FONTENUMPROC32A)&thunk, lParam );
133 /*************************************************************************
134 * THUNK_EnumFonts32W (GDI32.85)
136 INT32 THUNK_EnumFonts32W( HDC32 hdc, LPCWSTR lpFaceName,
137 FONTENUMPROC32W func, LPARAM lParam )
139 DECL_THUNK( thunk, func, CallTo32_4 );
140 return EnumFonts32W( hdc, lpFaceName, (FONTENUMPROC32W)&thunk, lParam );
143 /******************************************************************
144 * THUNK_EnumMetaFile16 (GDI.175)
146 BOOL16 THUNK_EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
147 MFENUMPROC16 func, LPARAM lParam )
149 DECL_THUNK( thunk, func, CallTo16_word_wllwl );
150 return EnumMetaFile( hdc, hmf, (MFENUMPROC16)&thunk, lParam );
154 /*************************************************************************
155 * THUNK_EnumFontFamilies16 (GDI.330)
157 INT16 THUNK_EnumFontFamilies16( HDC16 hdc, LPCSTR lpszFamily,
158 FONTENUMPROC16 func, LPARAM lParam )
160 DECL_THUNK( thunk, func, CallTo16_word_llwl );
161 return EnumFontFamilies16(hdc, lpszFamily, (FONTENUMPROC16)&thunk, lParam);
165 /*************************************************************************
166 * THUNK_EnumFontFamilies32A (GDI32.80)
168 INT32 THUNK_EnumFontFamilies32A( HDC32 hdc, LPCSTR lpszFamily,
169 FONTENUMPROC32A func, LPARAM lParam )
171 DECL_THUNK( thunk, func, CallTo32_4 );
172 return EnumFontFamilies32A(hdc,lpszFamily,(FONTENUMPROC32A)&thunk,lParam);
176 /*************************************************************************
177 * THUNK_EnumFontFamilies32W (GDI32.83)
179 INT32 THUNK_EnumFontFamilies32W( HDC32 hdc, LPCWSTR lpszFamily,
180 FONTENUMPROC32W func, LPARAM lParam )
182 DECL_THUNK( thunk, func, CallTo32_4 );
183 return EnumFontFamilies32W(hdc,lpszFamily,(FONTENUMPROC32W)&thunk,lParam);
186 /*************************************************************************
187 * THUNK_EnumFontFamiliesEx16 (GDI.613)
189 INT16 THUNK_EnumFontFamiliesEx16( HDC16 hdc, LPLOGFONT16 lpLF,
190 FONTENUMPROCEX16 func, LPARAM lParam,
191 DWORD reserved )
193 DECL_THUNK( thunk, func, CallTo16_word_llwl );
194 return EnumFontFamiliesEx16( hdc, lpLF, (FONTENUMPROCEX16)&thunk,
195 lParam, reserved );
199 /*************************************************************************
200 * THUNK_EnumFontFamiliesEx32A (GDI32.81)
202 INT32 THUNK_EnumFontFamiliesEx32A( HDC32 hdc, LPLOGFONT32A lpLF,
203 FONTENUMPROCEX32A func, LPARAM lParam,
204 DWORD reserved)
206 DECL_THUNK( thunk, func, CallTo32_4 );
207 return EnumFontFamiliesEx32A( hdc, lpLF, (FONTENUMPROCEX32A)&thunk,
208 lParam, reserved );
212 /*************************************************************************
213 * THUNK_EnumFontFamiliesEx32W (GDI32.82)
215 INT32 THUNK_EnumFontFamiliesEx32W( HDC32 hdc, LPLOGFONT32W lpLF,
216 FONTENUMPROCEX32W func, LPARAM lParam,
217 DWORD reserved )
219 DECL_THUNK( thunk, func, CallTo32_4 );
220 return EnumFontFamiliesEx32W( hdc, lpLF, (FONTENUMPROCEX32W)&thunk,
221 lParam, reserved );
225 /**********************************************************************
226 * THUNK_LineDDA16 (GDI.100)
228 void THUNK_LineDDA16( INT16 nXStart, INT16 nYStart, INT16 nXEnd, INT16 nYEnd,
229 LINEDDAPROC16 func, LPARAM lParam )
231 DECL_THUNK( thunk, func, CallTo16_word_wwl );
232 LineDDA16( nXStart, nYStart, nXEnd, nYEnd, (LINEDDAPROC16)&thunk, lParam );
236 /**********************************************************************
237 * THUNK_LineDDA32 (GDI32.248)
239 BOOL32 THUNK_LineDDA32( INT32 nXStart, INT32 nYStart, INT32 nXEnd, INT32 nYEnd,
240 LINEDDAPROC32 func, LPARAM lParam )
242 DECL_THUNK( thunk, func, CallTo32_3 );
243 return LineDDA32( nXStart, nYStart, nXEnd, nYEnd,
244 (LINEDDAPROC32)&thunk, lParam );
248 /*******************************************************************
249 * THUNK_EnumWindows16 (USER.54)
251 BOOL16 THUNK_EnumWindows16( WNDENUMPROC16 func, LPARAM lParam )
253 DECL_THUNK( thunk, func, CallTo16_word_wl );
254 return EnumWindows16( (WNDENUMPROC16)&thunk, lParam );
258 /*******************************************************************
259 * THUNK_EnumWindows32 (USER32.192)
261 BOOL32 THUNK_EnumWindows32( WNDENUMPROC32 func, LPARAM lParam )
263 DECL_THUNK( thunk, func, CallTo32_2 );
264 return EnumWindows32( (WNDENUMPROC32)&thunk, lParam );
268 /**********************************************************************
269 * THUNK_EnumChildWindows16 (USER.55)
271 BOOL16 THUNK_EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
272 LPARAM lParam )
274 DECL_THUNK( thunk, func, CallTo16_word_wl );
275 return EnumChildWindows16( parent, (WNDENUMPROC16)&thunk, lParam );
279 /**********************************************************************
280 * THUNK_EnumChildWindows32 (USER32.177)
282 BOOL32 THUNK_EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
283 LPARAM lParam )
285 DECL_THUNK( thunk, func, CallTo32_2 );
286 return EnumChildWindows32( parent, (WNDENUMPROC32)&thunk, lParam );
290 /**********************************************************************
291 * THUNK_EnumTaskWindows16 (USER.225)
293 BOOL16 THUNK_EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
294 LPARAM lParam )
296 DECL_THUNK( thunk, func, CallTo16_word_wl );
297 return EnumTaskWindows16( hTask, (WNDENUMPROC16)&thunk, lParam );
301 /**********************************************************************
302 * THUNK_EnumThreadWindows (USER32.189)
304 BOOL32 THUNK_EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
306 DECL_THUNK( thunk, func, CallTo32_2 );
307 return EnumThreadWindows( id, (WNDENUMPROC32)&thunk, lParam );
311 /***********************************************************************
312 * THUNK_EnumProps16 (USER.27)
314 INT16 THUNK_EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
316 DECL_THUNK( thunk, func, CallTo16_word_wlw );
317 return EnumProps16( hwnd, (PROPENUMPROC16)&thunk );
321 /***********************************************************************
322 * THUNK_EnumProps32A (USER32.185)
324 INT32 THUNK_EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
326 DECL_THUNK( thunk, func, CallTo32_3 );
327 return EnumProps32A( hwnd, (PROPENUMPROC32A)&thunk );
331 /***********************************************************************
332 * THUNK_EnumProps32W (USER32.188)
334 INT32 THUNK_EnumProps32W( HWND32 hwnd, PROPENUMPROC32W func )
336 DECL_THUNK( thunk, func, CallTo32_3 );
337 return EnumProps32W( hwnd, (PROPENUMPROC32W)&thunk );
341 /***********************************************************************
342 * THUNK_EnumPropsEx32A (USER32.186)
344 INT32 THUNK_EnumPropsEx32A( HWND32 hwnd, PROPENUMPROCEX32A func, LPARAM lParam)
346 DECL_THUNK( thunk, func, CallTo32_4 );
347 return EnumPropsEx32A( hwnd, (PROPENUMPROCEX32A)&thunk, lParam );
351 /***********************************************************************
352 * THUNK_EnumPropsEx32W (USER32.187)
354 INT32 THUNK_EnumPropsEx32W( HWND32 hwnd, PROPENUMPROCEX32W func, LPARAM lParam)
356 DECL_THUNK( thunk, func, CallTo32_4 );
357 return EnumPropsEx32W( hwnd, (PROPENUMPROCEX32W)&thunk, lParam );
361 /***********************************************************************
362 * THUNK_EnumSystemCodePages32A (KERNEL32.92)
364 BOOL32 THUNK_EnumSystemCodePages32A( CODEPAGE_ENUMPROC32A func, DWORD flags )
366 DECL_THUNK( thunk, func, CallTo32_1 );
367 return EnumSystemCodePages32A( (CODEPAGE_ENUMPROC32A)&thunk, flags );
371 /***********************************************************************
372 * THUNK_EnumSystemCodePages32W (KERNEL32.93)
374 BOOL32 THUNK_EnumSystemCodePages32W( CODEPAGE_ENUMPROC32W func, DWORD flags )
376 DECL_THUNK( thunk, func, CallTo32_1 );
377 return EnumSystemCodePages32W( (CODEPAGE_ENUMPROC32W)&thunk, flags );
380 /***********************************************************************
381 * THUNK_EnumSystemLocales32A (KERNEL32.92)
383 BOOL32 THUNK_EnumSystemLocales32A( LOCALE_ENUMPROC32A func, DWORD flags )
385 DECL_THUNK( thunk, func, CallTo32_1 );
386 return EnumSystemLocales32A( (LOCALE_ENUMPROC32A)&thunk, flags );
390 /***********************************************************************
391 * THUNK_EnumSystemLocales32W (KERNEL32.93)
393 BOOL32 THUNK_EnumSystemLocales32W( LOCALE_ENUMPROC32W func, DWORD flags )
395 DECL_THUNK( thunk, func, CallTo32_1 );
396 return EnumSystemLocales32W( (LOCALE_ENUMPROC32W)&thunk, flags );
400 /***********************************************************************
401 * THUNK_GrayString16 (USER.185)
403 BOOL16 THUNK_GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 func,
404 LPARAM lParam, INT16 cch, INT16 x, INT16 y,
405 INT16 cx, INT16 cy )
407 DECL_THUNK( thunk, func, CallTo16_word_wlw );
408 if (!func)
409 return GrayString( hdc, hbr, NULL, lParam, cch, x, y, cx, cy );
410 else
411 return GrayString( hdc, hbr, (GRAYSTRINGPROC16)&thunk, lParam, cch,
412 x, y, cx, cy );
416 /***********************************************************************
417 * THUNK_SetWindowsHook16 (USER.121)
419 FARPROC16 THUNK_SetWindowsHook16( INT16 id, HOOKPROC16 proc )
421 HINSTANCE16 hInst = FarGetOwner( HIWORD(proc) );
422 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
423 THUNK *thunk = THUNK_Alloc( (FARPROC16)proc, (RELAY)CallTo16_long_wwl );
424 if (!thunk) return 0;
425 return (FARPROC16)SetWindowsHookEx16( id, (HOOKPROC16)thunk, hInst, hTask);
429 /***********************************************************************
430 * THUNK_UnhookWindowsHook16 (USER.234)
432 BOOL16 THUNK_UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
434 BOOL16 ret;
435 THUNK *thunk = THUNK_Find( (FARPROC16)proc );
436 if (!thunk) return FALSE;
437 ret = UnhookWindowsHook16( id, (HOOKPROC16)thunk );
438 THUNK_Free( thunk );
439 return ret;
443 /***********************************************************************
444 * THUNK_SetWindowsHookEx16 (USER.291)
446 HHOOK THUNK_SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
447 HTASK16 hTask )
449 THUNK *thunk = THUNK_Alloc( (FARPROC16)proc, (RELAY)CallTo16_long_wwl );
450 if (!thunk) return 0;
451 return SetWindowsHookEx16( id, (HOOKPROC16)thunk, hInst, hTask );
455 /***********************************************************************
456 * THUNK_UnhookWindowHookEx16 (USER.292)
458 BOOL16 THUNK_UnhookWindowsHookEx16( HHOOK hhook )
460 THUNK *thunk = (THUNK *)HOOK_GetProc16( hhook );
461 BOOL16 ret = UnhookWindowsHookEx16( hhook );
462 if (thunk) THUNK_Free( thunk );
463 return ret;
467 static FARPROC16 defDCHookProc = NULL;
469 /***********************************************************************
470 * THUNK_SetDCHook (GDI.190)
472 BOOL16 THUNK_SetDCHook( HDC16 hdc, FARPROC16 proc, DWORD dwHookData )
474 THUNK *thunk, *oldThunk;
476 if (!defDCHookProc) /* Get DCHook Win16 entry point */
477 defDCHookProc = MODULE_GetEntryPoint( GetModuleHandle("USER"), 362 );
479 if (proc != defDCHookProc)
481 thunk = THUNK_Alloc( proc, (RELAY)CallTo16_word_wwll );
482 if (!thunk) return FALSE;
484 else thunk = (THUNK *)DCHook;
486 /* Free the previous thunk */
487 GetDCHook( hdc, (FARPROC16 *)&oldThunk );
488 if (oldThunk && (oldThunk != (THUNK *)DCHook)) THUNK_Free( oldThunk );
490 return SetDCHook( hdc, (FARPROC16)thunk, dwHookData );
494 /***********************************************************************
495 * THUNK_GetDCHook (GDI.191)
497 DWORD THUNK_GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
499 THUNK *thunk = NULL;
500 DWORD ret = GetDCHook( hdc, (FARPROC16 *)&thunk );
501 if (thunk)
503 if (thunk == (THUNK *)DCHook)
505 if (!defDCHookProc) /* Get DCHook Win16 entry point */
506 defDCHookProc = MODULE_GetEntryPoint( GetModuleHandle("USER"),
507 362 );
508 *phookProc = defDCHookProc;
510 else *phookProc = thunk->proc;
512 return ret;
516 struct thunkstruct
518 char magic[4];
519 DWORD x1;
520 DWORD x2;
523 UINT32 ThunkConnect32( struct thunkstruct *ths, LPSTR thunkfun16,
524 LPSTR module16, LPSTR module32, HMODULE32 hmod32,
525 DWORD dllinitarg1 )
527 HINSTANCE16 hmm;
529 fprintf(stdnimp,"ThunkConnect32(<struct>,%s,%s,%s,%x,%lx)\n",
530 thunkfun16,module32,module16,hmod32,dllinitarg1
532 fprintf(stdnimp," magic = %c%c%c%c\n",
533 ths->magic[0],
534 ths->magic[1],
535 ths->magic[2],
536 ths->magic[3]
538 fprintf(stdnimp," x1 = %lx\n",ths->x1);
539 fprintf(stdnimp," x2 = %lx\n",ths->x2);
540 hmm=LoadModule(module16,NULL);
541 return TRUE;