Sync to trunk head (r42241)
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / message.c
index 70ae5fd..a96d05d 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)
       {
@@ -156,6 +156,10 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
                Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
                break;
 
+            case WM_COPYGLOBALDATA:
+               Size = wParam;
+               break;
+
             default:
                assert(FALSE);
                Size = 0;
@@ -167,12 +171,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 +299,117 @@ 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->fsHooks & 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->fsHooks & 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 );
+   }
+}
+
+LRESULT
+FASTCALL
+IntDispatchMessage(PMSG pMsg)
+{
+  LARGE_INTEGER TickCount;
+  LONG Time;
+  LRESULT retval;
+  PWINDOW_OBJECT Window = NULL;
+
+  if (pMsg->hwnd)
+  {
+     Window = UserGetWindowObject(pMsg->hwnd);
+     if (!Window || !Window->Wnd) return 0;
+  }
+
+  if (((pMsg->message == WM_SYSTIMER) ||
+       (pMsg->message == WM_TIMER)) &&
+      (pMsg->lParam) )
+  {
+     if (pMsg->message == WM_TIMER)
+     {
+        if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),Window,pMsg->wParam,pMsg->lParam))
+        {
+           KeQueryTickCount(&TickCount);
+           Time = MsqCalculateMessageTime(&TickCount);
+           return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
+                                        TRUE,
+                                        pMsg->hwnd,
+                                        WM_TIMER,
+                                        pMsg->wParam,
+                                        (LPARAM)Time,
+                                        sizeof(LPARAM));
+        }
+        return 0;        
+     }
+     else
+     {
+        PTIMER pTimer = FindSystemTimer(pMsg);
+        if (pTimer && pTimer->pfn)
+        {
+           KeQueryTickCount(&TickCount);
+           Time = MsqCalculateMessageTime(&TickCount);
+           pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, Time);
+        }
+        return 0;
+     }
+  }
+  // Need a window!
+  if (!Window) return 0;
+
+  retval = co_IntPostOrSendMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
+
+  if (pMsg->message == WM_PAINT)
+  {
+  /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
+     HRGN hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
+     co_UserGetUpdateRgn( Window, hrgn, TRUE );
+     GreDeleteObject( hrgn );
+  }
+  return retval;
+}
+
+
 BOOL
-STDCALL
+APIENTRY
 NtUserCallMsgFilter(
    LPMSG lpmsg,
    INT code)
@@ -309,7 +422,7 @@ NtUserCallMsgFilter(
    UserEnterExclusive();
    if (lpmsg)
    {
-      _SEH_TRY
+      _SEH2_TRY
       {
          ProbeForRead((PVOID)lpmsg,
                        sizeof(MSG),
@@ -318,11 +431,11 @@ NtUserCallMsgFilter(
                 (PVOID)lpmsg,
                  sizeof(MSG));
       }
-      _SEH_HANDLE
+      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
          BadChk = TRUE;
       }
-      _SEH_END;
+      _SEH2_END;
    }
    else
      RETURN( FALSE);
@@ -334,7 +447,7 @@ NtUserCallMsgFilter(
       Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
    }
 
-   _SEH_TRY
+   _SEH2_TRY
    {
       ProbeForWrite((PVOID)lpmsg,
                      sizeof(MSG),
@@ -343,11 +456,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,97 +470,34 @@ CLEANUP:
    END_CLEANUP;
 }
 
-LRESULT STDCALL
-NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
+LRESULT APIENTRY
+NtUserDispatchMessage(PMSG UnsafeMsgInfo)
 {
-   NTSTATUS Status;
-   NTUSERDISPATCHMESSAGEINFO MsgInfo;
-   LRESULT Result = TRUE;
-   DECLARE_RETURN(LRESULT);
-
-   DPRINT("Enter NtUserDispatchMessage\n");
-   UserEnterExclusive();
-
-   Status = MmCopyFromCaller(&MsgInfo, UnsafeMsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
-   if (! NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      RETURN( 0);
-   }
-
-   /* Process timer messages. */
-   if (WM_TIMER == MsgInfo.Msg.message && 0 != MsgInfo.Msg.lParam)
-   {
-      LARGE_INTEGER LargeTickCount;
-      /* FIXME: Call hooks. */
-
-      /* FIXME: Check for continuing validity of timer. */
+  LRESULT Res = 0;
+  BOOL Hit = FALSE;
+  MSG SafeMsg;
 
-      MsgInfo.HandledByKernel = FALSE;
-      KeQueryTickCount(&LargeTickCount);
-      MsgInfo.Proc = (WNDPROC) MsgInfo.Msg.lParam;
-      MsgInfo.Msg.lParam = (LPARAM)LargeTickCount.u.LowPart;
-   }
-   else if (NULL == MsgInfo.Msg.hwnd)
-   {
-      MsgInfo.HandledByKernel = TRUE;
-      Result = 0;
-   }
-   else
-   {
-      PWINDOW_OBJECT Window;
-
-      /* Get the window object. */
-      Window = UserGetWindowObject(MsgInfo.Msg.hwnd);
-      if (NULL == Window)
-      {
-         MsgInfo.HandledByKernel = TRUE;
-         Result = 0;
-      }
-      else
-      {
-         if (Window->OwnerThread != PsGetCurrentThread())
-         {
-            DPRINT1("Window doesn't belong to the calling thread!\n");
-            MsgInfo.HandledByKernel = TRUE;
-            Result = 0;
-         }
-         else
-         {
-            /* FIXME: Call hook procedures. */
-
-            MsgInfo.HandledByKernel = FALSE;
-            Result = 0;
-
-            if (Window->Wnd->IsSystem)
-            {
-                MsgInfo.Proc = (!MsgInfo.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
-            }
-            else
-            {
-                MsgInfo.Ansi = !Window->Wnd->Unicode;
-                MsgInfo.Proc = Window->Wnd->WndProc;
-            }
-         }
-      }
-   }
-   Status = MmCopyToCaller(UnsafeMsgInfo, &MsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
-   if (! NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      RETURN( 0);
-   }
-
-   RETURN( Result);
+  UserEnterExclusive();  
+  _SEH2_TRY
+  {
+    ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
+    RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
+  }
+  _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+  {
+    SetLastNtError(_SEH2_GetExceptionCode());
+    Hit = TRUE;
+  }
+  _SEH2_END;
+  
+  if (!Hit) Res = IntDispatchMessage(&SafeMsg);
 
-CLEANUP:
-   DPRINT("Leave NtUserDispatchMessage. ret=%i\n", _ret_);
-   UserLeave();
-   END_CLEANUP;
+  UserLeave();
+  return Res;
 }
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserTranslateMessage(LPMSG lpMsg,
                        HKL dwhkl)
 {
@@ -550,10 +600,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)
                              );
 
@@ -643,7 +694,7 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *
    {
       /* generate double click messages, if necessary */
       if ((((*HitTest) != HTCLIENT) ||
-            (Window->Wnd->Class->Style & CS_DBLCLKS)) &&
+            (Window->Wnd->pcls->style & CS_DBLCLKS)) &&
             MsqIsDblClk(Msg, Remove))
       {
          Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
@@ -673,8 +724,8 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *
       {
          /* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
          Msg->lParam = MAKELONG(
-                          Msg->pt.x - (WORD)Window->Wnd->ClientRect.left,
-                          Msg->pt.y - (WORD)Window->Wnd->ClientRect.top);
+                          Msg->pt.x - (WORD)Window->Wnd->rcClient.left,
+                          Msg->pt.y - (WORD)Window->Wnd->rcClient.top);
       }
    }
 
@@ -688,11 +739,12 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *
  */
 BOOL FASTCALL
 co_IntPeekMessage(PUSER_MESSAGE Msg,
-                  HWND hWnd,
+                  PWINDOW_OBJECT Window,
                   UINT MsgFilterMin,
                   UINT MsgFilterMax,
                   UINT RemoveMsg)
 {
+   PTHREADINFO pti;
    LARGE_INTEGER LargeTickCount;
    PUSER_MESSAGE_QUEUE ThreadQueue;
    PUSER_MESSAGE Message;
@@ -704,7 +756,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 */
@@ -743,7 +796,7 @@ CheckMessages:
    Present = co_MsqFindMessage(ThreadQueue,
                                FALSE,
                                RemoveMessages,
-                               hWnd,
+                               Window,
                                MsgFilterMin,
                                MsgFilterMax,
                                &Message);
@@ -761,7 +814,7 @@ CheckMessages:
    Present = co_MsqFindMessage(ThreadQueue,
                                TRUE,
                                RemoveMessages,
-                               hWnd,
+                               Window,
                                MsgFilterMin,
                                MsgFilterMax,
                                &Message);
@@ -780,14 +833,19 @@ CheckMessages:
       ;
 
    /* Check for paint messages. */
-   if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, PsGetCurrentThreadWin32Thread(), &Msg->Msg, RemoveMessages))
+   if (IntGetPaintMessage(Window, MsgFilterMin, MsgFilterMax, pti, &Msg->Msg, RemoveMessages))
    {
       Msg->FreeLParam = FALSE;
       goto MsgExit;
    }
 
+   if (ThreadQueue->WakeMask & QS_TIMER)
+      if (PostTimerMessages(Window)) // If there are timers ready,
+         goto CheckMessages;       // go back and process them.
+
+   // LOL! Polling Timer Queue? How much time is spent doing this?
    /* Check for WM_(SYS)TIMER messages */
-   Present = MsqGetTimerMessage(ThreadQueue, hWnd, MsgFilterMin, MsgFilterMax,
+   Present = MsqGetTimerMessage(ThreadQueue, Window, MsgFilterMin, MsgFilterMax,
                                 &Msg->Msg, RemoveMessages);
    if (Present)
    {
@@ -875,7 +933,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 +969,7 @@ MsgExit:
    return Present;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
                   HWND hWnd,
                   UINT MsgFilterMin,
@@ -924,21 +982,28 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
    PWINDOW_OBJECT Window;
    PMSGMEMORY MsgMemoryEntry;
    PVOID UserMem;
-   UINT Size;
+   SIZE_T Size;
    USER_MESSAGE Msg;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserPeekMessage\n");
    UserEnterExclusive();
 
+   if (hWnd == (HWND)-1 || hWnd == (HWND)0x0000FFFF || hWnd == (HWND)0xFFFFFFFF)
+      hWnd = (HWND)1;
+
    /* Validate input */
-   if (hWnd && hWnd != INVALID_HANDLE_VALUE)
+   if (hWnd && hWnd != (HWND)1)
    {
       if (!(Window = UserGetWindowObject(hWnd)))
       {
          RETURN(-1);
       }
    }
+   else
+   {
+      Window = (PWINDOW_OBJECT)hWnd;
+   }
 
    if (MsgFilterMax < MsgFilterMin)
    {
@@ -946,7 +1011,7 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
       MsgFilterMax = 0;
    }
 
-   Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
+   Present = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, RemoveMsg);
    if (Present)
    {
 
@@ -967,18 +1032,18 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
          Info.LParamSize = Size;
          UserMem = NULL;
          Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
-                                          &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
+                                          &Size, MEM_COMMIT, PAGE_READWRITE);
          if (! NT_SUCCESS(Status))
          {
             SetLastNtError(Status);
             RETURN( (BOOL) -1);
          }
          /* Transfer lParam data to user-mode mem */
-         Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
+         Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Info.LParamSize);
          if (! NT_SUCCESS(Status))
          {
             ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
-                                &Info.LParamSize, MEM_RELEASE);
+                                &Size, MEM_RELEASE);
             SetLastNtError(Status);
             RETURN( (BOOL) -1);
          }
@@ -1005,25 +1070,27 @@ CLEANUP:
 }
 
 static BOOL FASTCALL
-co_IntWaitMessage(HWND Wnd,
+co_IntWaitMessage(PWINDOW_OBJECT Window,
                   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
    {
-      if (co_IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
+      if (co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
       {
          return TRUE;
       }
 
       /* Nothing found. Wait for new messages. */
-      Status = co_MsqWaitForNewMessages(ThreadQueue, Wnd, MsgFilterMin, MsgFilterMax);
+      Status = co_MsqWaitForNewMessages(ThreadQueue, Window, MsgFilterMin, MsgFilterMax);
    }
    while ((STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) || STATUS_TIMEOUT == Status);
 
@@ -1032,7 +1099,7 @@ co_IntWaitMessage(HWND Wnd,
    return FALSE;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
                  HWND hWnd,
                  UINT MsgFilterMin,
@@ -1051,10 +1118,11 @@ 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;
-   UINT Size;
+   SIZE_T Size;
    USER_MESSAGE Msg;
    DECLARE_RETURN(BOOL);
 //   USER_REFERENCE_ENTRY Ref;
@@ -1078,7 +1146,7 @@ NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
 
    do
    {
-      GotMessage = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
+      GotMessage = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_REMOVE);
       if (GotMessage)
       {
          Info.Msg = Msg.Msg;
@@ -1098,7 +1166,7 @@ NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
             Info.LParamSize = Size;
             UserMem = NULL;
             Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
-                                             &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
+                                             &Size, MEM_COMMIT, PAGE_READWRITE);
 
             if (! NT_SUCCESS(Status))
             {
@@ -1106,11 +1174,11 @@ NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
                RETURN( (BOOL) -1);
             }
             /* Transfer lParam data to user-mode mem */
-            Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
+            Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Info.LParamSize);
             if (! NT_SUCCESS(Status))
             {
                ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
-                                   &Info.LParamSize, MEM_DECOMMIT);
+                                   &Size, MEM_DECOMMIT);
                SetLastNtError(Status);
                RETURN( (BOOL) -1);
             }
@@ -1127,7 +1195,7 @@ NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
             RETURN( (BOOL) -1);
          }
       }
-      else if (! co_IntWaitMessage(hWnd, MsgFilterMin, MsgFilterMax))
+      else if (! co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax))
       {
          RETURN( (BOOL) -1);
       }
@@ -1183,7 +1251,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;
          }
       }
@@ -1239,22 +1307,79 @@ CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
    return STATUS_SUCCESS;
 }
 
+BOOL FASTCALL
+UserPostThreadMessage( DWORD idThread,
+                       UINT Msg,
+                       WPARAM wParam,
+                       LPARAM lParam)
+{
+   MSG Message;
+   PETHREAD peThread;
+   PTHREADINFO pThread;
+   LARGE_INTEGER LargeTickCount;
+   NTSTATUS Status;
+
+   DPRINT1("UserPostThreadMessage wParam 0x%x  lParam 0x%x\n", wParam,lParam);
+
+   if (FindMsgMemory(Msg) != 0)
+   {
+      SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+      return FALSE;
+   }
+
+   Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
+
+   if( Status == STATUS_SUCCESS )
+   {
+      pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
+      if( !pThread || !pThread->MessageQueue )
+      {
+         ObDereferenceObject( peThread );
+         return FALSE;
+      }
+
+      Message.hwnd = NULL;
+      Message.message = Msg;
+      Message.wParam = wParam;
+      Message.lParam = lParam;
+      IntGetCursorLocation(pThread->Desktop->WindowStation, &Message.pt);
+      KeQueryTickCount(&LargeTickCount);
+      pThread->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
+      MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
+      ObDereferenceObject( peThread );
+      return TRUE;
+   }
+   else
+   {
+      SetLastNtError( Status );
+   }
+   return FALSE;
+}
+
 BOOL FASTCALL
 UserPostMessage(HWND Wnd,
                 UINT Msg,
                 WPARAM wParam,
                 LPARAM lParam)
 {
-   MSG UserModeMsg, KernelModeMsg;
+   PTHREADINFO pti;
+   MSG Message;
    LARGE_INTEGER LargeTickCount;
-   NTSTATUS Status;
-   PMSGMEMORY MsgMemoryEntry;
 
-   if (WM_QUIT == Msg)
+   if (FindMsgMemory(Msg) != 0)
    {
-      MsqPostQuitMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, wParam);
+      SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+      return FALSE;
    }
-   else if (Wnd == HWND_BROADCAST)
+
+   if (!Wnd) 
+      return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
+                                    Msg,
+                                    wParam,
+                                    lParam);
+
+   pti = PsGetCurrentThreadWin32Thread();
+   if (Wnd == HWND_BROADCAST)
    {
       HWND *List;
       PWINDOW_OBJECT DesktopWindow;
@@ -1286,31 +1411,27 @@ UserPostMessage(HWND Wnd,
          return FALSE;
       }
 
-      UserModeMsg.hwnd = Wnd;
-      UserModeMsg.message = Msg;
-      UserModeMsg.wParam = wParam;
-      UserModeMsg.lParam = lParam;
-      MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
-      Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
-      if (! NT_SUCCESS(Status))
+      if (WM_QUIT == Msg)
       {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
-         return FALSE;
+          MsqPostQuitMessage(Window->MessageQueue, wParam);
+      }
+      else
+      {
+         Message.hwnd = Wnd;
+         Message.message = Msg;
+         Message.wParam = wParam;
+         Message.lParam = lParam;
+         IntGetCursorLocation(pti->Desktop->WindowStation, &Message.pt);
+         KeQueryTickCount(&LargeTickCount);
+         pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
+         MsqPostMessage(Window->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
       }
-      IntGetCursorLocation(PsGetCurrentThreadWin32Thread()->Desktop->WindowStation,
-                           &KernelModeMsg.pt);
-      KeQueryTickCount(&LargeTickCount);
-      KernelModeMsg.time = MsqCalculateMessageTime(&LargeTickCount);
-      MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
-                     NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
-                     QS_POSTMESSAGE);
    }
-
    return TRUE;
 }
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserPostMessage(HWND hWnd,
                   UINT Msg,
                   WPARAM wParam,
@@ -1321,7 +1442,7 @@ NtUserPostMessage(HWND hWnd,
    DPRINT("Enter NtUserPostMessage\n");
    UserEnterExclusive();
 
-   RETURN(UserPostMessage(hWnd, Msg, wParam, lParam));
+   RETURN( UserPostMessage(hWnd, Msg, wParam, lParam));
 
 CLEANUP:
    DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
@@ -1331,56 +1452,21 @@ CLEANUP:
 
 
 
-BOOL STDCALL
+BOOL APIENTRY
 NtUserPostThreadMessage(DWORD idThread,
                         UINT Msg,
                         WPARAM wParam,
                         LPARAM lParam)
 {
-   MSG UserModeMsg, KernelModeMsg;
-   PETHREAD peThread;
-   PW32THREAD pThread;
-   NTSTATUS Status;
-   PMSGMEMORY MsgMemoryEntry;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserPostThreadMessage\n");
    UserEnterExclusive();
 
-   Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
-
-   if( Status == STATUS_SUCCESS )
-   {
-      pThread = (PW32THREAD)peThread->Tcb.Win32Thread;
-      if( !pThread || !pThread->MessageQueue )
-      {
-         ObDereferenceObject( peThread );
-         RETURN( FALSE);
-      }
-
-      UserModeMsg.hwnd = NULL;
-      UserModeMsg.message = Msg;
-      UserModeMsg.wParam = wParam;
-      UserModeMsg.lParam = lParam;
-      MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
-      Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
-      if (! NT_SUCCESS(Status))
-      {
-         ObDereferenceObject( peThread );
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
-         RETURN( FALSE);
-      }
-      MsqPostMessage(pThread->MessageQueue, &KernelModeMsg,
-                     NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
-                     QS_POSTMESSAGE);
-      ObDereferenceObject( peThread );
-      RETURN( TRUE);
-   }
-   else
-   {
-      SetLastNtError( Status );
-      RETURN( FALSE);
-   }
+   RETURN( UserPostThreadMessage( idThread,
+                                  Msg,
+                                  wParam,
+                                  lParam));
 
 CLEANUP:
    DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
@@ -1388,7 +1474,7 @@ CLEANUP:
    END_CLEANUP;
 }
 
-DWORD STDCALL
+DWORD APIENTRY
 NtUserQuerySendMessage(DWORD Unknown0)
 {
    UNIMPLEMENTED;
@@ -1426,10 +1512,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 +1525,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)
    {
@@ -1480,7 +1553,7 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
           RETURN( FALSE);
       }
 
-      Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
+      Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->lpfnWndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
                lParamPacked,lParamBufferSize);
 
       if(uResult)
@@ -1488,17 +1561,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 +1594,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 +1681,7 @@ co_IntPostOrSendMessage(HWND hWnd,
                         LPARAM lParam)
 {
    ULONG_PTR Result;
+   PTHREADINFO pti;
    PWINDOW_OBJECT Window;
 
    if(hWnd == HWND_BROADCAST)
@@ -1640,7 +1694,8 @@ co_IntPostOrSendMessage(HWND hWnd,
       return 0;
    }
 
-   if(Window->MessageQueue != PsGetCurrentThreadWin32Thread()->MessageQueue)
+   pti = PsGetCurrentThreadWin32Thread();
+   if(Window->MessageQueue != pti->MessageQueue && FindMsgMemory(Msg) ==0)
    {
       Result = UserPostMessage(hWnd, Msg, wParam, lParam);
    }
@@ -1662,9 +1717,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 +1746,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,15 +1760,20 @@ 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);
+          Info.Proc = (!Info.Ansi ? Window->Wnd->lpfnWndProc : Window->Wnd->WndProcExtra);
       }
       else
       {
           Info.Ansi = !Window->Wnd->Unicode;
-          Info.Proc = Window->Wnd->WndProc;
+          Info.Proc = Window->Wnd->lpfnWndProc;
       }
+
+      IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result);
+
    }
    else
    {
@@ -1762,7 +1824,7 @@ co_IntDoSendMessage(HWND hWnd,
    return (LRESULT)Result;
 }
 
-LRESULT STDCALL
+LRESULT APIENTRY
 NtUserSendMessageTimeout(HWND hWnd,
                          UINT Msg,
                          WPARAM wParam,
@@ -1801,7 +1863,7 @@ CLEANUP:
    END_CLEANUP;
 }
 
-LRESULT STDCALL
+LRESULT APIENTRY
 NtUserSendMessage(HWND Wnd,
                   UINT Msg,
                   WPARAM wParam,
@@ -1829,6 +1891,13 @@ UserSendNotifyMessage(HWND hWnd,
                       LPARAM lParam)
 {
    BOOL Result = TRUE;
+
+   if (FindMsgMemory(Msg) != 0)
+   {
+      SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+      return FALSE;
+   }
+
    // Basicly the same as IntPostOrSendMessage
    if (hWnd == HWND_BROADCAST) //Handle Broadcast
    {
@@ -1851,70 +1920,32 @@ UserSendNotifyMessage(HWND hWnd,
    else
    {
      ULONG_PTR PResult;
+     PTHREADINFO pti;
      PWINDOW_OBJECT Window;
-     NTSTATUS Status;
-     MSG UserModeMsg;
-     MSG KernelModeMsg;
-     PMSGMEMORY MsgMemoryEntry;
+     MSG Message;
 
       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);
       }
       else
       { // Handle message and callback.
-         UserModeMsg.hwnd = hWnd;
-         UserModeMsg.message = Msg;
-         UserModeMsg.wParam = wParam;
-         UserModeMsg.lParam = lParam;
-         MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
-         Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
-         if (! NT_SUCCESS(Status))
-         {
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
-            return FALSE;
-         }
-         Result = co_IntSendMessageTimeoutSingle(
-                                   KernelModeMsg.hwnd, KernelModeMsg.message,
-                                   KernelModeMsg.wParam, KernelModeMsg.lParam,
-                                   SMTO_NORMAL, 0, &PResult);
+         Message.hwnd = hWnd;
+         Message.message = Msg;
+         Message.wParam = wParam;
+         Message.lParam = lParam;
 
-         Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
-         if (! NT_SUCCESS(Status))
-         {
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
-            return FALSE;
-         }
+         Result = co_IntSendMessageTimeoutSingle( hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &PResult);
       }
    }
    return Result;
 }
 
 
-BOOL STDCALL
-NtUserSendNotifyMessage(HWND hWnd,
-                        UINT Msg,
-                        WPARAM wParam,
-                        LPARAM lParam)
-{
-   DECLARE_RETURN(BOOL);
-
-   DPRINT("EnterNtUserSendNotifyMessage\n");
-   UserEnterExclusive();
-
-   RETURN(UserSendNotifyMessage(hWnd, Msg, wParam, lParam));
-
-CLEANUP:
-   DPRINT("Leave NtUserSendNotifyMessage, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-
-}
-
-
-BOOL STDCALL
+BOOL APIENTRY
 NtUserWaitMessage(VOID)
 {
    DECLARE_RETURN(BOOL);
@@ -1930,16 +1961,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 +1987,34 @@ CLEANUP:
    END_CLEANUP;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 IntInitMessagePumpHook()
 {
-   if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
+   if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
    {
-     ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook++;
+     ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook++;
      return TRUE;
    }
    return FALSE;
 }
 
-BOOL STDCALL
+BOOL APIENTRY
 IntUninitMessagePumpHook()
 {
-   if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
+   if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
    {
-      if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook <= 0)
+      if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook <= 0)
       {
          return FALSE;
       }
-      ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook--;
+      ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook--;
       return TRUE;
    }
    return FALSE;
 }
 
 
-LRESULT STDCALL
+BOOL APIENTRY
 NtUserMessageCall(
    HWND hWnd,
    UINT Msg,
@@ -1992,6 +2025,8 @@ NtUserMessageCall(
    BOOL Ansi)
 {
    LRESULT lResult = 0;
+   BOOL Ret = FALSE;
+   BOOL BadChk = FALSE;
    PWINDOW_OBJECT Window = NULL;
    USER_REFERENCE_ENTRY Ref;
 
@@ -2000,50 +2035,53 @@ NtUserMessageCall(
    /* Validate input */
    if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
    {
-      return 0;
-   }   
+      UserLeave();
+      return FALSE;
+   }
    switch(dwType)
    {
       case FNID_DEFWINDOWPROC:
          UserRefObjectCo(Window, &Ref);
          lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
+         Ret = TRUE;
          UserDerefObjectCo(Window);
       break;
+      case FNID_SENDNOTIFYMESSAGE:
+         Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
+      break;
       case FNID_BROADCASTSYSTEMMESSAGE:
       {
-         PBROADCASTPARM parm;
-         BOOL BadChk = FALSE;
+         BROADCASTPARM parm;
          DWORD_PTR RetVal = 0;
-         lResult = -1;
 
          if (ResultInfo)
          {
-            _SEH_TRY
+            _SEH2_TRY
             {
                ProbeForWrite((PVOID)ResultInfo,
                          sizeof(BROADCASTPARM),
-                                             1);               
-               parm = (PBROADCASTPARM)ResultInfo;
+                                             1);
+               RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
             }
-            _SEH_HANDLE
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                BadChk = TRUE;
             }
-            _SEH_END;
+            _SEH2_END;
             if (BadChk) break;
          }
          else
            break;
 
-         if ( parm->recipients & BSM_ALLDESKTOPS ||
-              parm->recipients == BSM_ALLCOMPONENTS )
+         if ( parm.recipients & BSM_ALLDESKTOPS ||
+              parm.recipients == BSM_ALLCOMPONENTS )
          {
          }
-         else if (parm->recipients & BSM_APPLICATIONS)
+         else if (parm.recipients & BSM_APPLICATIONS)
          {
-            if (parm->flags & BSF_QUERY)
+            if (parm.flags & BSF_QUERY)
             {
-               if (parm->flags & BSF_FORCEIFHUNG || parm->flags & BSF_NOHANG)
+               if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG)
                {
                   co_IntSendMessageTimeout( HWND_BROADCAST,
                                             Msg,
@@ -2053,7 +2091,7 @@ NtUserMessageCall(
                                             2000,
                                             &RetVal);
                }
-               else if (parm->flags & BSF_NOTIMEOUTIFNOTHUNG)
+               else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG)
                {
                   co_IntSendMessageTimeout( HWND_BROADCAST,
                                             Msg,
@@ -2074,13 +2112,13 @@ NtUserMessageCall(
                                             &RetVal);
                }
             }
-            else if (parm->flags & BSF_POSTMESSAGE)
+            else if (parm.flags & BSF_POSTMESSAGE)
             {
-               lResult = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
+               Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
             }
-            else if ( parm->flags & BSF_SENDNOTIFYMESSAGE)
+            else if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
             {
-               lResult = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
+               Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
             }
          }
       }
@@ -2091,11 +2129,11 @@ NtUserMessageCall(
       case FNID_CALLWNDPROC:
       case FNID_CALLWNDPROCRET:
       {
-         PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
+         PCLIENTINFO ClientInfo = GetWin32ClientInfo();
          PHOOK NextObj, Hook = ClientInfo->phkCurrent;
 
          if (!ClientInfo || !Hook) break;
-         
+
          UserReferenceObject(Hook);
 
          if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
@@ -2106,7 +2144,7 @@ NtUserMessageCall(
 
          NextObj = IntGetNextHook(Hook);
          ClientInfo->phkCurrent = NextObj;
-         
+
          if ( Hook->HookId == WH_CALLWNDPROC)
          {
             CWPSTRUCT CWP;
@@ -2115,11 +2153,11 @@ NtUserMessageCall(
             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, 
+                                         (LPARAM)&CWP,
                                           Hook->Proc,
                                           Hook->Ansi,
                                           &Hook->ModuleName);
@@ -2137,7 +2175,7 @@ NtUserMessageCall(
                                           HC_ACTION,
                                         ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
                                          (LPARAM)&CWPR,
-                                          Hook->Proc,   
+                                          Hook->Proc,
                                           Hook->Ansi,
                                           &Hook->ModuleName);
          }
@@ -2146,25 +2184,50 @@ NtUserMessageCall(
       }
       break;
    }
+
+   switch(dwType)
+   {
+      case FNID_DEFWINDOWPROC:
+      case FNID_CALLWNDPROC:
+      case FNID_CALLWNDPROCRET:
+         if (ResultInfo)
+         {
+            _SEH2_TRY
+            {
+                ProbeForWrite((PVOID)ResultInfo, sizeof(LRESULT), 1);
+                RtlCopyMemory((PVOID)ResultInfo, &lResult, sizeof(LRESULT));
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                BadChk = TRUE;
+            }
+            _SEH2_END;      
+         }
+         break;
+      default:
+         break;   
+   }
+
    UserLeave();
-   return lResult;
+
+   return BadChk ? FALSE : Ret;
 }
 
 #define INFINITE 0xFFFFFFFF
 #define WAIT_FAILED ((DWORD)0xFFFFFFFF)
 
 DWORD
-NTAPI
+APIENTRY
 NtUserWaitForInputIdle(
    IN HANDLE hProcess,
    IN DWORD dwMilliseconds,
    IN BOOL Unknown2)
 {
   PEPROCESS Process;
-  PW32PROCESS W32Process;
+  PPROCESSINFO W32Process;
   NTSTATUS Status;
   HANDLE Handles[2];
-  LARGE_INTEGER Timeout; 
+  LARGE_INTEGER Timeout;
   ULONGLONG StartTime, Run, Elapsed = 0;
 
   UserEnterExclusive();
@@ -2183,7 +2246,7 @@ NtUserWaitForInputIdle(
      return WAIT_FAILED;
   }
 
-  W32Process = (PW32PROCESS)Process->Win32Process;
+  W32Process = (PPROCESSINFO)Process->Win32Process;
   if (!W32Process)
   {
       ObDereferenceObject(Process);
@@ -2204,8 +2267,7 @@ NtUserWaitForInputIdle(
       return STATUS_SUCCESS;  /* no event to wait on */
   }
 
-  StartTime = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
-                          SharedUserData->TickCountMultiplier / 16777216);
+  StartTime = EngGetTickCount();
 
   Run = dwMilliseconds;
 
@@ -2259,9 +2321,7 @@ NtUserWaitForInputIdle(
 
      if (dwMilliseconds != INFINITE)
      {
-        Elapsed = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
-                              SharedUserData->TickCountMultiplier / 16777216) 
-                              - StartTime;
+        Elapsed = EngGetTickCount() - StartTime;
 
         if (Elapsed > Run)
            Status = STATUS_TIMEOUT;