mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 06:02:56 +00:00
[Win32k]
- Fixed WaitForInputIdle, finally!, passed all the wine tests for it. - Moved Get/Peek message to the new all in one support routine. - Foreground hook hits one out of five, this needs more research. - Attempted to workout synchronizing issues with low level and regular hooks. svn path=/trunk/; revision=49579
This commit is contained in:
parent
ea5d462bdf
commit
31efb355c9
3 changed files with 138 additions and 155 deletions
|
@ -103,6 +103,8 @@ Win32kProcessCallback(struct _EPROCESS *Process,
|
||||||
ExInitializeFastMutex(&Win32Process->DriverObjListLock);
|
ExInitializeFastMutex(&Win32Process->DriverObjListLock);
|
||||||
|
|
||||||
Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
|
Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
|
||||||
|
EngCreateEvent((PEVENT *)&Win32Process->InputIdleEvent);
|
||||||
|
KeInitializeEvent(Win32Process->InputIdleEvent, NotificationEvent, FALSE);
|
||||||
|
|
||||||
if(Process->Peb != NULL)
|
if(Process->Peb != NULL)
|
||||||
{
|
{
|
||||||
|
@ -118,6 +120,13 @@ Win32kProcessCallback(struct _EPROCESS *Process,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
||||||
|
Win32Process->W32PF_flags |= W32PF_TERMINATED;
|
||||||
|
if (Win32Process->InputIdleEvent)
|
||||||
|
{
|
||||||
|
EngFreeMem((PVOID)Win32Process->InputIdleEvent);
|
||||||
|
Win32Process->InputIdleEvent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
IntCleanupMenus(Process, Win32Process);
|
IntCleanupMenus(Process, Win32Process);
|
||||||
IntCleanupCurIcons(Process, Win32Process);
|
IntCleanupCurIcons(Process, Win32Process);
|
||||||
CleanupMonitorImpl();
|
CleanupMonitorImpl();
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
|
||||||
|
|
||||||
#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
|
#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -323,6 +325,52 @@ UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL No
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wakeup any thread/process waiting on idle input.
|
||||||
|
//
|
||||||
|
VOID FASTCALL
|
||||||
|
IdlePing(VOID)
|
||||||
|
{
|
||||||
|
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
|
||||||
|
PUSER_MESSAGE_QUEUE ForegroundQueue;
|
||||||
|
PTHREADINFO pti, ptiForeground = NULL;
|
||||||
|
|
||||||
|
ForegroundQueue = IntGetFocusMessageQueue();
|
||||||
|
|
||||||
|
if (ForegroundQueue)
|
||||||
|
ptiForeground = ForegroundQueue->Thread->Tcb.Win32Thread;
|
||||||
|
|
||||||
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
|
if ( pti && pti->pDeskInfo && pti == ptiForeground )
|
||||||
|
{
|
||||||
|
if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
|
||||||
|
pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
|
||||||
|
{
|
||||||
|
co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("IdlePing ppi 0x%x\n",ppi);
|
||||||
|
if ( ppi && ppi->InputIdleEvent )
|
||||||
|
{
|
||||||
|
DPRINT("InputIdleEvent\n");
|
||||||
|
KeSetEvent( ppi->InputIdleEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
IdlePong(VOID)
|
||||||
|
{
|
||||||
|
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
|
||||||
|
|
||||||
|
DPRINT("IdlePong ppi 0x%x\n",ppi);
|
||||||
|
if ( ppi && ppi->InputIdleEvent )
|
||||||
|
{
|
||||||
|
KeClearEvent(ppi->InputIdleEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VOID FASTCALL
|
static VOID FASTCALL
|
||||||
IntCallWndProc( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
IntCallWndProc( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -856,6 +904,8 @@ co_IntPeekMessage( PUSER_MESSAGE Msg,
|
||||||
|
|
||||||
RemoveMessages = RemoveMsg & PM_REMOVE;
|
RemoveMessages = RemoveMsg & PM_REMOVE;
|
||||||
|
|
||||||
|
IdlePong();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
KeQueryTickCount(&LargeTickCount);
|
KeQueryTickCount(&LargeTickCount);
|
||||||
|
@ -944,10 +994,6 @@ co_IntPeekMessage( PUSER_MESSAGE Msg,
|
||||||
}
|
}
|
||||||
while (TRUE);
|
while (TRUE);
|
||||||
|
|
||||||
// The WH_GETMESSAGE hook enables an application to monitor messages about to
|
|
||||||
// be returned by the GetMessage or PeekMessage function.
|
|
||||||
|
|
||||||
co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,6 +1114,7 @@ co_IntWaitMessage( PWND Window,
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing found. Wait for new messages. */
|
/* Nothing found. Wait for new messages. */
|
||||||
Status = co_MsqWaitForNewMessages( ThreadQueue,
|
Status = co_MsqWaitForNewMessages( ThreadQueue,
|
||||||
Window,
|
Window,
|
||||||
|
@ -1094,9 +1141,9 @@ co_IntGetPeekMessage( PMSG pMsg,
|
||||||
UINT RemoveMsg,
|
UINT RemoveMsg,
|
||||||
BOOL bGMSG )
|
BOOL bGMSG )
|
||||||
{
|
{
|
||||||
BOOL Present;
|
|
||||||
PWND Window;
|
PWND Window;
|
||||||
USER_MESSAGE Msg;
|
USER_MESSAGE Msg;
|
||||||
|
BOOL Present = FALSE;
|
||||||
|
|
||||||
if ( hWnd == HWND_TOPMOST || hWnd == HWND_BROADCAST )
|
if ( hWnd == HWND_TOPMOST || hWnd == HWND_BROADCAST )
|
||||||
hWnd = HWND_BOTTOM;
|
hWnd = HWND_BOTTOM;
|
||||||
|
@ -1123,6 +1170,8 @@ co_IntGetPeekMessage( PMSG pMsg,
|
||||||
MsgFilterMax = 0;
|
MsgFilterMax = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(&Msg, sizeof(USER_MESSAGE));
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Present = co_IntPeekMessage( &Msg,
|
Present = co_IntPeekMessage( &Msg,
|
||||||
|
@ -1132,33 +1181,40 @@ co_IntGetPeekMessage( PMSG pMsg,
|
||||||
RemoveMsg );
|
RemoveMsg );
|
||||||
if (Present)
|
if (Present)
|
||||||
{
|
{
|
||||||
RtlCopyMemory( pMsg, &Msg.Msg, sizeof(MSG));
|
RtlCopyMemory( pMsg, &Msg.Msg, sizeof(MSG));
|
||||||
|
|
||||||
if (bGMSG)
|
// The WH_GETMESSAGE hook enables an application to monitor messages about to
|
||||||
return (WM_QUIT != pMsg->message);
|
// be returned by the GetMessage or PeekMessage function.
|
||||||
else
|
|
||||||
return TRUE;
|
co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg);
|
||||||
|
|
||||||
|
if ( bGMSG )
|
||||||
|
return (WM_QUIT != pMsg->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bGMSG && !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
|
if ( bGMSG )
|
||||||
{
|
{
|
||||||
return -1;
|
if ( !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(RemoveMsg & PM_NOYIELD))
|
if (!(RemoveMsg & PM_NOYIELD))
|
||||||
{
|
{
|
||||||
// Yield this thread!
|
IdlePing();
|
||||||
UserLeave();
|
// Yield this thread!
|
||||||
ZwYieldExecution();
|
UserLeave();
|
||||||
UserEnterExclusive();
|
ZwYieldExecution();
|
||||||
// Fall through to fail.
|
UserEnterExclusive();
|
||||||
}
|
// Fall through to exit.
|
||||||
|
IdlePong();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while( bGMSG && !Present );
|
while( bGMSG && !Present );
|
||||||
|
|
||||||
return FALSE;
|
return Present;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
|
@ -2049,49 +2105,30 @@ NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
|
||||||
* retrieved.
|
* retrieved.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
BOOL GotMessage;
|
|
||||||
NTUSERGETMESSAGEINFO Info;
|
NTUSERGETMESSAGEINFO Info;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
/* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
|
/* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
|
||||||
PWND Window = NULL;
|
|
||||||
PMSGMEMORY MsgMemoryEntry;
|
PMSGMEMORY MsgMemoryEntry;
|
||||||
PVOID UserMem;
|
PVOID UserMem;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
USER_MESSAGE Msg;
|
MSG Msg;
|
||||||
|
BOOL GotMessage;
|
||||||
|
|
||||||
|
if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("Enter NtUserGetMessage\n");
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
/* Validate input */
|
RtlZeroMemory(&Msg, sizeof(MSG));
|
||||||
if (hWnd && !(Window = UserGetWindowObject(hWnd)))
|
|
||||||
{
|
|
||||||
UserLeave();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (Window) UserRefObjectCo(Window, &Ref);
|
GotMessage = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
|
||||||
|
|
||||||
if (MsgFilterMax < MsgFilterMin)
|
|
||||||
{
|
|
||||||
MsgFilterMin = 0;
|
|
||||||
MsgFilterMax = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
GotMessage = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_REMOVE);
|
|
||||||
|
|
||||||
if (!GotMessage && !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax))
|
|
||||||
{
|
|
||||||
UserLeave();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (! GotMessage);
|
|
||||||
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
|
||||||
Info.Msg = Msg.Msg;
|
Info.Msg = Msg; //.Msg;
|
||||||
/* See if this message type is present in the table */
|
/* See if this message type is present in the table */
|
||||||
MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
|
MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
|
||||||
|
|
||||||
|
@ -2103,7 +2140,7 @@ NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
|
||||||
if (NULL == MsgMemoryEntry)
|
if (NULL == MsgMemoryEntry)
|
||||||
{
|
{
|
||||||
/* Not present, no copying needed */
|
/* Not present, no copying needed */
|
||||||
Info.LParamSize = 0;
|
UnsafeInfo->LParamSize = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2127,8 +2164,8 @@ NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
|
||||||
ProbeForWrite(UserMem, Size, 1);
|
ProbeForWrite(UserMem, Size, 1);
|
||||||
RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
|
RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
|
||||||
|
|
||||||
Info.LParamSize = Size;
|
UnsafeInfo->LParamSize = Size;
|
||||||
Info.Msg.lParam = (LPARAM) UserMem;
|
UnsafeInfo->Msg.lParam = (LPARAM) UserMem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
@ -2144,7 +2181,7 @@ NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
return (Info.Msg.message != WM_QUIT );
|
return GotMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2163,10 +2200,10 @@ NtUserGetMessageX(PMSG pMsg,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(&Msg, sizeof(MSG));
|
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
RtlZeroMemory(&Msg, sizeof(MSG));
|
||||||
|
|
||||||
Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
|
Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
|
||||||
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
@ -2197,46 +2234,30 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
|
||||||
UINT RemoveMsg)
|
UINT RemoveMsg)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOL Ret;
|
|
||||||
NTUSERGETMESSAGEINFO Info;
|
NTUSERGETMESSAGEINFO Info;
|
||||||
PWND Window;
|
|
||||||
PMSGMEMORY MsgMemoryEntry;
|
PMSGMEMORY MsgMemoryEntry;
|
||||||
PVOID UserMem = NULL;
|
PVOID UserMem = NULL;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
USER_MESSAGE Msg;
|
MSG Msg;
|
||||||
|
BOOL Ret;
|
||||||
|
|
||||||
|
if ( RemoveMsg & PM_BADMSGFLAGS )
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_FLAGS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
if (hWnd == (HWND)-1 || hWnd == (HWND)0x0000FFFF || hWnd == (HWND)0xFFFFFFFF)
|
RtlZeroMemory(&Msg, sizeof(MSG));
|
||||||
hWnd = (HWND)1;
|
|
||||||
|
|
||||||
/* Validate input */
|
Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
|
||||||
if (hWnd && hWnd != (HWND)1)
|
|
||||||
{
|
|
||||||
if (!(Window = UserGetWindowObject(hWnd)))
|
|
||||||
{
|
|
||||||
UserLeave();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Window = (PWND)hWnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MsgFilterMax < MsgFilterMin)
|
|
||||||
{
|
|
||||||
MsgFilterMin = 0;
|
|
||||||
MsgFilterMax = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ret = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, RemoveMsg);
|
|
||||||
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
|
||||||
if (Ret)
|
if (Ret)
|
||||||
{
|
{
|
||||||
Info.Msg = Msg.Msg;
|
Info.Msg = Msg;
|
||||||
/* See if this message type is present in the table */
|
/* See if this message type is present in the table */
|
||||||
MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
|
MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
|
||||||
|
|
||||||
|
@ -2248,7 +2269,7 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
|
||||||
if (NULL == MsgMemoryEntry)
|
if (NULL == MsgMemoryEntry)
|
||||||
{
|
{
|
||||||
/* Not present, no copying needed */
|
/* Not present, no copying needed */
|
||||||
Info.LParamSize = 0;
|
UnsafeInfo->LParamSize = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2272,8 +2293,8 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
|
||||||
ProbeForWrite(UserMem, Size, 1);
|
ProbeForWrite(UserMem, Size, 1);
|
||||||
RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
|
RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
|
||||||
|
|
||||||
Info.LParamSize = Size;
|
UnsafeInfo->LParamSize = Size;
|
||||||
Info.Msg.lParam = (LPARAM) UserMem;
|
UnsafeInfo->Msg.lParam = (LPARAM) UserMem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
@ -2308,10 +2329,10 @@ NtUserPeekMessageX( PMSG pMsg,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(&Msg, sizeof(MSG));
|
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
RtlZeroMemory(&Msg, sizeof(MSG));
|
||||||
|
|
||||||
Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
|
Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
|
||||||
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
@ -2665,10 +2686,10 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
||||||
{
|
{
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
PPROCESSINFO W32Process;
|
PPROCESSINFO W32Process;
|
||||||
|
PTHREADINFO pti;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE Handles[2];
|
HANDLE Handles[3];
|
||||||
LARGE_INTEGER Timeout;
|
LARGE_INTEGER Timeout;
|
||||||
ULONGLONG StartTime, Run, Elapsed = 0;
|
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
@ -2686,8 +2707,13 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
||||||
return WAIT_FAILED;
|
return WAIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
W32Process = (PPROCESSINFO)Process->Win32Process;
|
W32Process = (PPROCESSINFO)Process->Win32Process;
|
||||||
if (!W32Process)
|
|
||||||
|
if ( PsGetProcessExitProcessCalled(Process) ||
|
||||||
|
!W32Process ||
|
||||||
|
pti->ppi == W32Process)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
@ -2695,10 +2721,9 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
||||||
return WAIT_FAILED;
|
return WAIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
EngCreateEvent((PEVENT *)&W32Process->InputIdleEvent);
|
|
||||||
|
|
||||||
Handles[0] = Process;
|
Handles[0] = Process;
|
||||||
Handles[1] = W32Process->InputIdleEvent;
|
Handles[1] = W32Process->InputIdleEvent;
|
||||||
|
Handles[2] = pti->MessageQueue->NewMessages; // pEventQueueServer; IntMsqSetWakeMask returns hEventQueueClient
|
||||||
|
|
||||||
if (!Handles[1])
|
if (!Handles[1])
|
||||||
{
|
{
|
||||||
|
@ -2707,16 +2732,15 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
||||||
return STATUS_SUCCESS; /* no event to wait on */
|
return STATUS_SUCCESS; /* no event to wait on */
|
||||||
}
|
}
|
||||||
|
|
||||||
StartTime = EngGetTickCount();
|
if (dwMilliseconds != INFINITE)
|
||||||
|
Timeout.QuadPart = (LONGLONG) dwMilliseconds * (LONGLONG) -10000;
|
||||||
Run = dwMilliseconds;
|
|
||||||
|
|
||||||
|
DPRINT("WFII: ppi 0x%x\n",W32Process);
|
||||||
DPRINT("WFII: waiting for %p\n", Handles[1] );
|
DPRINT("WFII: waiting for %p\n", Handles[1] );
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Timeout.QuadPart = Run - Elapsed;
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
Status = KeWaitForMultipleObjects( 2,
|
Status = KeWaitForMultipleObjects( 3,
|
||||||
Handles,
|
Handles,
|
||||||
WaitAny,
|
WaitAny,
|
||||||
UserRequest,
|
UserRequest,
|
||||||
|
@ -2736,21 +2760,19 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
||||||
switch (Status)
|
switch (Status)
|
||||||
{
|
{
|
||||||
case STATUS_WAIT_0:
|
case STATUS_WAIT_0:
|
||||||
Status = WAIT_FAILED;
|
|
||||||
goto WaitExit;
|
goto WaitExit;
|
||||||
|
|
||||||
case STATUS_WAIT_2:
|
case STATUS_WAIT_2:
|
||||||
{
|
{
|
||||||
USER_MESSAGE Msg;
|
USER_MESSAGE Msg;
|
||||||
co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
|
co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
|
||||||
break;
|
DPRINT1("WFII: WAIT 2\n");
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case STATUS_USER_APC:
|
|
||||||
case STATUS_ALERTED:
|
|
||||||
case STATUS_TIMEOUT:
|
case STATUS_TIMEOUT:
|
||||||
DPRINT1("WFII: timeout\n");
|
DPRINT1("WFII: timeout\n");
|
||||||
Status = STATUS_TIMEOUT;
|
case WAIT_FAILED:
|
||||||
goto WaitExit;
|
goto WaitExit;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2758,24 +2780,10 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
goto WaitExit;
|
goto WaitExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwMilliseconds != INFINITE)
|
|
||||||
{
|
|
||||||
Elapsed = EngGetTickCount() - StartTime;
|
|
||||||
|
|
||||||
if (Elapsed > Run)
|
|
||||||
Status = STATUS_TIMEOUT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (1);
|
while (TRUE);
|
||||||
|
|
||||||
WaitExit:
|
WaitExit:
|
||||||
if (W32Process->InputIdleEvent)
|
|
||||||
{
|
|
||||||
EngFreeMem((PVOID)W32Process->InputIdleEvent);
|
|
||||||
W32Process->InputIdleEvent = NULL;
|
|
||||||
}
|
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
UserLeave();
|
UserLeave();
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -62,32 +62,6 @@ static PAGED_LOOKASIDE_LIST MessageLookasideList;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
//
|
|
||||||
// Wakeup any thread/process waiting on idle input.
|
|
||||||
//
|
|
||||||
static VOID FASTCALL
|
|
||||||
IdlePing(VOID)
|
|
||||||
{
|
|
||||||
HWND hWnd;
|
|
||||||
PWND Window;
|
|
||||||
PPROCESSINFO W32d = PsGetCurrentProcessWin32Process();
|
|
||||||
|
|
||||||
hWnd = UserGetForegroundWindow();
|
|
||||||
|
|
||||||
Window = UserGetWindowObject(hWnd);
|
|
||||||
|
|
||||||
if (Window && Window->head.pti)
|
|
||||||
{
|
|
||||||
if (Window->head.pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE))
|
|
||||||
{
|
|
||||||
co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (W32d && W32d->InputIdleEvent)
|
|
||||||
KePulseEvent( W32d->InputIdleEvent, EVENT_INCREMENT, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE FASTCALL
|
HANDLE FASTCALL
|
||||||
IntMsqSetWakeMask(DWORD WakeMask)
|
IntMsqSetWakeMask(DWORD WakeMask)
|
||||||
{
|
{
|
||||||
|
@ -578,8 +552,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWND Window,
|
||||||
WaitObjects[0] = &HardwareMessageQueueLock;
|
WaitObjects[0] = &HardwareMessageQueueLock;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
IdlePing();
|
|
||||||
|
|
||||||
UserLeaveCo();
|
UserLeaveCo();
|
||||||
|
|
||||||
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
|
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
|
||||||
|
@ -1185,8 +1157,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
|
|
||||||
if(Block)
|
if(Block)
|
||||||
{
|
{
|
||||||
IdlePing();
|
|
||||||
|
|
||||||
UserLeaveCo();
|
UserLeaveCo();
|
||||||
|
|
||||||
/* don't process messages sent to the thread */
|
/* don't process messages sent to the thread */
|
||||||
|
@ -1248,8 +1218,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
WaitObjects[1] = ThreadQueue->NewMessages;
|
WaitObjects[1] = ThreadQueue->NewMessages;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
IdlePing();
|
|
||||||
|
|
||||||
UserLeaveCo();
|
UserLeaveCo();
|
||||||
|
|
||||||
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
|
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
|
||||||
|
@ -1407,8 +1375,6 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
|
||||||
PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent};
|
PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent};
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
|
|
||||||
IdlePing(); // Going to wait so send Idle ping.
|
|
||||||
|
|
||||||
UserLeaveCo();
|
UserLeaveCo();
|
||||||
|
|
||||||
ret = KeWaitForMultipleObjects(2,
|
ret = KeWaitForMultipleObjects(2,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue