diff --git a/reactos/win32ss/user/user32/CMakeLists.txt b/reactos/win32ss/user/user32/CMakeLists.txt index e9038361c33..4d0fe258f2d 100644 --- a/reactos/win32ss/user/user32/CMakeLists.txt +++ b/reactos/win32ss/user/user32/CMakeLists.txt @@ -64,8 +64,16 @@ list(APPEND SOURCE ${CMAKE_CURRENT_BINARY_DIR}/user32_stubs.c include/user32.h) +if(ARCH STREQUAL "i386") + list(APPEND ASM_SOURCE + windows/wndproc_fixup.S) +endif() + +add_asm_files(user32_asm ${ASM_SOURCE}) + add_library(user32 SHARED ${SOURCE} + ${user32_asm} user32.rc ${CMAKE_CURRENT_BINARY_DIR}/user32.def) diff --git a/reactos/win32ss/user/user32/windows/message.c b/reactos/win32ss/user/user32/windows/message.c index e84d7533cbf..02e5e90fe0c 100644 --- a/reactos/win32ss/user/user32/windows/message.c +++ b/reactos/win32ss/user/user32/windows/message.c @@ -13,6 +13,22 @@ #include WINE_DEFAULT_DEBUG_CHANNEL(user32); + +#ifdef __i386__ +/* For bad applications which provide bad (non stdcall) WndProc */ +extern +__cdecl +LRESULT +CALL_EXTERN_WNDPROC( + WNDPROC WndProc, + HWND hWnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam); +#else +# define CALL_EXTERN_WNDPROC(proc, h, m, w, l) proc(h, m, w, l) +#endif + /* From wine: */ /* flag for messages that contain pointers */ /* 32 messages per entry, messages 0..31 map to bits 0..31 */ @@ -1448,15 +1464,7 @@ IntCallWindowProcW(BOOL IsAnsiProc, if (PreResult) goto Exit; - _SEH2_TRY // wine does this. - { - Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - ERR("Exception when calling Ansi WndProc %p Msg %d pti %p Wndpti %p\n",WndProc,Msg,GetW32ThreadInfo(),pWnd->head.pti); - } - _SEH2_END; + Result = CALL_EXTERN_WNDPROC(WndProc, AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam); if (Hook && MsgOverride) { @@ -1497,15 +1505,7 @@ IntCallWindowProcW(BOOL IsAnsiProc, if (PreResult) goto Exit; - _SEH2_TRY - { - Result = WndProc(hWnd, Msg, wParam, lParam); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - ERR("Exception when calling unicode WndProc %p Msg %d pti %p Wndpti %p\n",WndProc, Msg,GetW32ThreadInfo(),pWnd->head.pti); - } - _SEH2_END; + Result = CALL_EXTERN_WNDPROC(WndProc, hWnd, Msg, wParam, lParam); if (Hook && MsgOverride) { @@ -1585,15 +1585,7 @@ IntCallWindowProcA(BOOL IsAnsiProc, if (PreResult) goto Exit; - _SEH2_TRY - { - Result = WndProc(hWnd, Msg, wParam, lParam); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - ERR("Exception when calling Ansi WndProc %p Msg %d pti %p Wndpti %p\n",WndProc,Msg,GetW32ThreadInfo(),pWnd->head.pti); - } - _SEH2_END; + Result = CALL_EXTERN_WNDPROC(WndProc, hWnd, Msg, wParam, lParam); if (Hook && MsgOverride) { @@ -1641,16 +1633,7 @@ IntCallWindowProcA(BOOL IsAnsiProc, if (PreResult) goto Exit; - _SEH2_TRY - { - Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message, - UnicodeMsg.wParam, UnicodeMsg.lParam); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - ERR("Exception when calling unicode WndProc %p Msg %d pti %p Wndpti %p\n",WndProc, Msg,GetW32ThreadInfo(),pWnd->head.pti); - } - _SEH2_END; + Result = CALL_EXTERN_WNDPROC(WndProc, UnicodeMsg.hwnd, UnicodeMsg.message, UnicodeMsg.wParam, UnicodeMsg.lParam); if (Hook && MsgOverride) { diff --git a/reactos/win32ss/user/user32/windows/wndproc_fixup.S b/reactos/win32ss/user/user32/windows/wndproc_fixup.S new file mode 100644 index 00000000000..ff6bf39fcb4 --- /dev/null +++ b/reactos/win32ss/user/user32/windows/wndproc_fixup.S @@ -0,0 +1,56 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS user32.dll + * FILE: win32ss/user/user32/windows/wndproc_fixup.S + * PURPOSE: Messages + * PROGRAMMER: Jérôme Gardou jerome.gardou@reactos.org + * LICENCE : LGPL, copyright Alexandre Julliard + */ + +#include +#include + +/* Some applications provide invalid callbacks which don't follow the stdcall convention */ + +.code + +/* + * __cdecl + * LRESULT + * CALL_EXTERN_WNDPROC( + * WNDPROC WndProc, + * HWND hWnd, + * UINT Msg, + * WPARAM wParam, + * LPARAM lParam); + */ +PUBLIC _CALL_EXTERN_WNDPROC +FUNC _CALL_EXTERN_WNDPROC + FPO 0, 0, 0, 0, 0, FRAME_FPO + + push ebp + mov ebp, esp + + push edi + push esi + push ebp + + sub esp, 12 + + push dword ptr [ebp + 24] + push dword ptr [ebp + 20] + push dword ptr [ebp + 16] + push dword ptr [ebp + 12] + mov eax, dword ptr [ebp + 8] + + call eax + + lea esp, dword ptr [ebp - 12] + pop ebx + pop esi + pop edi + + leave + ret + +ENDFUNC