4 * Copyright 1996 Alexandre Julliard
16 typedef void (*RELAY
)();
20 typedef struct tagTHUNK
22 BYTE popl_eax
; /* 0x58 popl %eax (return address)*/
23 BYTE pushl_func
; /* 0x68 pushl $proc */
24 FARPROC32 proc WINE_PACKED
;
25 BYTE pushl_eax
; /* 0x50 pushl %eax */
26 BYTE jmp
; /* 0xe9 jmp relay (relative jump)*/
27 RELAY relay WINE_PACKED
;
28 struct tagTHUNK
*next WINE_PACKED
;
33 #define DECL_THUNK(name,proc,relay) \
34 THUNK name = { 0x58, 0x68, (FARPROC32)(proc), 0x50, 0xe9, \
35 (RELAY)((char *)(relay) - (char *)(&(name).next)), NULL }
38 static THUNK
*firstThunk
= NULL
;
40 /***********************************************************************
43 static THUNK
*THUNK_Alloc( FARPROC32 func
, RELAY relay
)
45 THUNK
*thunk
= HeapAlloc( GetProcessHeap(), 0, sizeof(*thunk
) );
48 thunk
->popl_eax
= 0x58;
49 thunk
->pushl_func
= 0x68;
51 thunk
->pushl_eax
= 0x50;
53 thunk
->relay
= (RELAY
)((char *)relay
- (char *)(&thunk
->next
));
54 thunk
->next
= firstThunk
;
61 /***********************************************************************
64 static THUNK
*THUNK_Find( FARPROC32 func
)
66 THUNK
*thunk
= firstThunk
;
67 while (thunk
&& (thunk
->proc
!= func
)) thunk
= thunk
->next
;
72 /***********************************************************************
75 void THUNK_Free( THUNK
*thunk
)
77 if (HEAP_IsInsideHeap( GetProcessHeap(), 0, thunk
))
79 THUNK
**prev
= &firstThunk
;
80 while (*prev
&& (*prev
!= thunk
)) prev
= &(*prev
)->next
;
84 HeapFree( GetProcessHeap(), 0, thunk
);
88 fprintf( stderr
, "THUNK_Free: invalid thunk addr %p\n", thunk
);
92 /***********************************************************************
93 * THUNK_EnumObjects16 (GDI.71)
95 INT16
THUNK_EnumObjects16( HDC16 hdc
, INT16 nObjType
,
96 GOBJENUMPROC16 func
, LPARAM lParam
)
98 DECL_THUNK( thunk
, func
, CallTo16_word_ll
);
99 return EnumObjects16( hdc
, nObjType
, (GOBJENUMPROC16
)&thunk
, lParam
);
103 /***********************************************************************
104 * THUNK_EnumObjects32 (GDI32.89)
106 INT32
THUNK_EnumObjects32( HDC32 hdc
, INT32 nObjType
,
107 GOBJENUMPROC32 func
, LPARAM lParam
)
109 DECL_THUNK( thunk
, func
, CallTo32_2
);
110 return EnumObjects32( hdc
, nObjType
, (GOBJENUMPROC32
)&thunk
, lParam
);
114 /*************************************************************************
115 * THUNK_EnumFonts16 (GDI.70)
117 INT16
THUNK_EnumFonts16( HDC16 hdc
, LPCSTR lpFaceName
,
118 FONTENUMPROC16 func
, LPARAM lParam
)
120 DECL_THUNK( thunk
, func
, CallTo16_word_llwl
);
121 return EnumFonts16( hdc
, lpFaceName
, (FONTENUMPROC16
)&thunk
, lParam
);
124 /*************************************************************************
125 * THUNK_EnumFonts32A (GDI32.84)
127 INT32
THUNK_EnumFonts32A( HDC32 hdc
, LPCSTR lpFaceName
,
128 FONTENUMPROC32A func
, LPARAM lParam
)
130 DECL_THUNK( thunk
, func
, CallTo32_4
);
131 return EnumFonts32A( hdc
, lpFaceName
, (FONTENUMPROC32A
)&thunk
, lParam
);
134 /*************************************************************************
135 * THUNK_EnumFonts32W (GDI32.85)
137 INT32
THUNK_EnumFonts32W( HDC32 hdc
, LPCWSTR lpFaceName
,
138 FONTENUMPROC32W func
, LPARAM lParam
)
140 DECL_THUNK( thunk
, func
, CallTo32_4
);
141 return EnumFonts32W( hdc
, lpFaceName
, (FONTENUMPROC32W
)&thunk
, lParam
);
144 /******************************************************************
145 * THUNK_EnumMetaFile16 (GDI.175)
147 BOOL16
THUNK_EnumMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
,
148 MFENUMPROC16 func
, LPARAM lParam
)
150 DECL_THUNK( thunk
, func
, CallTo16_word_wllwl
);
151 return EnumMetaFile16( hdc
, hmf
, (MFENUMPROC16
)&thunk
, lParam
);
155 /*************************************************************************
156 * THUNK_EnumFontFamilies16 (GDI.330)
158 INT16
THUNK_EnumFontFamilies16( HDC16 hdc
, LPCSTR lpszFamily
,
159 FONTENUMPROC16 func
, LPARAM lParam
)
161 DECL_THUNK( thunk
, func
, CallTo16_word_llwl
);
162 return EnumFontFamilies16(hdc
, lpszFamily
, (FONTENUMPROC16
)&thunk
, lParam
);
166 /*************************************************************************
167 * THUNK_EnumFontFamilies32A (GDI32.80)
169 INT32
THUNK_EnumFontFamilies32A( HDC32 hdc
, LPCSTR lpszFamily
,
170 FONTENUMPROC32A func
, LPARAM lParam
)
172 DECL_THUNK( thunk
, func
, CallTo32_4
);
173 return EnumFontFamilies32A(hdc
,lpszFamily
,(FONTENUMPROC32A
)&thunk
,lParam
);
177 /*************************************************************************
178 * THUNK_EnumFontFamilies32W (GDI32.83)
180 INT32
THUNK_EnumFontFamilies32W( HDC32 hdc
, LPCWSTR lpszFamily
,
181 FONTENUMPROC32W func
, LPARAM lParam
)
183 DECL_THUNK( thunk
, func
, CallTo32_4
);
184 return EnumFontFamilies32W(hdc
,lpszFamily
,(FONTENUMPROC32W
)&thunk
,lParam
);
187 /*************************************************************************
188 * THUNK_EnumFontFamiliesEx16 (GDI.613)
190 INT16
THUNK_EnumFontFamiliesEx16( HDC16 hdc
, LPLOGFONT16 lpLF
,
191 FONTENUMPROCEX16 func
, LPARAM lParam
,
194 DECL_THUNK( thunk
, func
, CallTo16_word_llwl
);
195 return EnumFontFamiliesEx16( hdc
, lpLF
, (FONTENUMPROCEX16
)&thunk
,
200 /*************************************************************************
201 * THUNK_EnumFontFamiliesEx32A (GDI32.81)
203 INT32
THUNK_EnumFontFamiliesEx32A( HDC32 hdc
, LPLOGFONT32A lpLF
,
204 FONTENUMPROCEX32A func
, LPARAM lParam
,
207 DECL_THUNK( thunk
, func
, CallTo32_4
);
208 return EnumFontFamiliesEx32A( hdc
, lpLF
, (FONTENUMPROCEX32A
)&thunk
,
213 /*************************************************************************
214 * THUNK_EnumFontFamiliesEx32W (GDI32.82)
216 INT32
THUNK_EnumFontFamiliesEx32W( HDC32 hdc
, LPLOGFONT32W lpLF
,
217 FONTENUMPROCEX32W func
, LPARAM lParam
,
220 DECL_THUNK( thunk
, func
, CallTo32_4
);
221 return EnumFontFamiliesEx32W( hdc
, lpLF
, (FONTENUMPROCEX32W
)&thunk
,
226 /**********************************************************************
227 * THUNK_LineDDA16 (GDI.100)
229 void THUNK_LineDDA16( INT16 nXStart
, INT16 nYStart
, INT16 nXEnd
, INT16 nYEnd
,
230 LINEDDAPROC16 func
, LPARAM lParam
)
232 DECL_THUNK( thunk
, func
, CallTo16_word_wwl
);
233 LineDDA16( nXStart
, nYStart
, nXEnd
, nYEnd
, (LINEDDAPROC16
)&thunk
, lParam
);
237 /**********************************************************************
238 * THUNK_LineDDA32 (GDI32.248)
240 BOOL32
THUNK_LineDDA32( INT32 nXStart
, INT32 nYStart
, INT32 nXEnd
, INT32 nYEnd
,
241 LINEDDAPROC32 func
, LPARAM lParam
)
243 DECL_THUNK( thunk
, func
, CallTo32_3
);
244 return LineDDA32( nXStart
, nYStart
, nXEnd
, nYEnd
,
245 (LINEDDAPROC32
)&thunk
, lParam
);
249 /*******************************************************************
250 * THUNK_EnumWindows16 (USER.54)
252 BOOL16
THUNK_EnumWindows16( WNDENUMPROC16 func
, LPARAM lParam
)
254 DECL_THUNK( thunk
, func
, CallTo16_word_wl
);
255 return EnumWindows16( (WNDENUMPROC16
)&thunk
, lParam
);
259 /*******************************************************************
260 * THUNK_EnumWindows32 (USER32.192)
262 BOOL32
THUNK_EnumWindows32( WNDENUMPROC32 func
, LPARAM lParam
)
264 DECL_THUNK( thunk
, func
, CallTo32_2
);
265 return EnumWindows32( (WNDENUMPROC32
)&thunk
, lParam
);
269 /**********************************************************************
270 * THUNK_EnumChildWindows16 (USER.55)
272 BOOL16
THUNK_EnumChildWindows16( HWND16 parent
, WNDENUMPROC16 func
,
275 DECL_THUNK( thunk
, func
, CallTo16_word_wl
);
276 return EnumChildWindows16( parent
, (WNDENUMPROC16
)&thunk
, lParam
);
280 /**********************************************************************
281 * THUNK_EnumChildWindows32 (USER32.177)
283 BOOL32
THUNK_EnumChildWindows32( HWND32 parent
, WNDENUMPROC32 func
,
286 DECL_THUNK( thunk
, func
, CallTo32_2
);
287 return EnumChildWindows32( parent
, (WNDENUMPROC32
)&thunk
, lParam
);
291 /**********************************************************************
292 * THUNK_EnumTaskWindows16 (USER.225)
294 BOOL16
THUNK_EnumTaskWindows16( HTASK16 hTask
, WNDENUMPROC16 func
,
297 DECL_THUNK( thunk
, func
, CallTo16_word_wl
);
298 return EnumTaskWindows16( hTask
, (WNDENUMPROC16
)&thunk
, lParam
);
302 /**********************************************************************
303 * THUNK_EnumThreadWindows (USER32.189)
305 BOOL32
THUNK_EnumThreadWindows( DWORD id
, WNDENUMPROC32 func
, LPARAM lParam
)
307 DECL_THUNK( thunk
, func
, CallTo32_2
);
308 return EnumThreadWindows( id
, (WNDENUMPROC32
)&thunk
, lParam
);
312 /***********************************************************************
313 * THUNK_EnumProps16 (USER.27)
315 INT16
THUNK_EnumProps16( HWND16 hwnd
, PROPENUMPROC16 func
)
317 DECL_THUNK( thunk
, func
, CallTo16_word_wlw
);
318 return EnumProps16( hwnd
, (PROPENUMPROC16
)&thunk
);
322 /***********************************************************************
323 * THUNK_EnumProps32A (USER32.185)
325 INT32
THUNK_EnumProps32A( HWND32 hwnd
, PROPENUMPROC32A func
)
327 DECL_THUNK( thunk
, func
, CallTo32_3
);
328 return EnumProps32A( hwnd
, (PROPENUMPROC32A
)&thunk
);
332 /***********************************************************************
333 * THUNK_EnumProps32W (USER32.188)
335 INT32
THUNK_EnumProps32W( HWND32 hwnd
, PROPENUMPROC32W func
)
337 DECL_THUNK( thunk
, func
, CallTo32_3
);
338 return EnumProps32W( hwnd
, (PROPENUMPROC32W
)&thunk
);
342 /***********************************************************************
343 * THUNK_EnumPropsEx32A (USER32.186)
345 INT32
THUNK_EnumPropsEx32A( HWND32 hwnd
, PROPENUMPROCEX32A func
, LPARAM lParam
)
347 DECL_THUNK( thunk
, func
, CallTo32_4
);
348 return EnumPropsEx32A( hwnd
, (PROPENUMPROCEX32A
)&thunk
, lParam
);
352 /***********************************************************************
353 * THUNK_EnumPropsEx32W (USER32.187)
355 INT32
THUNK_EnumPropsEx32W( HWND32 hwnd
, PROPENUMPROCEX32W func
, LPARAM lParam
)
357 DECL_THUNK( thunk
, func
, CallTo32_4
);
358 return EnumPropsEx32W( hwnd
, (PROPENUMPROCEX32W
)&thunk
, lParam
);
362 /***********************************************************************
363 * THUNK_EnumSystemCodePages32A (KERNEL32.92)
365 BOOL32
THUNK_EnumSystemCodePages32A( CODEPAGE_ENUMPROC32A func
, DWORD flags
)
367 DECL_THUNK( thunk
, func
, CallTo32_1
);
368 return EnumSystemCodePages32A( (CODEPAGE_ENUMPROC32A
)&thunk
, flags
);
372 /***********************************************************************
373 * THUNK_EnumSystemCodePages32W (KERNEL32.93)
375 BOOL32
THUNK_EnumSystemCodePages32W( CODEPAGE_ENUMPROC32W func
, DWORD flags
)
377 DECL_THUNK( thunk
, func
, CallTo32_1
);
378 return EnumSystemCodePages32W( (CODEPAGE_ENUMPROC32W
)&thunk
, flags
);
381 /***********************************************************************
382 * THUNK_EnumSystemLocales32A (KERNEL32.92)
384 BOOL32
THUNK_EnumSystemLocales32A( LOCALE_ENUMPROC32A func
, DWORD flags
)
386 DECL_THUNK( thunk
, func
, CallTo32_1
);
387 return EnumSystemLocales32A( (LOCALE_ENUMPROC32A
)&thunk
, flags
);
391 /***********************************************************************
392 * THUNK_EnumSystemLocales32W (KERNEL32.93)
394 BOOL32
THUNK_EnumSystemLocales32W( LOCALE_ENUMPROC32W func
, DWORD flags
)
396 DECL_THUNK( thunk
, func
, CallTo32_1
);
397 return EnumSystemLocales32W( (LOCALE_ENUMPROC32W
)&thunk
, flags
);
400 /***********************************************************************
401 * THUNK_EnumResourceLanguages32W (KERNEL32.87)
403 BOOL32
THUNK_EnumResourceLanguages32W( HMODULE32 hmod
,LPCWSTR type
,LPCWSTR name
,ENUMRESLANGPROC32W func
, LONG lParam
)
405 DECL_THUNK( thunk
, func
, CallTo32_5
);
406 return EnumResourceLanguages32W( hmod
,type
,name
,(ENUMRESLANGPROC32W
)&thunk
, lParam
);
409 /***********************************************************************
410 * THUNK_EnumResourceLanguages32A (KERNEL32.86)
412 BOOL32
THUNK_EnumResourceLanguages32A( HMODULE32 hmod
,LPCSTR type
,LPCSTR name
,ENUMRESLANGPROC32A func
, LONG lParam
)
414 DECL_THUNK( thunk
, func
, CallTo32_5
);
415 return EnumResourceLanguages32A( hmod
,type
,name
,(ENUMRESLANGPROC32A
)&thunk
, lParam
);
418 /***********************************************************************
419 * THUNK_EnumResourceNames32A (KERNEL32.88)
421 BOOL32
THUNK_EnumResourceNames32A( HMODULE32 hmod
, LPCSTR type
,
422 ENUMRESNAMEPROC32A func
, LONG lParam
)
424 DECL_THUNK( thunk
, func
, CallTo32_4
);
425 return EnumResourceNames32A( hmod
,type
,(ENUMRESNAMEPROC32A
)&thunk
,lParam
);
428 /***********************************************************************
429 * THUNK_EnumResourceNames32W (KERNEL32.89)
431 BOOL32
THUNK_EnumResourceNames32W( HMODULE32 hmod
, LPCWSTR type
,
432 ENUMRESNAMEPROC32W func
, LONG lParam
)
434 DECL_THUNK( thunk
, func
, CallTo32_4
);
435 return EnumResourceNames32W( hmod
,type
,(ENUMRESNAMEPROC32W
)&thunk
, lParam
);
438 /***********************************************************************
439 * THUNK_EnumResourceTypes32A (KERNEL32.90)
441 BOOL32
THUNK_EnumResourceTypes32A( HMODULE32 hmod
,ENUMRESTYPEPROC32A func
, LONG lParam
)
443 DECL_THUNK( thunk
, func
, CallTo32_3
);
444 return EnumResourceTypes32A( hmod
,(ENUMRESTYPEPROC32A
)&thunk
, lParam
);
447 /***********************************************************************
448 * THUNK_EnumResourceTypes32W (KERNEL32.91)
450 BOOL32
THUNK_EnumResourceTypes32W( HMODULE32 hmod
,ENUMRESTYPEPROC32W func
, LONG lParam
)
452 DECL_THUNK( thunk
, func
, CallTo32_3
);
453 return EnumResourceTypes32W( hmod
,(ENUMRESTYPEPROC32W
)&thunk
, lParam
);
457 /***********************************************************************
458 * THUNK_GrayString16 (USER.185)
460 BOOL16
THUNK_GrayString16( HDC16 hdc
, HBRUSH16 hbr
, GRAYSTRINGPROC16 func
,
461 LPARAM lParam
, INT16 cch
, INT16 x
, INT16 y
,
464 DECL_THUNK( thunk
, func
, CallTo16_word_wlw
);
466 return GrayString16( hdc
, hbr
, NULL
, lParam
, cch
, x
, y
, cx
, cy
);
468 return GrayString16( hdc
, hbr
, (GRAYSTRINGPROC16
)&thunk
, lParam
, cch
,
473 /***********************************************************************
474 * THUNK_GrayString32A (USER32.314)
476 BOOL32
THUNK_GrayString32A( HDC32 hdc
, HBRUSH32 hbr
, GRAYSTRINGPROC32 func
,
477 LPARAM lParam
, INT32 cch
, INT32 x
, INT32 y
,
480 DECL_THUNK( thunk
, func
, CallTo32_3
);
482 return GrayString32A( hdc
, hbr
, NULL
, lParam
, cch
, x
, y
, cx
, cy
);
484 return GrayString32A( hdc
, hbr
, (GRAYSTRINGPROC32
)&thunk
, lParam
, cch
,
489 /***********************************************************************
490 * THUNK_GrayString32W (USER32.315)
492 BOOL32
THUNK_GrayString32W( HDC32 hdc
, HBRUSH32 hbr
, GRAYSTRINGPROC32 func
,
493 LPARAM lParam
, INT32 cch
, INT32 x
, INT32 y
,
496 DECL_THUNK( thunk
, func
, CallTo32_3
);
498 return GrayString32W( hdc
, hbr
, NULL
, lParam
, cch
, x
, y
, cx
, cy
);
500 return GrayString32W( hdc
, hbr
, (GRAYSTRINGPROC32
)&thunk
, lParam
, cch
,
505 /***********************************************************************
506 * THUNK_SetWindowsHook16 (USER.121)
508 FARPROC16
THUNK_SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
510 HINSTANCE16 hInst
= FarGetOwner( HIWORD(proc
) );
511 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
512 THUNK
*thunk
= THUNK_Alloc( (FARPROC16
)proc
, (RELAY
)CallTo16_long_wwl
);
513 if (!thunk
) return 0;
514 return (FARPROC16
)SetWindowsHookEx16( id
, (HOOKPROC16
)thunk
, hInst
, hTask
);
518 /***********************************************************************
519 * THUNK_UnhookWindowsHook16 (USER.234)
521 BOOL16
THUNK_UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
524 THUNK
*thunk
= THUNK_Find( (FARPROC16
)proc
);
525 if (!thunk
) return FALSE
;
526 ret
= UnhookWindowsHook16( id
, (HOOKPROC16
)thunk
);
532 /***********************************************************************
533 * THUNK_SetWindowsHookEx16 (USER.291)
535 HHOOK
THUNK_SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
538 THUNK
*thunk
= THUNK_Alloc( (FARPROC16
)proc
, (RELAY
)CallTo16_long_wwl
);
539 if (!thunk
) return 0;
540 return SetWindowsHookEx16( id
, (HOOKPROC16
)thunk
, hInst
, hTask
);
544 /***********************************************************************
545 * THUNK_UnhookWindowHookEx16 (USER.292)
547 BOOL16
THUNK_UnhookWindowsHookEx16( HHOOK hhook
)
549 THUNK
*thunk
= (THUNK
*)HOOK_GetProc16( hhook
);
550 BOOL16 ret
= UnhookWindowsHookEx16( hhook
);
551 if (thunk
) THUNK_Free( thunk
);
556 /*************************************************************
557 * THUNK_SetUnhandledExceptionFilter (KERNEL32.516)
559 LPTOP_LEVEL_EXCEPTION_FILTER
THUNK_SetUnhandledExceptionFilter(
560 LPTOP_LEVEL_EXCEPTION_FILTER filter
)
562 LPTOP_LEVEL_EXCEPTION_FILTER old
;
563 THUNK
*thunk
= THUNK_Alloc( (FARPROC16
)filter
, (RELAY
)CallTo32_1
);
564 if (!thunk
) return NULL
;
565 old
= SetUnhandledExceptionFilter( (LPTOP_LEVEL_EXCEPTION_FILTER
)thunk
);
566 if (!old
) return NULL
;
567 thunk
= (THUNK
*)old
;
568 old
= (LPTOP_LEVEL_EXCEPTION_FILTER
)thunk
->proc
;
574 static FARPROC16 defDCHookProc
= NULL
;
576 /***********************************************************************
577 * THUNK_SetDCHook (GDI.190)
579 BOOL16
THUNK_SetDCHook( HDC16 hdc
, FARPROC16 proc
, DWORD dwHookData
)
581 THUNK
*thunk
, *oldThunk
;
583 if (!defDCHookProc
) /* Get DCHook Win16 entry point */
584 defDCHookProc
= MODULE_GetEntryPoint( GetModuleHandle16("USER"), 362 );
586 if (proc
!= defDCHookProc
)
588 thunk
= THUNK_Alloc( proc
, (RELAY
)CallTo16_word_wwll
);
589 if (!thunk
) return FALSE
;
591 else thunk
= (THUNK
*)DCHook
;
593 /* Free the previous thunk */
594 GetDCHook( hdc
, (FARPROC16
*)&oldThunk
);
595 if (oldThunk
&& (oldThunk
!= (THUNK
*)DCHook
)) THUNK_Free( oldThunk
);
597 return SetDCHook( hdc
, (FARPROC16
)thunk
, dwHookData
);
601 /***********************************************************************
602 * THUNK_GetDCHook (GDI.191)
604 DWORD
THUNK_GetDCHook( HDC16 hdc
, FARPROC16
*phookProc
)
607 DWORD ret
= GetDCHook( hdc
, (FARPROC16
*)&thunk
);
610 if (thunk
== (THUNK
*)DCHook
)
612 if (!defDCHookProc
) /* Get DCHook Win16 entry point */
613 defDCHookProc
= MODULE_GetEntryPoint(GetModuleHandle16("USER"),
615 *phookProc
= defDCHookProc
;
617 else *phookProc
= thunk
->proc
;
630 UINT32
ThunkConnect32( struct thunkstruct
*ths
, LPSTR thunkfun16
,
631 LPSTR module16
, LPSTR module32
, HMODULE32 hmod32
,
636 fprintf(stdnimp
,"ThunkConnect32(<struct>,%s,%s,%s,%x,%lx)\n",
637 thunkfun16
,module32
,module16
,hmod32
,dllinitarg1
639 fprintf(stdnimp
," magic = %c%c%c%c\n",
645 fprintf(stdnimp
," x1 = %lx\n",ths
->x1
);
646 fprintf(stdnimp
," x2 = %lx\n",ths
->x2
);
647 hmm
=LoadModule16(module16
,NULL
);