- Add support for SMTO_NOTIMEOUTIFNOTHUNG.

- Fix WH_CALLWNDPROC/RET for multi thread.
- Fix foreground idle.

svn path=/trunk/; revision=34776
This commit is contained in:
James Tabor 2008-07-25 12:31:59 +00:00
parent 9f5f04ab20
commit f123580aa0
2 changed files with 65 additions and 35 deletions

View file

@ -1390,7 +1390,6 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
BOOL SameThread = FALSE; BOOL SameThread = FALSE;
/* FIXME: Call hooks. */
if (!(Window = UserGetWindowObject(hWnd))) if (!(Window = UserGetWindowObject(hWnd)))
{ {
RETURN( FALSE); RETURN( FALSE);
@ -1399,9 +1398,23 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
UserRefObjectCo(Window, &Ref); UserRefObjectCo(Window, &Ref);
Win32Thread = PsGetCurrentThreadWin32Thread(); Win32Thread = PsGetCurrentThreadWin32Thread();
if (Window->ti == Win32Thread->ThreadInfo)
SameThread = TRUE;
if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
(SameThread && ISITHOOKED(WH_CALLWNDPROC)) )
{
CWPSTRUCT CWP;
CWP.hwnd = hWnd;
CWP.message = Msg;
CWP.wParam = wParam;
CWP.lParam = lParam;
co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
}
if (NULL != Win32Thread && if (NULL != Win32Thread &&
Window->MessageQueue == Win32Thread->MessageQueue) Window->MessageQueue == Win32Thread->MessageQueue)
{ {
if (Win32Thread->IsExiting) if (Win32Thread->IsExiting)
{ {
@ -1422,24 +1435,10 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam))) if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam)))
{ {
DPRINT1("Failed to pack message parameters\n"); DPRINT1("Failed to pack message parameters\n");
RETURN( FALSE); RETURN( FALSE);
} }
if (Window->ti == Win32Thread->ThreadInfo)
SameThread = TRUE;
if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
(SameThread && ISITHOOKED(WH_CALLWNDPROC)) )
{
CWPSTRUCT CWP;
CWP.hwnd = hWnd;
CWP.message = Msg;
CWP.wParam = wParam;
CWP.lParam = lParam;
co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
}
Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam, Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
lParamPacked,lParamBufferSize); lParamPacked,lParamBufferSize);
@ -1447,7 +1446,7 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
{ {
*uResult = Result; *uResult = Result;
} }
if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) || if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
(SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) ) (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
{ {
@ -1463,39 +1462,70 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam))) if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam)))
{ {
DPRINT1("Failed to unpack message parameters\n"); DPRINT1("Failed to unpack message parameters\n");
RETURN( TRUE); RETURN( TRUE);
} }
RETURN( TRUE); RETURN( TRUE);
} }
if(uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->MessageQueue)) if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->MessageQueue))
{ {
/* FIXME - Set a LastError? */ /* FIXME - Set a LastError? */
RETURN( FALSE); RETURN( FALSE);
} }
if(Window->Status & WINDOWSTATUS_DESTROYING) if (Window->Status & WINDOWSTATUS_DESTROYING)
{ {
/* FIXME - last error? */ /* FIXME - last error? */
DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd); DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
RETURN( FALSE); RETURN( FALSE);
} }
Status = co_MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam, do
uTimeout, (uFlags & SMTO_BLOCK), FALSE, uResult); {
Status = co_MsqSendMessage( Window->MessageQueue,
hWnd,
Msg,
wParam,
lParam,
uTimeout,
(uFlags & SMTO_BLOCK),
FALSE,
uResult);
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
!MsqIsHung(Window->MessageQueue));
if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
(SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
{
CWPRETSTRUCT CWPR;
CWPR.hwnd = hWnd;
CWPR.message = Msg;
CWPR.wParam = wParam;
CWPR.lParam = lParam;
CWPR.lResult = *uResult;
co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
}
if (STATUS_TIMEOUT == Status) if (STATUS_TIMEOUT == Status)
{ {
/* MSDN says GetLastError() should return 0 after timeout */ /*
SetLastWin32Error(0); MSDN says:
RETURN( FALSE); Microsoft Windows 2000: If GetLastError returns zero, then the function
timed out.
XP+ : If the function fails or times out, the return value is zero.
To get extended error information, call GetLastError. If GetLastError
returns ERROR_TIMEOUT, then the function timed out.
*/
SetLastWin32Error(ERROR_TIMEOUT);
RETURN( FALSE);
} }
else if (! NT_SUCCESS(Status)) else if (! NT_SUCCESS(Status))
{ {
SetLastNtError(Status); SetLastNtError(Status);
RETURN( FALSE); RETURN( FALSE);
} }
RETURN( TRUE); RETURN( TRUE);

View file

@ -78,12 +78,12 @@ IdlePing(VOID)
Window = UserGetWindowObject(hWnd); Window = UserGetWindowObject(hWnd);
if (Window && Window->Wnd && (Window->Wnd->ti == GetW32ThreadInfo())) if (Window && Window->ti)
{ {
if (ISITHOOKED(WH_FOREGROUNDIDLE)) if (Window->ti->Hooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE))
{ {
co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0); co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
} }
} }
if (W32d && W32d->InputIdleEvent) if (W32d && W32d->InputIdleEvent)