4 * Copyright 1996 Alexandre Julliard
15 typedef void (*RELAY
)();
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
;
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 /***********************************************************************
42 static THUNK
*THUNK_Alloc( FARPROC32 func
, RELAY relay
)
44 THUNK
*thunk
= HeapAlloc( SystemHeap
, 0, sizeof(*thunk
) );
47 thunk
->popl_eax
= 0x58;
48 thunk
->pushl_func
= 0x68;
50 thunk
->pushl_eax
= 0x50;
52 thunk
->relay
= (RELAY
)((char *)relay
- (char *)(&thunk
->next
));
53 thunk
->next
= firstThunk
;
60 /***********************************************************************
63 static THUNK
*THUNK_Find( FARPROC32 func
)
65 THUNK
*thunk
= firstThunk
;
66 while (thunk
&& (thunk
->proc
!= func
)) thunk
= thunk
->next
;
71 /***********************************************************************
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
;
83 HeapFree( SystemHeap
, 0, thunk
);
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
,
193 DECL_THUNK( thunk
, func
, CallTo16_word_llwl
);
194 return EnumFontFamiliesEx16( hdc
, lpLF
, (FONTENUMPROCEX16
)&thunk
,
199 /*************************************************************************
200 * THUNK_EnumFontFamiliesEx32A (GDI32.81)
202 INT32
THUNK_EnumFontFamiliesEx32A( HDC32 hdc
, LPLOGFONT32A lpLF
,
203 FONTENUMPROCEX32A func
, LPARAM lParam
,
206 DECL_THUNK( thunk
, func
, CallTo32_4
);
207 return EnumFontFamiliesEx32A( hdc
, lpLF
, (FONTENUMPROCEX32A
)&thunk
,
212 /*************************************************************************
213 * THUNK_EnumFontFamiliesEx32W (GDI32.82)
215 INT32
THUNK_EnumFontFamiliesEx32W( HDC32 hdc
, LPLOGFONT32W lpLF
,
216 FONTENUMPROCEX32W func
, LPARAM lParam
,
219 DECL_THUNK( thunk
, func
, CallTo32_4
);
220 return EnumFontFamiliesEx32W( hdc
, lpLF
, (FONTENUMPROCEX32W
)&thunk
,
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
,
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
,
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
,
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
,
407 DECL_THUNK( thunk
, func
, CallTo16_word_wlw
);
409 return GrayString( hdc
, hbr
, NULL
, lParam
, cch
, x
, y
, cx
, cy
);
411 return GrayString( hdc
, hbr
, (GRAYSTRINGPROC16
)&thunk
, lParam
, cch
,
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
)
435 THUNK
*thunk
= THUNK_Find( (FARPROC16
)proc
);
436 if (!thunk
) return FALSE
;
437 ret
= UnhookWindowsHook16( id
, (HOOKPROC16
)thunk
);
443 /***********************************************************************
444 * THUNK_SetWindowsHookEx16 (USER.291)
446 HHOOK
THUNK_SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
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
);
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
)
500 DWORD ret
= GetDCHook( hdc
, (FARPROC16
*)&thunk
);
503 if (thunk
== (THUNK
*)DCHook
)
505 if (!defDCHookProc
) /* Get DCHook Win16 entry point */
506 defDCHookProc
= MODULE_GetEntryPoint( GetModuleHandle("USER"),
508 *phookProc
= defDCHookProc
;
510 else *phookProc
= thunk
->proc
;
523 UINT32
ThunkConnect32( struct thunkstruct
*ths
, LPSTR thunkfun16
,
524 LPSTR module16
, LPSTR module32
, HMODULE32 hmod32
,
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",
538 fprintf(stdnimp
," x1 = %lx\n",ths
->x1
);
539 fprintf(stdnimp
," x2 = %lx\n",ths
->x2
);
540 hmm
=LoadModule(module16
,NULL
);