From 37fe8c8eff9f65bc5d3f706b09145e4e01ff4419 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 14 Nov 2011 15:20:48 +0000 Subject: [PATCH] [Win32k|User32] - Fix broadcast message, pass all wine tests. Code consolidation next round. svn path=/trunk/; revision=54376 --- reactos/dll/win32/user32/windows/message.c | 19 +- .../subsystems/win32/win32k/ntuser/message.c | 311 +++++++++++++++--- 2 files changed, 280 insertions(+), 50 deletions(-) diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index e590dcdee51..fdfb2738132 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -2728,7 +2728,7 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength) if (pci->CallbackWnd.hWnd == UMMsg.hwnd) pWnd = pci->CallbackWnd.pWnd; - + CallbackArgs->Result = IntCallWindowProcW( CallbackArgs->IsAnsiProc, CallbackArgs->Proc, pWnd, @@ -3059,16 +3059,13 @@ IntBroadcastSystemMessage( if (dwflags & BSF_LUID) parm.luid = pBSMInfo->luid; - if (*lpdwRecipients & BSM_APPLICATIONS) - { - ret = NtUserMessageCall(GetDesktopWindow(), - uiMessage, - wParam, - lParam, - (ULONG_PTR)&parm, - FNID_BROADCASTSYSTEMMESSAGE, - Ansi); - } + ret = NtUserMessageCall(GetDesktopWindow(), + uiMessage, + wParam, + lParam, + (ULONG_PTR)&parm, + FNID_BROADCASTSYSTEMMESSAGE, + Ansi); if (!ret) { diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index c47c3085d0d..1b58d8ea135 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -2066,7 +2066,7 @@ NtUserMessageCall( HWND hWnd, break; case FNID_BROADCASTSYSTEMMESSAGE: { - BROADCASTPARM parm; + BROADCASTPARM parm, *retparam; DWORD_PTR RetVal = 0; if (ResultInfo) @@ -2086,53 +2086,286 @@ NtUserMessageCall( HWND hWnd, break; if ( parm.recipients & BSM_ALLDESKTOPS || - parm.recipients == BSM_ALLCOMPONENTS ) + parm.recipients == BSM_ALLCOMPONENTS ) { + PLIST_ENTRY DesktopEntry; + PDESKTOP rpdesk; + HWND *List, hwndDenied = NULL; + HDESK hDesk = NULL; + PWND pwnd, pwndDesk; + ULONG i; + UINT fuFlags; + + for (DesktopEntry = InputWindowStation->DesktopListHead.Flink; + DesktopEntry != &InputWindowStation->DesktopListHead; + DesktopEntry = DesktopEntry->Flink) + { + rpdesk = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry); + pwndDesk = rpdesk->pDeskInfo->spwnd; + List = IntWinListChildren(pwndDesk); + + if (parm.flags & BSF_QUERY) + { + if (List != NULL) + { + if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG) + { + fuFlags = SMTO_ABORTIFHUNG; + } + else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG) + { + fuFlags = SMTO_NOTIMEOUTIFNOTHUNG; + } + else + { + fuFlags = SMTO_NORMAL; + } + co_IntSendMessageTimeout( UserHMGetHandle(pwndDesk), + Msg, + wParam, + lParam, + fuFlags, + 2000, + &RetVal); + Ret = TRUE; + for (i = 0; List[i]; i++) + { + pwnd = UserGetWindowObject(List[i]); + if (!pwnd) continue; + + if ( pwnd->fnid == FNID_MENU || + pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] ) + continue; + + if ( parm.flags & BSF_IGNORECURRENTTASK ) + { + if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + continue; + } + co_IntSendMessageTimeout( List[i], + Msg, + wParam, + lParam, + fuFlags, + 2000, + &RetVal); + + if (!RetVal && EngGetLastError() == ERROR_TIMEOUT) + { + if (!(parm.flags & BSF_FORCEIFHUNG)) + Ret = FALSE; + } + if (RetVal == BROADCAST_QUERY_DENY) + { + hwndDenied = List[i]; + hDesk = UserHMGetHandle(pwndDesk); + Ret = FALSE; + } + } + ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + _SEH2_TRY + { + retparam = (PBROADCASTPARM) ResultInfo; + retparam->hDesk = hDesk; + retparam->hWnd = hwndDenied; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(break); + } + _SEH2_END; + if (!Ret) break; // Have a hit! Let everyone know! + } + } + else if (parm.flags & BSF_POSTMESSAGE) + { + if (List != NULL) + { + UserPostMessage(UserHMGetHandle(pwndDesk), Msg, wParam, lParam); + + for (i = 0; List[i]; i++) + { + pwnd = UserGetWindowObject(List[i]); + if (!pwnd) continue; + + if ( pwnd->fnid == FNID_MENU || + pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] ) + continue; + + if ( parm.flags & BSF_IGNORECURRENTTASK ) + { + if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + continue; + } + UserPostMessage(List[i], Msg, wParam, lParam); + } + ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + } + Ret = TRUE; + } + else + { + if (List != NULL) + { + UserSendNotifyMessage(UserHMGetHandle(pwndDesk), Msg, wParam, lParam); + + for (i = 0; List[i]; i++) + { + pwnd = UserGetWindowObject(List[i]); + if (!pwnd) continue; + + if ( pwnd->fnid == FNID_MENU || + pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] ) + continue; + + if ( parm.flags & BSF_IGNORECURRENTTASK ) + { + if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + continue; + } + UserSendNotifyMessage(List[i], Msg, wParam, lParam); + } + ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + } + Ret = TRUE; + } + } } else if (parm.recipients & BSM_APPLICATIONS) { - if (parm.flags & BSF_QUERY) - { - if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG) - { - co_IntSendMessageTimeout( HWND_BROADCAST, + HWND *List, hwndDenied = NULL; + HDESK hDesk = NULL; + PWND pwnd, pwndDesk; + ULONG i; + UINT fuFlags; + + pwndDesk = UserGetWindowObject(IntGetDesktopWindow()); + List = IntWinListChildren(pwndDesk); + + if (parm.flags & BSF_QUERY) + { + if (List != NULL) + { + if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG) + { + fuFlags = SMTO_ABORTIFHUNG; + } + else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG) + { + fuFlags = SMTO_NOTIMEOUTIFNOTHUNG; + } + else + { + fuFlags = SMTO_NORMAL; + } + co_IntSendMessageTimeout( UserHMGetHandle(pwndDesk), + Msg, + wParam, + lParam, + fuFlags, + 2000, + &RetVal); + Ret = TRUE; + for (i = 0; List[i]; i++) + { + pwnd = UserGetWindowObject(List[i]); + if (!pwnd) continue; + + if ( pwnd->fnid == FNID_MENU || + pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] ) + continue; + + if ( parm.flags & BSF_IGNORECURRENTTASK ) + { + if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + continue; + } + co_IntSendMessageTimeout( List[i], Msg, wParam, lParam, - SMTO_ABORTIFHUNG, + fuFlags, 2000, &RetVal); - } - else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG) - { - co_IntSendMessageTimeout( HWND_BROADCAST, - Msg, - wParam, - lParam, - SMTO_NOTIMEOUTIFNOTHUNG, - 2000, - &RetVal); - } - else - { - co_IntSendMessageTimeout( HWND_BROADCAST, - Msg, - wParam, - lParam, - SMTO_NORMAL, - 2000, - &RetVal); - } - Ret = RetVal; - } - else if (parm.flags & BSF_POSTMESSAGE) - { - Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam); - } - else //Everything else,,,, if ( parm.flags & BSF_SENDNOTIFYMESSAGE) - { - Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam); - } + + if (!RetVal && EngGetLastError() == ERROR_TIMEOUT) + { + if (!(parm.flags & BSF_FORCEIFHUNG)) + Ret = FALSE; + } + if (RetVal == BROADCAST_QUERY_DENY) + { + hwndDenied = List[i]; + hDesk = UserHMGetHandle(pwndDesk); + Ret = FALSE; + } + } + ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + _SEH2_TRY + { + retparam = (PBROADCASTPARM) ResultInfo; + retparam->hDesk = hDesk; + retparam->hWnd = hwndDenied; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(break); + } + _SEH2_END; + } + } + else if (parm.flags & BSF_POSTMESSAGE) + { + if (List != NULL) + { + UserPostMessage(UserHMGetHandle(pwndDesk), Msg, wParam, lParam); + + for (i = 0; List[i]; i++) + { + pwnd = UserGetWindowObject(List[i]); + if (!pwnd) continue; + + if ( pwnd->fnid == FNID_MENU || + pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] ) + continue; + + if ( parm.flags & BSF_IGNORECURRENTTASK ) + { + if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + continue; + } + UserPostMessage(List[i], Msg, wParam, lParam); + } + ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + } + Ret = TRUE; + } + else + { + if (List != NULL) + { + UserSendNotifyMessage(UserHMGetHandle(pwndDesk), Msg, wParam, lParam); + + for (i = 0; List[i]; i++) + { + pwnd = UserGetWindowObject(List[i]); + if (!pwnd) continue; + + if ( pwnd->fnid == FNID_MENU || + pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] ) + continue; + + if ( parm.flags & BSF_IGNORECURRENTTASK ) + { + if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + continue; + } + UserSendNotifyMessage(List[i], Msg, wParam, lParam); + } + ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + } + Ret = TRUE; + } } } break;