- NtUserWaitForInputIdle: Call EngGetTickCount, removing duplicated code
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / message.c
index 79a7402..2f23df4 100644 (file)
@@ -114,7 +114,7 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
    PUNICODE_STRING ClassName;
    UINT Size = 0;
 
-   _SEH_TRY
+   _SEH2_TRY
    {
       if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
       {
@@ -167,12 +167,12 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
          Size = MsgMemoryEntry->Size;
       }
    }
-   _SEH_HANDLE
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
-      DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH_GetExceptionCode());
+      DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH2_GetExceptionCode());
       Size = 0;
    }
-   _SEH_END;
+   _SEH2_END;
    return Size;
 }
 
@@ -295,8 +295,55 @@ UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
    return STATUS_INVALID_PARAMETER;
 }
 
+static
+VOID
+FASTCALL
+IntCallWndProc
+( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+   BOOL SameThread = FALSE;
+
+   if (Window->ti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->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 );
+   }
+}
+static
+VOID
+FASTCALL
+IntCallWndProcRet
+( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
+{
+   BOOL SameThread = FALSE;
+
+   if (Window->ti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->ThreadInfo)
+      SameThread = TRUE;
+
+   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 );
+   }
+}
+
+
 BOOL
-STDCALL
+APIENTRY
 NtUserCallMsgFilter(
    LPMSG lpmsg,
    INT code)
@@ -309,7 +356,7 @@ NtUserCallMsgFilter(
    UserEnterExclusive();
    if (lpmsg)
    {
-      _SEH_TRY
+      _SEH2_TRY
       {
          ProbeForRead((PVOID)lpmsg,
                        sizeof(MSG),
@@ -318,11 +365,11 @@ NtUserCallMsgFilter(
                 (PVOID)lpmsg,
                  sizeof(MSG));
       }
-      _SEH_HANDLE
+      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
          BadChk = TRUE;
       }
-      _SEH_END;
+      _SEH2_END;
    }
    else
      RETURN( FALSE);
@@ -334,7 +381,7 @@ NtUserCallMsgFilter(
       Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
    }
 
-   _SEH_TRY
+   _SEH2_TRY
    {
       ProbeForWrite((PVOID)lpmsg,
                      sizeof(MSG),
@@ -343,11 +390,11 @@ NtUserCallMsgFilter(
                             &Msg,
                      sizeof(MSG));
    }
-   _SEH_HANDLE
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
       BadChk = TRUE;
    }
-   _SEH_END;
+   _SEH2_END;
    if (BadChk) RETURN( FALSE);
    RETURN( Ret)
 
@@ -357,7 +404,7 @@ CLEANUP:
    END_CLEANUP;
 }
 
-LRESULT STDCALL
+LRESULT APIENTRY
 NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
 {
    NTSTATUS Status;
@@ -447,7 +494,7 @@ CLEANUP:
 }
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserTranslateMessage(LPMSG lpMsg,
                        HKL dwhkl)
 {
@@ -550,10 +597,11 @@ co_IntActivateWindowMouse(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, PWINDOW_OB
    }
 
    Parent = IntGetParent(MsgWindow);//fixme: deref retval?
-   /* fixme: abort if no parent ? */
+
+   /* If no parent window, pass MsgWindows HWND as wParam. Fixes bug #3111 */
    Result = co_IntSendMessage(MsgWindow->hSelf,
                               WM_MOUSEACTIVATE,
-                              (WPARAM) (Parent ? Parent->hSelf : NULL),
+                              (WPARAM) (Parent ? Parent->hSelf : MsgWindow->hSelf),
                               (LPARAM)MAKELONG(*HitTest, Msg->message)
                              );
 
@@ -693,6 +741,7 @@ co_IntPeekMessage(PUSER_MESSAGE Msg,
                   UINT MsgFilterMax,
                   UINT RemoveMsg)
 {
+   PTHREADINFO pti;
    LARGE_INTEGER LargeTickCount;
    PUSER_MESSAGE_QUEUE ThreadQueue;
    PUSER_MESSAGE Message;
@@ -704,7 +753,8 @@ co_IntPeekMessage(PUSER_MESSAGE Msg,
    /* The queues and order in which they are checked are documented in the MSDN
       article on GetMessage() */
 
-   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
+   pti = PsGetCurrentThreadWin32Thread();
+   ThreadQueue = pti->MessageQueue;
 
    /* Inspect RemoveMsg flags */
    /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
@@ -780,7 +830,7 @@ CheckMessages:
       ;
 
    /* Check for paint messages. */
-   if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, PsGetCurrentThreadWin32Thread(), &Msg->Msg, RemoveMessages))
+   if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, pti, &Msg->Msg, RemoveMessages))
    {
       Msg->FreeLParam = FALSE;
       goto MsgExit;
@@ -875,7 +925,7 @@ MsgExit:
                 MHook.hwnd         = Msg->Msg.hwnd;
                 MHook.wHitTestCode = HitTest;
                 MHook.dwExtraInfo  = 0;
-                co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, 
+                co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED,
                                    Msg->Msg.message, (LPARAM)&MHook);
             }
             return FALSE;
@@ -911,7 +961,7 @@ MsgExit:
    return Present;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
                   HWND hWnd,
                   UINT MsgFilterMin,
@@ -1009,11 +1059,13 @@ co_IntWaitMessage(HWND Wnd,
                   UINT MsgFilterMin,
                   UINT MsgFilterMax)
 {
+   PTHREADINFO pti;
    PUSER_MESSAGE_QUEUE ThreadQueue;
    NTSTATUS Status;
    USER_MESSAGE Msg;
 
-   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
+   pti = PsGetCurrentThreadWin32Thread();
+   ThreadQueue = pti->MessageQueue;
 
    do
    {
@@ -1032,7 +1084,7 @@ co_IntWaitMessage(HWND Wnd,
    return FALSE;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
                  HWND hWnd,
                  UINT MsgFilterMin,
@@ -1051,6 +1103,7 @@ NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
    BOOL GotMessage;
    NTUSERGETMESSAGEINFO Info;
    NTSTATUS Status;
+   /* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
    PWINDOW_OBJECT Window = NULL;
    PMSGMEMORY MsgMemoryEntry;
    PVOID UserMem;
@@ -1183,7 +1236,7 @@ CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEnt
          if (! NT_SUCCESS(Status))
          {
             DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
-            ExFreePool(KernelMem);
+            ExFreePoolWithTag(KernelMem, TAG_MSG);
             return Status;
          }
       }
@@ -1245,14 +1298,16 @@ UserPostMessage(HWND Wnd,
                 WPARAM wParam,
                 LPARAM lParam)
 {
+   PTHREADINFO pti;
    MSG UserModeMsg, KernelModeMsg;
    LARGE_INTEGER LargeTickCount;
    NTSTATUS Status;
    PMSGMEMORY MsgMemoryEntry;
 
+   pti = PsGetCurrentThreadWin32Thread();
    if (WM_QUIT == Msg)
    {
-      MsqPostQuitMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, wParam);
+      MsqPostQuitMessage(pti->MessageQueue, wParam);
    }
    else if (Wnd == HWND_BROADCAST)
    {
@@ -1297,7 +1352,7 @@ UserPostMessage(HWND Wnd,
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
          return FALSE;
       }
-      IntGetCursorLocation(PsGetCurrentThreadWin32Thread()->Desktop->WindowStation,
+      IntGetCursorLocation(pti->Desktop->WindowStation,
                            &KernelModeMsg.pt);
       KeQueryTickCount(&LargeTickCount);
       KernelModeMsg.time = MsqCalculateMessageTime(&LargeTickCount);
@@ -1310,7 +1365,7 @@ UserPostMessage(HWND Wnd,
 }
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserPostMessage(HWND hWnd,
                   UINT Msg,
                   WPARAM wParam,
@@ -1331,7 +1386,7 @@ CLEANUP:
 
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserPostThreadMessage(DWORD idThread,
                         UINT Msg,
                         WPARAM wParam,
@@ -1339,7 +1394,7 @@ NtUserPostThreadMessage(DWORD idThread,
 {
    MSG UserModeMsg, KernelModeMsg;
    PETHREAD peThread;
-   PW32THREAD pThread;
+   PTHREADINFO pThread;
    NTSTATUS Status;
    PMSGMEMORY MsgMemoryEntry;
    DECLARE_RETURN(BOOL);
@@ -1351,7 +1406,7 @@ NtUserPostThreadMessage(DWORD idThread,
 
    if( Status == STATUS_SUCCESS )
    {
-      pThread = (PW32THREAD)peThread->Tcb.Win32Thread;
+      pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
       if( !pThread || !pThread->MessageQueue )
       {
          ObDereferenceObject( peThread );
@@ -1388,7 +1443,7 @@ CLEANUP:
    END_CLEANUP;
 }
 
-DWORD STDCALL
+DWORD APIENTRY
 NtUserQuerySendMessage(DWORD Unknown0)
 {
    UNIMPLEMENTED;
@@ -1426,10 +1481,9 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
    PMSGMEMORY MsgMemoryEntry;
    INT lParamBufferSize;
    LPARAM lParamPacked;
-   PW32THREAD Win32Thread;
+   PTHREADINFO Win32Thread;
    DECLARE_RETURN(LRESULT);
    USER_REFERENCE_ENTRY Ref;
-   BOOL SameThread = FALSE;
 
    if (!(Window = UserGetWindowObject(hWnd)))
    {
@@ -1440,20 +1494,8 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
 
    Win32Thread = PsGetCurrentThreadWin32Thread();
 
-   if (Window->ti == Win32Thread->ThreadInfo)
-      SameThread = TRUE;
+   IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
 
-   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 &&
        Window->MessageQueue == Win32Thread->MessageQueue)
    {
@@ -1488,17 +1530,7 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
          *uResult = Result;
       }
 
-      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 = Result;
-         co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
-      }
+      IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
 
       if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam)))
       {
@@ -1531,28 +1563,18 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
                                                 lParam,
                                               uTimeout,
                                  (uFlags & SMTO_BLOCK),
-                                                 FALSE,
+                                            MSQ_NORMAL,
                                                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 );
-   }
+   IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
 
    if (STATUS_TIMEOUT == Status)
    {
-/* 
+/*
    MSDN says:
       Microsoft Windows 2000: If GetLastError returns zero, then the function
       timed out.
@@ -1628,6 +1650,7 @@ co_IntPostOrSendMessage(HWND hWnd,
                         LPARAM lParam)
 {
    ULONG_PTR Result;
+   PTHREADINFO pti;
    PWINDOW_OBJECT Window;
 
    if(hWnd == HWND_BROADCAST)
@@ -1640,7 +1663,8 @@ co_IntPostOrSendMessage(HWND hWnd,
       return 0;
    }
 
-   if(Window->MessageQueue != PsGetCurrentThreadWin32Thread()->MessageQueue)
+   pti = PsGetCurrentThreadWin32Thread();
+   if(Window->MessageQueue != pti->MessageQueue)
    {
       Result = UserPostMessage(hWnd, Msg, wParam, lParam);
    }
@@ -1662,9 +1686,10 @@ co_IntDoSendMessage(HWND hWnd,
                     PDOSENDMESSAGE dsm,
                     PNTUSERSENDMESSAGEINFO UnsafeInfo)
 {
+   PTHREADINFO pti;
    LRESULT Result = TRUE;
    NTSTATUS Status;
-   PWINDOW_OBJECT Window;
+   PWINDOW_OBJECT Window = NULL;
    NTUSERSENDMESSAGEINFO Info;
    MSG UserModeMsg;
    MSG KernelModeMsg;
@@ -1690,8 +1715,9 @@ co_IntDoSendMessage(HWND hWnd,
    /* FIXME: Check for an exiting window. */
 
    /* See if the current thread can handle the message */
-   if (HWND_BROADCAST != hWnd && NULL != PsGetCurrentThreadWin32Thread() &&
-         Window->MessageQueue == PsGetCurrentThreadWin32Thread()->MessageQueue)
+   pti = PsGetCurrentThreadWin32Thread();
+   if (HWND_BROADCAST != hWnd && NULL != pti &&
+         Window->MessageQueue == pti->MessageQueue)
    {
       /* Gather the information usermode needs to call the window proc directly */
       Info.HandledByKernel = FALSE;
@@ -1703,6 +1729,8 @@ co_IntDoSendMessage(HWND hWnd,
          Info.Ansi = ! Window->Wnd->Unicode;
       }
 
+      IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+
       if (Window->Wnd->IsSystem)
       {
           Info.Proc = (!Info.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
@@ -1712,6 +1740,9 @@ co_IntDoSendMessage(HWND hWnd,
           Info.Ansi = !Window->Wnd->Unicode;
           Info.Proc = Window->Wnd->WndProc;
       }
+
+      IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result);
+
    }
    else
    {
@@ -1762,7 +1793,7 @@ co_IntDoSendMessage(HWND hWnd,
    return (LRESULT)Result;
 }
 
-LRESULT STDCALL
+LRESULT APIENTRY
 NtUserSendMessageTimeout(HWND hWnd,
                          UINT Msg,
                          WPARAM wParam,
@@ -1801,7 +1832,7 @@ CLEANUP:
    END_CLEANUP;
 }
 
-LRESULT STDCALL
+LRESULT APIENTRY
 NtUserSendMessage(HWND Wnd,
                   UINT Msg,
                   WPARAM wParam,
@@ -1851,6 +1882,7 @@ UserSendNotifyMessage(HWND hWnd,
    else
    {
      ULONG_PTR PResult;
+     PTHREADINFO pti;
      PWINDOW_OBJECT Window;
      NTSTATUS Status;
      MSG UserModeMsg;
@@ -1859,7 +1891,8 @@ UserSendNotifyMessage(HWND hWnd,
 
       if(!(Window = UserGetWindowObject(hWnd))) return FALSE;
 
-      if(Window->MessageQueue != PsGetCurrentThreadWin32Thread()->MessageQueue)
+      pti = PsGetCurrentThreadWin32Thread();
+      if(Window->MessageQueue != pti->MessageQueue)
       { // Send message w/o waiting for it.
          Result = UserPostMessage(hWnd, Msg, wParam, lParam);
       }
@@ -1893,7 +1926,7 @@ UserSendNotifyMessage(HWND hWnd,
 }
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserSendNotifyMessage(HWND hWnd,
                         UINT Msg,
                         WPARAM wParam,
@@ -1914,7 +1947,7 @@ CLEANUP:
 }
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserWaitMessage(VOID)
 {
    DECLARE_RETURN(BOOL);
@@ -1930,16 +1963,18 @@ CLEANUP:
    END_CLEANUP;
 }
 
-DWORD STDCALL
+DWORD APIENTRY
 IntGetQueueStatus(BOOL ClearChanges)
 {
+   PTHREADINFO pti;
    PUSER_MESSAGE_QUEUE Queue;
    DWORD Result;
    DECLARE_RETURN(DWORD);
 
    DPRINT("Enter IntGetQueueStatus\n");
 
-   Queue = PsGetCurrentThreadWin32Thread()->MessageQueue;
+   pti = PsGetCurrentThreadWin32Thread();
+   Queue = pti->MessageQueue;
 
    Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
    if (ClearChanges)
@@ -1954,34 +1989,34 @@ CLEANUP:
    END_CLEANUP;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 IntInitMessagePumpHook()
 {
-   if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
+   if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
    {
-     ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook++;
+     ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook++;
      return TRUE;
    }
    return FALSE;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 IntUninitMessagePumpHook()
 {
-   if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
+   if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
    {
-      if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook <= 0)
+      if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook <= 0)
       {
          return FALSE;
       }
-      ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook--;
+      ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook--;
       return TRUE;
    }
    return FALSE;
 }
 
 
-LRESULT STDCALL
+LRESULT APIENTRY
 NtUserMessageCall(
    HWND hWnd,
    UINT Msg,
@@ -2001,7 +2036,7 @@ NtUserMessageCall(
    if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
    {
       return 0;
-   }   
+   }
    switch(dwType)
    {
       case FNID_DEFWINDOWPROC:
@@ -2018,18 +2053,18 @@ NtUserMessageCall(
 
          if (ResultInfo)
          {
-            _SEH_TRY
+            _SEH2_TRY
             {
                ProbeForWrite((PVOID)ResultInfo,
                          sizeof(BROADCASTPARM),
-                                             1);               
+                                             1);
                parm = (PBROADCASTPARM)ResultInfo;
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                BadChk = TRUE;
             }
-            _SEH_END;
+            _SEH2_END;
             if (BadChk) break;
          }
          else
@@ -2087,33 +2122,62 @@ NtUserMessageCall(
       break;
       case FNID_SENDMESSAGECALLBACK:
       break;
+      // CallNextHook bypass.
       case FNID_CALLWNDPROC:
-      {
-         CWPSTRUCT CWP;
-         PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
-         CWP.hwnd    = hWnd;
-         CWP.message = Msg;
-         CWP.wParam  = wParam;
-         CWP.lParam  = lParam;
-         lResult = co_HOOK_CallHooks( WH_CALLWNDPROC,
-                                      HC_ACTION,
-                                      ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
-                                      (LPARAM)&CWP );
-      }
-      break;
       case FNID_CALLWNDPROCRET:
       {
-         CWPRETSTRUCT CWPR;
-         PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
-         CWPR.hwnd    = hWnd;
-         CWPR.message = Msg;
-         CWPR.wParam  = wParam;
-         CWPR.lParam  = lParam;
-         CWPR.lResult = ClientInfo->dwHookData;
-         lResult = co_HOOK_CallHooks( WH_CALLWNDPROCRET,
-                                      HC_ACTION,
-                                      ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
-                                      (LPARAM)&CWPR );
+         PCLIENTINFO ClientInfo = GetWin32ClientInfo();
+         PHOOK NextObj, Hook = ClientInfo->phkCurrent;
+
+         if (!ClientInfo || !Hook) break;
+
+         UserReferenceObject(Hook);
+
+         if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
+         {
+            UserDereferenceObject(Hook);
+            break;
+         }
+
+         NextObj = IntGetNextHook(Hook);
+         ClientInfo->phkCurrent = NextObj;
+
+         if ( Hook->HookId == WH_CALLWNDPROC)
+         {
+            CWPSTRUCT CWP;
+            CWP.hwnd    = hWnd;
+            CWP.message = Msg;
+            CWP.wParam  = wParam;
+            CWP.lParam  = lParam;
+            DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
+
+            lResult = co_IntCallHookProc( Hook->HookId,
+                                          HC_ACTION,
+                                        ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
+                                         (LPARAM)&CWP,
+                                          Hook->Proc,
+                                          Hook->Ansi,
+                                          &Hook->ModuleName);
+         }
+         else
+         {
+            CWPRETSTRUCT CWPR;
+            CWPR.hwnd    = hWnd;
+            CWPR.message = Msg;
+            CWPR.wParam  = wParam;
+            CWPR.lParam  = lParam;
+            CWPR.lResult = ClientInfo->dwHookData;
+
+            lResult = co_IntCallHookProc( Hook->HookId,
+                                          HC_ACTION,
+                                        ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
+                                         (LPARAM)&CWPR,
+                                          Hook->Proc,
+                                          Hook->Ansi,
+                                          &Hook->ModuleName);
+         }
+         UserDereferenceObject(Hook);
+         lResult = (LRESULT) NextObj;
       }
       break;
    }
@@ -2125,7 +2189,7 @@ NtUserMessageCall(
 #define WAIT_FAILED ((DWORD)0xFFFFFFFF)
 
 DWORD
-NTAPI
+APIENTRY
 NtUserWaitForInputIdle(
    IN HANDLE hProcess,
    IN DWORD dwMilliseconds,
@@ -2135,7 +2199,7 @@ NtUserWaitForInputIdle(
   PW32PROCESS W32Process;
   NTSTATUS Status;
   HANDLE Handles[2];
-  LARGE_INTEGER Timeout; 
+  LARGE_INTEGER Timeout;
   ULONGLONG StartTime, Run, Elapsed = 0;
 
   UserEnterExclusive();
@@ -2175,8 +2239,7 @@ NtUserWaitForInputIdle(
       return STATUS_SUCCESS;  /* no event to wait on */
   }
 
-  StartTime = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
-                          SharedUserData->TickCountMultiplier / 16777216);
+  StartTime = EngGetTickCount();
 
   Run = dwMilliseconds;
 
@@ -2230,9 +2293,7 @@ NtUserWaitForInputIdle(
 
      if (dwMilliseconds != INFINITE)
      {
-        Elapsed = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
-                              SharedUserData->TickCountMultiplier / 16777216) 
-                              - StartTime;
+        Elapsed = EngGetTickCount() - StartTime;
 
         if (Elapsed > Run)
            Status = STATUS_TIMEOUT;