diff --git a/dlls/user/message.c b/dlls/user/message.c index 76968fffb4..55270a525a 100644 --- a/dlls/user/message.c +++ b/dlls/user/message.c @@ -1339,10 +1339,18 @@ static BOOL unpack_dde_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM */ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL unicode ) { - LRESULT result; + LRESULT result = 0; WNDPROC winproc; + MESSAGEQUEUE *queue = QUEUE_Current(); - if (msg & 0x80000000) return handle_internal_message( hwnd, msg, wparam, lparam ); + if (queue->recursion_count > MAX_SENDMSG_RECURSION) return 0; + queue->recursion_count++; + + if (msg & 0x80000000) + { + result = handle_internal_message( hwnd, msg, wparam, lparam ); + goto done; + } /* first the WH_CALLWNDPROC hook */ if (HOOK_IsHooked( WH_CALLWNDPROC )) @@ -1363,12 +1371,12 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar /* now call the window procedure */ if (unicode) { - if (!(winproc = (WNDPROC)GetWindowLongW( hwnd, GWL_WNDPROC ))) return 0; + if (!(winproc = (WNDPROC)GetWindowLongW( hwnd, GWL_WNDPROC ))) goto done; result = CallWindowProcW( winproc, hwnd, msg, wparam, lparam ); } else { - if (!(winproc = (WNDPROC)GetWindowLongA( hwnd, GWL_WNDPROC ))) return 0; + if (!(winproc = (WNDPROC)GetWindowLongA( hwnd, GWL_WNDPROC ))) goto done; result = CallWindowProcA( winproc, hwnd, msg, wparam, lparam ); } @@ -1384,6 +1392,8 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar if (unicode) HOOK_CallHooksW( WH_CALLWNDPROCRET, HC_ACTION, 1, (LPARAM)&cwp ); else HOOK_CallHooksA( WH_CALLWNDPROCRET, HC_ACTION, 1, (LPARAM)&cwp ); } + done: + queue->recursion_count--; return result; } diff --git a/include/queue.h b/include/queue.h index 76b0089782..591146e506 100644 --- a/include/queue.h +++ b/include/queue.h @@ -53,6 +53,7 @@ typedef struct tagMESSAGEQUEUE HQUEUE16 self; /* Handle to self (was: reserved) */ TEB* teb; /* Thread owning queue */ HANDLE server_queue; /* Handle to server-side queue */ + DWORD recursion_count; /* Counter to prevent infinite SendMessage recursion */ struct received_message_info *receive_info; /* Info about message being currently received */ DWORD magic; /* magic number should be QUEUE_MAGIC */ @@ -73,7 +74,8 @@ typedef struct tagMESSAGEQUEUE } MESSAGEQUEUE; -#define QUEUE_MAGIC 0xD46E80AF +#define QUEUE_MAGIC 0xD46E80AF +#define MAX_SENDMSG_RECURSION 64 /* Per queue data management methods */ HWND PERQDATA_GetFocusWnd( PERQUEUEDATA *pQData );