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 EnumObjects( hdc
, nObjType
, (GOBJENUMPROC16
)&thunk
, lParam
);
102 /*************************************************************************
103 * THUNK_EnumFonts16 (GDI.70)
105 INT16
THUNK_EnumFonts16( HDC16 hdc
, LPCSTR lpFaceName
,
106 FONTENUMPROC16 func
, LPARAM lParam
)
108 DECL_THUNK( thunk
, func
, CallTo16_word_llwl
);
109 return EnumFonts( hdc
, lpFaceName
, (FONTENUMPROC16
)&thunk
, lParam
);
113 /******************************************************************
114 * THUNK_EnumMetaFile16 (GDI.175)
116 BOOL16
THUNK_EnumMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
,
117 MFENUMPROC16 func
, LPARAM lParam
)
119 DECL_THUNK( thunk
, func
, CallTo16_word_wllwl
);
120 return EnumMetaFile( hdc
, hmf
, (MFENUMPROC16
)&thunk
, lParam
);
124 /*************************************************************************
125 * THUNK_EnumFontFamilies16 (GDI.330)
127 INT16
THUNK_EnumFontFamilies16( HDC16 hdc
, LPCSTR lpszFamily
,
128 FONTENUMPROC16 func
, LPARAM lParam
)
130 DECL_THUNK( thunk
, func
, CallTo16_word_llwl
);
131 return EnumFontFamilies( hdc
, lpszFamily
, (FONTENUMPROC16
)&thunk
, lParam
);
135 /**********************************************************************
136 * THUNK_LineDDA16 (GDI.100)
138 void THUNK_LineDDA16( INT16 nXStart
, INT16 nYStart
, INT16 nXEnd
, INT16 nYEnd
,
139 LINEDDAPROC16 func
, LPARAM lParam
)
141 DECL_THUNK( thunk
, func
, CallTo16_word_wwl
);
142 LineDDA16( nXStart
, nYStart
, nXEnd
, nYEnd
, (LINEDDAPROC16
)&thunk
, lParam
);
146 /**********************************************************************
147 * THUNK_LineDDA32 (GDI32.248)
149 BOOL32
THUNK_LineDDA32( INT32 nXStart
, INT32 nYStart
, INT32 nXEnd
, INT32 nYEnd
,
150 LINEDDAPROC32 func
, LPARAM lParam
)
152 DECL_THUNK( thunk
, func
, CallTo32_3
);
153 return LineDDA32( nXStart
, nYStart
, nXEnd
, nYEnd
,
154 (LINEDDAPROC32
)&thunk
, lParam
);
158 /*******************************************************************
159 * THUNK_EnumWindows16 (USER.54)
161 BOOL16
THUNK_EnumWindows16( WNDENUMPROC16 func
, LPARAM lParam
)
163 DECL_THUNK( thunk
, func
, CallTo16_word_wl
);
164 return EnumWindows16( (WNDENUMPROC16
)&thunk
, lParam
);
168 /*******************************************************************
169 * THUNK_EnumWindows32 (USER32.192)
171 BOOL32
THUNK_EnumWindows32( WNDENUMPROC32 func
, LPARAM lParam
)
173 DECL_THUNK( thunk
, func
, CallTo32_2
);
174 return EnumWindows32( (WNDENUMPROC32
)&thunk
, lParam
);
178 /**********************************************************************
179 * THUNK_EnumChildWindows16 (USER.55)
181 BOOL16
THUNK_EnumChildWindows16( HWND16 parent
, WNDENUMPROC16 func
,
184 DECL_THUNK( thunk
, func
, CallTo16_word_wl
);
185 return EnumChildWindows16( parent
, (WNDENUMPROC16
)&thunk
, lParam
);
189 /**********************************************************************
190 * THUNK_EnumChildWindows32 (USER32.177)
192 BOOL32
THUNK_EnumChildWindows32( HWND32 parent
, WNDENUMPROC32 func
,
195 DECL_THUNK( thunk
, func
, CallTo32_2
);
196 return EnumChildWindows32( parent
, (WNDENUMPROC32
)&thunk
, lParam
);
200 /**********************************************************************
201 * THUNK_EnumTaskWindows16 (USER.225)
203 BOOL16
THUNK_EnumTaskWindows16( HTASK16 hTask
, WNDENUMPROC16 func
,
206 DECL_THUNK( thunk
, func
, CallTo16_word_wl
);
207 return EnumTaskWindows16( hTask
, (WNDENUMPROC16
)&thunk
, lParam
);
211 /**********************************************************************
212 * THUNK_EnumThreadWindows (USER32.189)
214 BOOL32
THUNK_EnumThreadWindows( DWORD id
, WNDENUMPROC32 func
, LPARAM lParam
)
216 DECL_THUNK( thunk
, func
, CallTo32_2
);
217 return EnumThreadWindows( id
, (WNDENUMPROC32
)&thunk
, lParam
);
221 /***********************************************************************
222 * THUNK_EnumProps16 (USER.27)
224 INT16
THUNK_EnumProps16( HWND16 hwnd
, PROPENUMPROC16 func
)
226 DECL_THUNK( thunk
, func
, CallTo16_word_wlw
);
227 return EnumProps16( hwnd
, (PROPENUMPROC16
)&thunk
);
231 /***********************************************************************
232 * THUNK_EnumProps32A (USER32.185)
234 INT32
THUNK_EnumProps32A( HWND32 hwnd
, PROPENUMPROC32A func
)
236 DECL_THUNK( thunk
, func
, CallTo32_3
);
237 return EnumProps32A( hwnd
, (PROPENUMPROC32A
)&thunk
);
241 /***********************************************************************
242 * THUNK_EnumProps32W (USER32.188)
244 INT32
THUNK_EnumProps32W( HWND32 hwnd
, PROPENUMPROC32W func
)
246 DECL_THUNK( thunk
, func
, CallTo32_3
);
247 return EnumProps32W( hwnd
, (PROPENUMPROC32W
)&thunk
);
251 /***********************************************************************
252 * THUNK_EnumPropsEx32A (USER32.186)
254 INT32
THUNK_EnumPropsEx32A( HWND32 hwnd
, PROPENUMPROCEX32A func
, LPARAM lParam
)
256 DECL_THUNK( thunk
, func
, CallTo32_4
);
257 return EnumPropsEx32A( hwnd
, (PROPENUMPROCEX32A
)&thunk
, lParam
);
261 /***********************************************************************
262 * THUNK_EnumPropsEx32W (USER32.187)
264 INT32
THUNK_EnumPropsEx32W( HWND32 hwnd
, PROPENUMPROCEX32W func
, LPARAM lParam
)
266 DECL_THUNK( thunk
, func
, CallTo32_4
);
267 return EnumPropsEx32W( hwnd
, (PROPENUMPROCEX32W
)&thunk
, lParam
);
271 /***********************************************************************
272 * THUNK_GrayString16 (USER.185)
274 BOOL16
THUNK_GrayString16( HDC16 hdc
, HBRUSH16 hbr
, GRAYSTRINGPROC16 func
,
275 LPARAM lParam
, INT16 cch
, INT16 x
, INT16 y
,
278 DECL_THUNK( thunk
, func
, CallTo16_word_wlw
);
280 return GrayString( hdc
, hbr
, NULL
, lParam
, cch
, x
, y
, cx
, cy
);
282 return GrayString( hdc
, hbr
, (GRAYSTRINGPROC16
)&thunk
, lParam
, cch
,
287 /***********************************************************************
288 * THUNK_SetWindowsHook16 (USER.121)
290 FARPROC16
THUNK_SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
292 HINSTANCE16 hInst
= FarGetOwner( HIWORD(proc
) );
293 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
294 THUNK
*thunk
= THUNK_Alloc( (FARPROC16
)proc
, (RELAY
)CallTo16_long_wwl
);
295 if (!thunk
) return 0;
296 return (FARPROC16
)SetWindowsHookEx16( id
, (HOOKPROC16
)thunk
, hInst
, hTask
);
300 /***********************************************************************
301 * THUNK_UnhookWindowsHook16 (USER.234)
303 BOOL16
THUNK_UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
306 THUNK
*thunk
= THUNK_Find( (FARPROC16
)proc
);
307 if (thunk
) ret
= UnhookWindowsHook16( id
, (HOOKPROC16
)thunk
);
312 /***********************************************************************
313 * THUNK_SetWindowsHookEx16 (USER.291)
315 HHOOK
THUNK_SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
318 THUNK
*thunk
= THUNK_Alloc( (FARPROC16
)proc
, (RELAY
)CallTo16_long_wwl
);
319 if (!thunk
) return 0;
320 return SetWindowsHookEx16( id
, (HOOKPROC16
)thunk
, hInst
, hTask
);
324 /***********************************************************************
325 * THUNK_UnhookWindowHookEx16 (USER.292)
327 BOOL16
THUNK_UnhookWindowsHookEx16( HHOOK hhook
)
329 THUNK
*thunk
= (THUNK
*)HOOK_GetProc16( hhook
);
330 BOOL16 ret
= UnhookWindowsHookEx16( hhook
);
331 if (thunk
) THUNK_Free( thunk
);
336 static FARPROC16 defDCHookProc
= NULL
;
338 /***********************************************************************
339 * THUNK_SetDCHook (GDI.190)
341 BOOL16
THUNK_SetDCHook( HDC16 hdc
, FARPROC16 proc
, DWORD dwHookData
)
343 THUNK
*thunk
, *oldThunk
;
345 if (!defDCHookProc
) /* Get DCHook Win16 entry point */
346 defDCHookProc
= MODULE_GetEntryPoint( GetModuleHandle("USER"), 362 );
348 if (proc
!= defDCHookProc
)
350 thunk
= THUNK_Alloc( proc
, (RELAY
)CallTo16_word_wwll
);
351 if (!thunk
) return FALSE
;
353 else thunk
= (THUNK
*)DCHook
;
355 /* Free the previous thunk */
356 GetDCHook( hdc
, (FARPROC16
*)&oldThunk
);
357 if (oldThunk
&& (oldThunk
!= (THUNK
*)DCHook
)) THUNK_Free( oldThunk
);
359 return SetDCHook( hdc
, (FARPROC16
)thunk
, dwHookData
);
363 /***********************************************************************
364 * THUNK_GetDCHook (GDI.191)
366 DWORD
THUNK_GetDCHook( HDC16 hdc
, FARPROC16
*phookProc
)
369 DWORD ret
= GetDCHook( hdc
, (FARPROC16
*)&thunk
);
372 if (thunk
== (THUNK
*)DCHook
)
374 if (!defDCHookProc
) /* Get DCHook Win16 entry point */
375 defDCHookProc
= MODULE_GetEntryPoint( GetModuleHandle("USER"),
377 *phookProc
= defDCHookProc
;
379 else *phookProc
= thunk
->proc
;
392 UINT32
ThunkConnect32( struct thunkstruct
*ths
, LPSTR thunkfun16
,
393 LPSTR module16
, LPSTR module32
, HMODULE32 hmod32
,
398 fprintf(stdnimp
,"ThunkConnect32(<struct>,%s,%s,%s,%x,%lx)\n",
399 thunkfun16
,module32
,module16
,hmod32
,dllinitarg1
401 fprintf(stdnimp
," magic = %c%c%c%c\n",
407 fprintf(stdnimp
," x1 = %lx\n",ths
->x1
);
408 fprintf(stdnimp
," x2 = %lx\n",ths
->x2
);
409 hmm
=LoadModule(module16
,NULL
);