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 );
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);