Module: wine Branch: master Commit: c9d1a1906e9342a707a63d73b4afffcc0577ed11 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c9d1a1906e9342a707a63d73b4...
Author: Dan Kegel dank@kegel.com Date: Wed Apr 24 08:15:56 2013 -0700
user32: Add assembly wrapper for calling hook procedures.
---
dlls/user32/hook.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index c9e9e20..633704b 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -202,6 +202,48 @@ static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, return handle; }
+#ifdef __i386__ +/* Some apps pass a non-stdcall proc to SetWindowsHookExA, + * so we need a small assembly wrapper to call the proc. + */ +extern LRESULT HOOKPROC_wrapper( HOOKPROC proc, + INT code, WPARAM wParam, LPARAM lParam ); +__ASM_GLOBAL_FUNC( HOOKPROC_wrapper, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp,%ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "pushl %edi\n\t" + __ASM_CFI(".cfi_rel_offset %edi,-4\n\t") + "pushl %esi\n\t" + __ASM_CFI(".cfi_rel_offset %esi,-8\n\t") + "pushl %ebx\n\t" + __ASM_CFI(".cfi_rel_offset %ebx,-12\n\t") + "pushl 20(%ebp)\n\t" + "pushl 16(%ebp)\n\t" + "pushl 12(%ebp)\n\t" + "movl 8(%ebp),%eax\n\t" + "call *%eax\n\t" + "leal -12(%ebp),%esp\n\t" + "popl %ebx\n\t" + __ASM_CFI(".cfi_same_value %ebx\n\t") + "popl %esi\n\t" + __ASM_CFI(".cfi_same_value %esi\n\t") + "popl %edi\n\t" + __ASM_CFI(".cfi_same_value %edi\n\t") + "leave\n\t" + __ASM_CFI(".cfi_def_cfa %esp,4\n\t") + __ASM_CFI(".cfi_same_value %ebp\n\t") + "ret" ) +#else +static inline LRESULT HOOKPROC_wrapper( HOOKPROC proc, + INT code, WPARAM wParam, LPARAM lParam ) +{ + return proc( code, wParam, lParam ); +} +#endif /* __i386__ */ +
/*********************************************************************** * call_hook_AtoW @@ -210,7 +252,8 @@ static LRESULT call_hook_AtoW( HOOKPROC proc, INT id, INT code, WPARAM wparam, L { LRESULT ret; UNICODE_STRING usBuffer; - if (id != WH_CBT || code != HCBT_CREATEWND) ret = proc( code, wparam, lparam ); + if (id != WH_CBT || code != HCBT_CREATEWND) + ret = HOOKPROC_wrapper( proc, code, wparam, lparam ); else { CBT_CREATEWNDA *cbtcwA = (CBT_CREATEWNDA *)lparam; @@ -233,7 +276,7 @@ static LRESULT call_hook_AtoW( HOOKPROC proc, INT id, INT code, WPARAM wparam, L RtlCreateUnicodeStringFromAsciiz(&usBuffer,cbtcwA->lpcs->lpszClass); csW.lpszClass = classW = usBuffer.Buffer; } - ret = proc( code, wparam, (LPARAM)&cbtcwW ); + ret = HOOKPROC_wrapper( proc, code, wparam, (LPARAM)&cbtcwW ); cbtcwA->hwndInsertAfter = cbtcwW.hwndInsertAfter; HeapFree( GetProcessHeap(), 0, nameW ); HeapFree( GetProcessHeap(), 0, classW ); @@ -249,7 +292,8 @@ static LRESULT call_hook_WtoA( HOOKPROC proc, INT id, INT code, WPARAM wparam, L { LRESULT ret;
- if (id != WH_CBT || code != HCBT_CREATEWND) ret = proc( code, wparam, lparam ); + if (id != WH_CBT || code != HCBT_CREATEWND) + ret = HOOKPROC_wrapper( proc, code, wparam, lparam ); else { CBT_CREATEWNDW *cbtcwW = (CBT_CREATEWNDW *)lparam; @@ -277,7 +321,7 @@ static LRESULT call_hook_WtoA( HOOKPROC proc, INT id, INT code, WPARAM wparam, L csA.lpszClass = classA; }
- ret = proc( code, wparam, (LPARAM)&cbtcwA ); + ret = HOOKPROC_wrapper( proc, code, wparam, (LPARAM)&cbtcwA ); cbtcwW->hwndInsertAfter = cbtcwA.hwndInsertAfter; HeapFree( GetProcessHeap(), 0, nameA ); HeapFree( GetProcessHeap(), 0, classA );