- Update KTHREAD and KUSER_SHARED_DATA to latest versions. This should make 2K3 drive...
[reactos.git] / reactos / subsys / win32k / ntuser / message.c
index c3f4482..7e90408 100644 (file)
 
 typedef struct
 {
-  UINT uFlags;
-  UINT uTimeout;
-  ULONG_PTR Result;
-} DOSENDMESSAGE, *PDOSENDMESSAGE;
+   UINT uFlags;
+   UINT uTimeout;
+   ULONG_PTR Result;
+}
+DOSENDMESSAGE, *PDOSENDMESSAGE;
 
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS FASTCALL
 IntInitMessageImpl(VOID)
 {
-  return STATUS_SUCCESS;
+   return STATUS_SUCCESS;
 }
 
 NTSTATUS FASTCALL
 IntCleanupMessageImpl(VOID)
 {
-  return STATUS_SUCCESS;
+   return STATUS_SUCCESS;
 }
 
 #define MMS_SIZE_WPARAM      -1
@@ -63,160 +64,167 @@ IntCleanupMessageImpl(VOID)
 #define MMS_FLAG_WRITE       0x02
 #define MMS_FLAG_READWRITE   (MMS_FLAG_READ | MMS_FLAG_WRITE)
 typedef struct tagMSGMEMORY
-  {
-    UINT Message;
-    UINT Size;
-    INT Flags;
-  } MSGMEMORY, *PMSGMEMORY;
+{
+   UINT Message;
+   UINT Size;
+   INT Flags;
+}
+MSGMEMORY, *PMSGMEMORY;
 
 static MSGMEMORY MsgMemory[] =
-  {
-    { WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
-    { WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
-    { WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
-    { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
-    { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
-    { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
-    { WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
-    { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
-    { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
-    { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
-    { WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
-    { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
-    { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
-  };
+   {
+      { WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
+      { WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
+      { WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
+      { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
+      { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
+      { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
+      { WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
+      { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
+      { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
+      { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
+      { WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
+      { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
+      { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
+   };
 
 static PMSGMEMORY FASTCALL
 FindMsgMemory(UINT Msg)
-  {
-  PMSGMEMORY MsgMemoryEntry;
-
-  /* See if this message type is present in the table */
-  for (MsgMemoryEntry = MsgMemory;
-       MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
-       MsgMemoryEntry++)
-    {
+{
+   PMSGMEMORY MsgMemoryEntry;
+
+   /* See if this message type is present in the table */
+   for (MsgMemoryEntry = MsgMemory;
+         MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
+         MsgMemoryEntry++)
+   {
       if (Msg == MsgMemoryEntry->Message)
-        {
-          return MsgMemoryEntry;
-        }
-    }
+      {
+         return MsgMemoryEntry;
+      }
+   }
 
-  return NULL;
+   return NULL;
 }
 
 static UINT FASTCALL
 MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
 {
-  CREATESTRUCTW *Cs;
-  PUNICODE_STRING WindowName;
-  PUNICODE_STRING ClassName;
-  UINT Size;
+   CREATESTRUCTW *Cs;
+   PUNICODE_STRING WindowName;
+   PUNICODE_STRING ClassName;
+   UINT Size;
 
-  if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
-    {
+   _SEH_TRY {
+      if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
+   {
       return (UINT) wParam;
-    }
-  else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
-    {
+      }
+      else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
+   {
       return (UINT) (wParam * sizeof(WCHAR));
-    }
-  else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
-    {
+      }
+      else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
+   {
       return (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
-    }
-  else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
-    {
+      }
+      else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
+   {
       switch(MsgMemoryEntry->Message)
-        {
-        case WM_CREATE:
-        case WM_NCCREATE:
-          Cs = (CREATESTRUCTW *) lParam;
-          WindowName = (PUNICODE_STRING) Cs->lpszName;
-          ClassName = (PUNICODE_STRING) Cs->lpszClass;
-          Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
-          if (IS_ATOM(ClassName->Buffer))
-            {
-              Size += sizeof(WCHAR) + sizeof(ATOM);
-            }
-          else
-            {
-              Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
-            }
-          return Size;
-          break;
-
-        case WM_NCCALCSIZE:
-          return wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
-          break;
-
-        case WM_COPYDATA:
-          return sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
-
-        default:
-          assert(FALSE);
-          return 0;
-          break;
-        }
-    }
-  else
-    {
-      return MsgMemoryEntry->Size;
-    }
+         {
+            case WM_CREATE:
+            case WM_NCCREATE:
+               Cs = (CREATESTRUCTW *) lParam;
+               WindowName = (PUNICODE_STRING) Cs->lpszName;
+               ClassName = (PUNICODE_STRING) Cs->lpszClass;
+               Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
+               if (IS_ATOM(ClassName->Buffer))
+               {
+                  Size += sizeof(WCHAR) + sizeof(ATOM);
+               }
+               else
+               {
+                  Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
+               }
+               return Size;
+               break;
+
+            case WM_NCCALCSIZE:
+               return wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
+               break;
+
+            case WM_COPYDATA:
+               return sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
+
+            default:
+               assert(FALSE);
+               return 0;
+               break;
+         }
+      }
+      else
+      {
+         return MsgMemoryEntry->Size;
+      }
+   } _SEH_HANDLE {
+
+      DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH_GetExceptionCode());
+   } _SEH_END;
+   return 0;
 }
 
 static FASTCALL NTSTATUS
 PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
-  NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
-  NCCALCSIZE_PARAMS *PackedNcCalcsize;
-  CREATESTRUCTW *UnpackedCs;
-  CREATESTRUCTW *PackedCs;
-  PUNICODE_STRING WindowName;
-  PUNICODE_STRING ClassName;
-  UINT Size;
-  PCHAR CsData;
-
-  *lParamPacked = lParam;
-  if (WM_NCCALCSIZE == Msg && wParam)
-    {
+   NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
+   NCCALCSIZE_PARAMS *PackedNcCalcsize;
+   CREATESTRUCTW *UnpackedCs;
+   CREATESTRUCTW *PackedCs;
+   PUNICODE_STRING WindowName;
+   PUNICODE_STRING ClassName;
+   UINT Size;
+   PCHAR CsData;
+
+   *lParamPacked = lParam;
+   if (WM_NCCALCSIZE == Msg && wParam)
+   {
       UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
       if (UnpackedNcCalcsize->lppos != (PWINDOWPOS) (UnpackedNcCalcsize + 1))
-        {
-          PackedNcCalcsize = ExAllocatePoolWithTag(PagedPool,
-                                                   sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
-                                                   TAG_MSG);
-          if (NULL == PackedNcCalcsize)
-            {
-              DPRINT1("Not enough memory to pack lParam\n");
-              return STATUS_NO_MEMORY;
-            }
-          RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
-          PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
-          RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
-          *lParamPacked = (LPARAM) PackedNcCalcsize;
-        }
-    }
-  else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
-    {
+      {
+         PackedNcCalcsize = ExAllocatePoolWithTag(PagedPool,
+                            sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
+                            TAG_MSG);
+         if (NULL == PackedNcCalcsize)
+         {
+            DPRINT1("Not enough memory to pack lParam\n");
+            return STATUS_NO_MEMORY;
+         }
+         RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
+         PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
+         RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
+         *lParamPacked = (LPARAM) PackedNcCalcsize;
+      }
+   }
+   else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
+   {
       UnpackedCs = (CREATESTRUCTW *) lParam;
       WindowName = (PUNICODE_STRING) UnpackedCs->lpszName;
       ClassName = (PUNICODE_STRING) UnpackedCs->lpszClass;
       Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
       if (IS_ATOM(ClassName->Buffer))
-        {
-          Size += sizeof(WCHAR) + sizeof(ATOM);
-        }
+      {
+         Size += sizeof(WCHAR) + sizeof(ATOM);
+      }
       else
-        {
-          Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
-        }
+      {
+         Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
+      }
       PackedCs = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
       if (NULL == PackedCs)
-        {
-          DPRINT1("Not enough memory to pack lParam\n");
-          return STATUS_NO_MEMORY;
-        }
+      {
+         DPRINT1("Not enough memory to pack lParam\n");
+         return STATUS_NO_MEMORY;
+      }
       RtlCopyMemory(PackedCs, UnpackedCs, sizeof(CREATESTRUCTW));
       CsData = (PCHAR) (PackedCs + 1);
       PackedCs->lpszName = (LPCWSTR) (CsData - (PCHAR) PackedCs);
@@ -226,42 +234,42 @@ PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
       CsData += sizeof(WCHAR);
       PackedCs->lpszClass = (LPCWSTR) (CsData - (PCHAR) PackedCs);
       if (IS_ATOM(ClassName->Buffer))
-        {
-          *((WCHAR *) CsData) = L'A';
-          CsData += sizeof(WCHAR);
-          *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
-          CsData += sizeof(ATOM);
-        }
+      {
+         *((WCHAR *) CsData) = L'A';
+         CsData += sizeof(WCHAR);
+         *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
+         CsData += sizeof(ATOM);
+      }
       else
-        {
-          *((WCHAR *) CsData) = L'S';
-          CsData += sizeof(WCHAR);
-          RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
-          CsData += ClassName->Length;
-          *((WCHAR *) CsData) = L'\0';
-          CsData += sizeof(WCHAR);
-        }
+      {
+         *((WCHAR *) CsData) = L'S';
+         CsData += sizeof(WCHAR);
+         RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
+         CsData += ClassName->Length;
+         *((WCHAR *) CsData) = L'\0';
+         CsData += sizeof(WCHAR);
+      }
       ASSERT(CsData == (PCHAR) PackedCs + Size);
       *lParamPacked = (LPARAM) PackedCs;
-    }
+   }
 
-  return STATUS_SUCCESS;
+   return STATUS_SUCCESS;
 }
 
 static FASTCALL NTSTATUS
 UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
-  NCCALCSIZE_PARAMS *UnpackedParams;
-  NCCALCSIZE_PARAMS *PackedParams;
-  PWINDOWPOS UnpackedWindowPos;
+   NCCALCSIZE_PARAMS *UnpackedParams;
+   NCCALCSIZE_PARAMS *PackedParams;
+   PWINDOWPOS UnpackedWindowPos;
 
-  if (lParamPacked == lParam)
-    {
+   if (lParamPacked == lParam)
+   {
       return STATUS_SUCCESS;
-    }
+   }
 
-  if (WM_NCCALCSIZE == Msg && wParam)
-    {
+   if (WM_NCCALCSIZE == Msg && wParam)
+   {
       PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
       UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
       UnpackedWindowPos = UnpackedParams->lppos;
@@ -271,38 +279,61 @@ UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
       ExFreePool((PVOID) lParamPacked);
 
       return STATUS_SUCCESS;
-    }
-  else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
-    {
+   }
+   else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
+   {
       ExFreePool((PVOID) lParamPacked);
 
       return STATUS_SUCCESS;
-    }
+   }
 
-  ASSERT(FALSE);
+   ASSERT(FALSE);
 
-  return STATUS_INVALID_PARAMETER;
+   return STATUS_INVALID_PARAMETER;
 }
 
+BOOL
+STDCALL
+NtUserCallMsgFilter(
+   LPMSG msg,
+   INT code)
+{
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserCallMsgFilter\n");
+   UserEnterExclusive();
+
+   if (co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg))
+      RETURN( TRUE);
+   RETURN( co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg));
+
+CLEANUP:
+   DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
+   UserLeave();
+   END_CLEANUP;
+}
 
 LRESULT STDCALL
 NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
 {
-  NTSTATUS Status;
-  NTUSERDISPATCHMESSAGEINFO MsgInfo;
-  PWINDOW_OBJECT WindowObject;
-  LRESULT Result = TRUE;
-
-  Status = MmCopyFromCaller(&MsgInfo, UnsafeMsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
-  if (! NT_SUCCESS(Status))
-    {
+   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;
-    }
+      RETURN( 0);
+   }
 
-  /* Process timer messages. */
-  if (WM_TIMER == MsgInfo.Msg.message && 0 != MsgInfo.Msg.lParam)
-    {
+   /* Process timer messages. */
+   if (WM_TIMER == MsgInfo.Msg.message && 0 != MsgInfo.Msg.lParam)
+   {
       LARGE_INTEGER LargeTickCount;
       /* FIXME: Call hooks. */
 
@@ -312,283 +343,311 @@ NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
       KeQueryTickCount(&LargeTickCount);
       MsgInfo.Proc = (WNDPROC) MsgInfo.Msg.lParam;
       MsgInfo.Msg.lParam = (LPARAM)LargeTickCount.u.LowPart;
-    }
-  else if (NULL == MsgInfo.Msg.hwnd)
-    {
+   }
+   else if (NULL == MsgInfo.Msg.hwnd)
+   {
       MsgInfo.HandledByKernel = TRUE;
       Result = 0;
-    }
-  else
-    {
+   }
+   else
+   {
+      PWINDOW_OBJECT Window;
+      
       /* Get the window object. */
-      WindowObject = IntGetWindowObject(MsgInfo.Msg.hwnd);
-      if (NULL == WindowObject)
-        {
-          SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-          MsgInfo.HandledByKernel = TRUE;
-          Result = 0;
-        }
+      Window = UserGetWindowObject(MsgInfo.Msg.hwnd);
+      if (NULL == Window)
+      {
+         MsgInfo.HandledByKernel = TRUE;
+         Result = 0;
+      }
       else
-        {
-          if (WindowObject->OwnerThread != PsGetCurrentThread())
+      {
+         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 (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
             {
-              IntReleaseWindowObject(WindowObject);
-              DPRINT1("Window doesn't belong to the calling thread!\n");
-              MsgInfo.HandledByKernel = TRUE;
-              Result = 0;
+               if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000))
+               {
+                  /* Both Unicode and Ansi winprocs are real, use whatever
+                     usermode prefers */
+                  MsgInfo.Proc = (MsgInfo.Ansi ? Window->WndProcA
+                                  : Window->WndProcW);
+               }
+               else
+               {
+                  /* Real Unicode winproc */
+                  MsgInfo.Ansi = FALSE;
+                  MsgInfo.Proc = Window->WndProcW;
+               }
             }
-          else
+            else
             {
-              /* FIXME: Call hook procedures. */
-
-              MsgInfo.HandledByKernel = FALSE;
-              Result = 0;
-              if (0xFFFF0000 != ((DWORD) WindowObject->WndProcW & 0xFFFF0000))
-                {
-                  if (0xFFFF0000 != ((DWORD) WindowObject->WndProcA & 0xFFFF0000))
-                    {
-                      /* Both Unicode and Ansi winprocs are real, use whatever
-                         usermode prefers */
-                      MsgInfo.Proc = (MsgInfo.Ansi ? WindowObject->WndProcA
-                                      : WindowObject->WndProcW);
-                    }
-                  else
-                    {
-                      /* Real Unicode winproc */
-                      MsgInfo.Ansi = FALSE;
-                      MsgInfo.Proc = WindowObject->WndProcW;
-                    }
-                }
-              else
-                {
-                  /* Must have real Ansi winproc */
-                  MsgInfo.Ansi = TRUE;
-                  MsgInfo.Proc = WindowObject->WndProcA;
-                }
+               /* Must have real Ansi winproc */
+               MsgInfo.Ansi = TRUE;
+               MsgInfo.Proc = Window->WndProcA;
             }
-          IntReleaseWindowObject(WindowObject);
-        }
-    }
-  Status = MmCopyToCaller(UnsafeMsgInfo, &MsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
-  if (! NT_SUCCESS(Status))
-    {
+         }
+      }
+   }
+   Status = MmCopyToCaller(UnsafeMsgInfo, &MsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
+   if (! NT_SUCCESS(Status))
+   {
       SetLastNtError(Status);
-      return 0;
-    }
-  
-  return Result;
+      RETURN( 0);
+   }
+
+   RETURN( Result);
+
+CLEANUP:
+   DPRINT("Leave NtUserDispatchMessage. ret=%i\n", _ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
 BOOL STDCALL
 NtUserTranslateMessage(LPMSG lpMsg,
-                      HKL dwhkl)
+                       HKL dwhkl)
 {
-  NTSTATUS Status;
-  MSG SafeMsg;
+   NTSTATUS Status;
+   MSG SafeMsg;
+   DECLARE_RETURN(BOOL);
 
-  Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastNtError(Status);
-    return FALSE;
-  }
+   DPRINT("Enter NtUserTranslateMessage\n");
+   UserEnterExclusive();
 
-  return IntTranslateKbdMessage(&SafeMsg, dwhkl);
+   Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
+   if(!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN( FALSE);
+   }
+
+   RETURN( IntTranslateKbdMessage(&SafeMsg, dwhkl));
+
+CLEANUP:
+   DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 
 VOID FASTCALL
-IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
+co_IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
 {
-  if(!Msg->hwnd || ThreadQueue->CaptureWindow)
-  {
-    return;
-  }
-  
-  switch(Msg->message)
-  {
-    case WM_MOUSEMOVE:
-    {
-      IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
-      break;
-    }
-    case WM_NCMOUSEMOVE:
-    {
-      IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
-      break;
-    }
-    case WM_LBUTTONDOWN:
-    case WM_MBUTTONDOWN:
-    case WM_RBUTTONDOWN:
-    case WM_XBUTTONDOWN:
-    case WM_LBUTTONDBLCLK:
-    case WM_MBUTTONDBLCLK:
-    case WM_RBUTTONDBLCLK:
-    case WM_XBUTTONDBLCLK:
-    {
-      WPARAM wParam;
-      PSYSTEM_CURSORINFO CurInfo;
-      
-      if(!IntGetWindowStationObject(InputWindowStation))
-      {
-        break;
-      }
-      CurInfo = IntGetSysCursorInfo(InputWindowStation);
-      wParam = (WPARAM)(CurInfo->ButtonsDown);
-      ObDereferenceObject(InputWindowStation);
-      
-      IntSendMessage(Msg->hwnd, WM_MOUSEMOVE, wParam, Msg->lParam);
-      IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
-      break;
-    }
-    case WM_NCLBUTTONDOWN:
-    case WM_NCMBUTTONDOWN:
-    case WM_NCRBUTTONDOWN:
-    case WM_NCXBUTTONDOWN:
-    case WM_NCLBUTTONDBLCLK:
-    case WM_NCMBUTTONDBLCLK:
-    case WM_NCRBUTTONDBLCLK:
-    case WM_NCXBUTTONDBLCLK:
-    {
-      IntSendMessage(Msg->hwnd, WM_NCMOUSEMOVE, (WPARAM)Msg->wParam, Msg->lParam);
-      IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
-      break;
-    }
-  }
+   if(!Msg->hwnd || ThreadQueue->CaptureWindow)
+   {
+      return;
+   }
+
+   switch(Msg->message)
+   {
+      case WM_MOUSEMOVE:
+         {
+            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
+            break;
+         }
+      case WM_NCMOUSEMOVE:
+         {
+            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
+            break;
+         }
+      case WM_LBUTTONDOWN:
+      case WM_MBUTTONDOWN:
+      case WM_RBUTTONDOWN:
+      case WM_XBUTTONDOWN:
+      case WM_LBUTTONDBLCLK:
+      case WM_MBUTTONDBLCLK:
+      case WM_RBUTTONDBLCLK:
+      case WM_XBUTTONDBLCLK:
+         {
+            WPARAM wParam;
+            PSYSTEM_CURSORINFO CurInfo;
+
+            if(!IntGetWindowStationObject(InputWindowStation))
+            {
+               break;
+            }
+            CurInfo = IntGetSysCursorInfo(InputWindowStation);
+            wParam = (WPARAM)(CurInfo->ButtonsDown);
+            ObDereferenceObject(InputWindowStation);
+
+            co_IntSendMessage(Msg->hwnd, WM_MOUSEMOVE, wParam, Msg->lParam);
+            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
+            break;
+         }
+      case WM_NCLBUTTONDOWN:
+      case WM_NCMBUTTONDOWN:
+      case WM_NCRBUTTONDOWN:
+      case WM_NCXBUTTONDOWN:
+      case WM_NCLBUTTONDBLCLK:
+      case WM_NCMBUTTONDBLCLK:
+      case WM_NCRBUTTONDBLCLK:
+      case WM_NCXBUTTONDBLCLK:
+         {
+            co_IntSendMessage(Msg->hwnd, WM_NCMOUSEMOVE, (WPARAM)Msg->wParam, Msg->lParam);
+            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
+            break;
+         }
+   }
 }
 
 BOOL FASTCALL
-IntActivateWindowMouse(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, PWINDOW_OBJECT MsgWindow, 
-                       USHORT *HitTest)
+co_IntActivateWindowMouse(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, PWINDOW_OBJECT MsgWindow,
+                          USHORT *HitTest)
 {
-  ULONG Result;
-  
-  if(*HitTest == (USHORT)HTTRANSPARENT)
-  {
-    /* eat the message, search again! */
-    return TRUE;
-  }
-  
-  Result = IntSendMessage(MsgWindow->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(MsgWindow->Self), (LPARAM)MAKELONG(*HitTest, Msg->message));
-  switch (Result)
-  {
-    case MA_NOACTIVATEANDEAT:
-      return TRUE;
-    case MA_NOACTIVATE:
-      break;
-    case MA_ACTIVATEANDEAT:
-      IntMouseActivateWindow(MsgWindow);
+   ULONG Result;
+   PWINDOW_OBJECT Parent;
+
+   ASSERT_REFS_CO(MsgWindow);
+
+   if(*HitTest == (USHORT)HTTRANSPARENT)
+   {
+      /* eat the message, search again! */
       return TRUE;
-    default:
-      /* MA_ACTIVATE */
-      IntMouseActivateWindow(MsgWindow);
-      break;
-  }
-  
-  return FALSE;
+   }
+
+   Parent = IntGetParent(MsgWindow);//fixme: deref retval?
+   /* fixme: abort if no parent ? */
+   Result = co_IntSendMessage(MsgWindow->hSelf,
+                              WM_MOUSEACTIVATE,
+                              (WPARAM) (Parent ? Parent->hSelf : NULL),
+                              (LPARAM)MAKELONG(*HitTest, Msg->message)
+                             );
+
+   switch (Result)
+   {
+      case MA_NOACTIVATEANDEAT:
+         return TRUE;
+      case MA_NOACTIVATE:
+         break;
+      case MA_ACTIVATEANDEAT:
+         co_IntMouseActivateWindow(MsgWindow);
+         return TRUE;
+      default:
+         /* MA_ACTIVATE */
+         co_IntMouseActivateWindow(MsgWindow);
+         break;
+   }
+
+   return FALSE;
 }
 
 BOOL FASTCALL
-IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *HitTest, BOOL Remove)
+co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *HitTest, BOOL Remove)
 {
-  PWINDOW_OBJECT Window;
-  
-  if(!(Window = IntGetWindowObject(Msg->hwnd)))
-  {
-    /* let's just eat the message?! */
-    return TRUE;
-  }
-  
-  if(ThreadQueue == Window->MessageQueue &&
-     ThreadQueue->CaptureWindow != Window->Self)
-  {
-    /* only send WM_NCHITTEST messages if we're not capturing the window! */
-    *HitTest = IntSendMessage(Window->Self, WM_NCHITTEST, 0, 
-                              MAKELONG(Msg->pt.x, Msg->pt.y));
-    
-    if(*HitTest == (USHORT)HTTRANSPARENT)
-    {
-      PWINDOW_OBJECT DesktopWindow;
-      HWND hDesktop = IntGetDesktopWindow();
-      
-      if((DesktopWindow = IntGetWindowObject(hDesktop)))
+   PWINDOW_OBJECT Window;
+   USER_REFERENCE_ENTRY Ref, DesktopRef;
+
+   if(!(Window = UserGetWindowObject(Msg->hwnd)))
+   {
+      /* let's just eat the message?! */
+      return TRUE;
+   }
+
+   UserRefObjectCo(Window, &Ref);
+
+   if(ThreadQueue == Window->MessageQueue &&
+         ThreadQueue->CaptureWindow != Window->hSelf)
+   {
+      /* only send WM_NCHITTEST messages if we're not capturing the window! */
+      *HitTest = co_IntSendMessage(Window->hSelf, WM_NCHITTEST, 0,
+                                   MAKELONG(Msg->pt.x, Msg->pt.y));
+
+      if(*HitTest == (USHORT)HTTRANSPARENT)
       {
-        PWINDOW_OBJECT Wnd;
-        
-        WinPosWindowFromPoint(DesktopWindow, Window->MessageQueue, &Msg->pt, &Wnd);
-        if(Wnd)
-        {
-          if(Wnd != Window)
-          {
-            /* post the message to the other window */
-            Msg->hwnd = Wnd->Self;
-            if(!(Wnd->Status & WINDOWSTATUS_DESTROYING))
+         PWINDOW_OBJECT DesktopWindow;
+         HWND hDesktop = IntGetDesktopWindow();
+
+         if((DesktopWindow = UserGetWindowObject(hDesktop)))
+         {
+            PWINDOW_OBJECT Wnd;
+            
+            UserRefObjectCo(DesktopWindow, &DesktopRef);
+            
+            co_WinPosWindowFromPoint(DesktopWindow, Window->MessageQueue, &Msg->pt, &Wnd);
+            if(Wnd)
             {
-              MsqPostMessage(Wnd->MessageQueue, Msg, FALSE,
-                             Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
-                             QS_MOUSEBUTTON);
+               if(Wnd != Window)
+               {
+                  /* post the message to the other window */
+                  Msg->hwnd = Wnd->hSelf;
+                  if(!(Wnd->Status & WINDOWSTATUS_DESTROYING))
+                  {
+                     MsqPostMessage(Wnd->MessageQueue, Msg, FALSE,
+                                    Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
+                                    QS_MOUSEBUTTON);
+                  }
+
+                  /* eat the message */
+                  UserDerefObject(Wnd);
+                  UserDerefObjectCo(DesktopWindow);
+                  UserDerefObjectCo(Window);
+                  return TRUE;
+               }
+               UserDerefObject(Wnd);
             }
-            
-            /* eat the message */
-            IntReleaseWindowObject(Wnd);
-            IntReleaseWindowObject(Window);
-            IntReleaseWindowObject(DesktopWindow);
-            return TRUE;
-          }
-         IntReleaseWindowObject(Wnd); 
-        }
-        
-        IntReleaseWindowObject(DesktopWindow);
+
+            UserDerefObjectCo(DesktopWindow);
+         }
       }
-    }
-  }
-  else
-  {
-    *HitTest = HTCLIENT;
-  }
-  
-  if(IS_BTN_MESSAGE(Msg->message, DOWN))
-  {
-    /* generate double click messages, if necessary */
-    if ((((*HitTest) != HTCLIENT) || 
-        (IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) &&
-        MsqIsDblClk(Msg, Remove))
-    {
-      Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
-    }
-  }
-  
-  if(Msg->message != WM_MOUSEWHEEL)
-  {
-    
-    if ((*HitTest) != HTCLIENT)
-    {
-      Msg->message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
-      if((Msg->message == WM_NCRBUTTONUP) && 
-         (((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)))
+   }
+   else
+   {
+      *HitTest = HTCLIENT;
+   }
+
+   if(IS_BTN_MESSAGE(Msg->message, DOWN))
+   {
+      /* generate double click messages, if necessary */
+      if ((((*HitTest) != HTCLIENT) ||
+            (IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) &&
+            MsqIsDblClk(Msg, Remove))
       {
-        Msg->message = WM_CONTEXTMENU;
-        Msg->wParam = (WPARAM)Window->Self;
+         Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
       }
-      else
+   }
+
+   if(Msg->message != WM_MOUSEWHEEL)
+   {
+
+      if ((*HitTest) != HTCLIENT)
       {
-        Msg->wParam = *HitTest;
+         Msg->message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
+         if((Msg->message == WM_NCRBUTTONUP) &&
+               (((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)))
+         {
+            Msg->message = WM_CONTEXTMENU;
+            Msg->wParam = (WPARAM)Window->hSelf;
+         }
+         else
+         {
+            Msg->wParam = *HitTest;
+         }
+         Msg->lParam = MAKELONG(Msg->pt.x, Msg->pt.y);
       }
-      Msg->lParam = MAKELONG(Msg->pt.x, Msg->pt.y);
-    }
-    else if(ThreadQueue->MoveSize == NULL &&
-            ThreadQueue->MenuOwner == NULL)
-    {
-      /* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
-      Msg->lParam = MAKELONG(
-        Msg->pt.x - (WORD)Window->ClientRect.left,
-        Msg->pt.y - (WORD)Window->ClientRect.top);
-    }
-  }
-  
-  IntReleaseWindowObject(Window);
-  return FALSE;
+      else if(ThreadQueue->MoveSize == NULL &&
+              ThreadQueue->MenuOwner == NULL)
+      {
+         /* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
+         Msg->lParam = MAKELONG(
+                          Msg->pt.x - (WORD)Window->ClientRect.left,
+                          Msg->pt.y - (WORD)Window->ClientRect.top);
+      }
+   }
+
+   UserDerefObjectCo(Window);
+   return FALSE;
 }
 
 
@@ -596,293 +655,305 @@ IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *Hit
  * Internal version of PeekMessage() doing all the work
  */
 BOOL FASTCALL
-IntPeekMessage(PUSER_MESSAGE Msg,
-                HWND Wnd,
-                UINT MsgFilterMin,
-                UINT MsgFilterMax,
-                UINT RemoveMsg)
+co_IntPeekMessage(PUSER_MESSAGE Msg,
+                  HWND hWnd,
+                  UINT MsgFilterMin,
+                  UINT MsgFilterMax,
+                  UINT RemoveMsg)
 {
-  LARGE_INTEGER LargeTickCount;
-  PUSER_MESSAGE_QUEUE ThreadQueue;
-  PUSER_MESSAGE Message;
-  BOOL Present, RemoveMessages;
-
-  /* The queues and order in which they are checked are documented in the MSDN
-     article on GetMessage() */
-
-  ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
-
-  /* Inspect RemoveMsg flags */
-  /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
-  RemoveMessages = RemoveMsg & PM_REMOVE;
-  
-  CheckMessages:
-  
-  Present = FALSE;
-  
-  KeQueryTickCount(&LargeTickCount);
-  ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
-
-  /* Dispatch sent messages here. */
-  while (MsqDispatchOneSentMessage(ThreadQueue));
-      
-  /* Now look for a quit message. */
-  
-  if (ThreadQueue->QuitPosted)
-  {
-    /* According to the PSDK, WM_QUIT messages are always returned, regardless
-       of the filter specified */
-    Msg->Msg.hwnd = NULL;
-    Msg->Msg.message = WM_QUIT;
-    Msg->Msg.wParam = ThreadQueue->QuitExitCode;
-    Msg->Msg.lParam = 0;
-    Msg->FreeLParam = FALSE;
-    if (RemoveMessages)
-    {
-      ThreadQueue->QuitPosted = FALSE;
-    }
-    return TRUE;
-  }
-
-  /* Now check for normal messages. */
-  Present = MsqFindMessage(ThreadQueue,
-                           FALSE,
-                           RemoveMessages,
-                           Wnd,
-                           MsgFilterMin,
-                           MsgFilterMax,
-                           &Message);
-  if (Present)
-  {
-    RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
-    if (RemoveMessages)
-    {
-      MsqDestroyMessage(Message);
-    }
-    goto MessageFound;
-  }
-  
-  /* Check for hardware events. */
-  Present = MsqFindMessage(ThreadQueue,
-                           TRUE,
-                           RemoveMessages,
-                           Wnd,
-                           MsgFilterMin,
-                           MsgFilterMax,
-                           &Message);
-  if (Present)
-  {
-    RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
-    if (RemoveMessages)
-    {
-      MsqDestroyMessage(Message);
-    }
-    goto MessageFound;
-  }
-  
-  /* Check for sent messages again. */
-  while (MsqDispatchOneSentMessage(ThreadQueue));
-
-  /* Check for paint messages. */
-  if (IntGetPaintMessage(Wnd, MsgFilterMin, MsgFilterMax, PsGetWin32Thread(), &Msg->Msg, RemoveMessages))
-  {
-    Msg->FreeLParam = FALSE;
-    return TRUE;
-  }
-  
-  /* Check for WM_(SYS)TIMER messages */
-  Present = MsqGetTimerMessage(ThreadQueue, Wnd, MsgFilterMin, MsgFilterMax,
-                               &Msg->Msg, RemoveMessages);
-  if (Present)
-  {
-    Msg->FreeLParam = FALSE;
-    goto MessageFound;
-  }
-  
-  if(Present)
-  {
-    MessageFound:
-    
-    if(RemoveMessages)
-    {
-      PWINDOW_OBJECT MsgWindow = NULL;;
-      
-      if(Msg->Msg.hwnd && (MsgWindow = IntGetWindowObject(Msg->Msg.hwnd)) &&
-         Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST)
+   LARGE_INTEGER LargeTickCount;
+   PUSER_MESSAGE_QUEUE ThreadQueue;
+   PUSER_MESSAGE Message;
+   BOOL Present, RemoveMessages;
+   USER_REFERENCE_ENTRY Ref;
+
+   /* The queues and order in which they are checked are documented in the MSDN
+      article on GetMessage() */
+
+   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
+
+   /* Inspect RemoveMsg flags */
+   /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
+   RemoveMessages = RemoveMsg & PM_REMOVE;
+
+CheckMessages:
+
+   Present = FALSE;
+
+   KeQueryTickCount(&LargeTickCount);
+   ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
+
+   /* Dispatch sent messages here. */
+   while (co_MsqDispatchOneSentMessage(ThreadQueue))
+      ;
+
+   /* Now look for a quit message. */
+
+   if (ThreadQueue->QuitPosted)
+   {
+      /* According to the PSDK, WM_QUIT messages are always returned, regardless
+         of the filter specified */
+      Msg->Msg.hwnd = NULL;
+      Msg->Msg.message = WM_QUIT;
+      Msg->Msg.wParam = ThreadQueue->QuitExitCode;
+      Msg->Msg.lParam = 0;
+      Msg->FreeLParam = FALSE;
+      if (RemoveMessages)
       {
-        USHORT HitTest;
-        
-        if(IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, TRUE))
-          /* FIXME - check message filter again, if the message doesn't match anymore,
-                     search again */
-        {
-          IntReleaseWindowObject(MsgWindow);
-          /* eat the message, search again */
-          goto CheckMessages;
-        }
-        if(ThreadQueue->CaptureWindow == NULL)
-        {
-          IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
-          if((Msg->Msg.message != WM_MOUSEMOVE && Msg->Msg.message != WM_NCMOUSEMOVE) &&
-             IS_BTN_MESSAGE(Msg->Msg.message, DOWN) &&
-             IntActivateWindowMouse(ThreadQueue, &Msg->Msg, MsgWindow, &HitTest))
-          {
-            IntReleaseWindowObject(MsgWindow);
-            /* eat the message, search again */
-            goto CheckMessages;
-          }
-        }
+         ThreadQueue->QuitPosted = FALSE;
       }
-      else
+      return TRUE;
+   }
+
+   /* Now check for normal messages. */
+   Present = co_MsqFindMessage(ThreadQueue,
+                               FALSE,
+                               RemoveMessages,
+                               hWnd,
+                               MsgFilterMin,
+                               MsgFilterMax,
+                               &Message);
+   if (Present)
+   {
+      RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
+      if (RemoveMessages)
       {
-        IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
+         MsqDestroyMessage(Message);
       }
-      
-      if(MsgWindow)
+      goto MessageFound;
+   }
+
+   /* Check for hardware events. */
+   Present = co_MsqFindMessage(ThreadQueue,
+                               TRUE,
+                               RemoveMessages,
+                               hWnd,
+                               MsgFilterMin,
+                               MsgFilterMax,
+                               &Message);
+   if (Present)
+   {
+      RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
+      if (RemoveMessages)
       {
-        IntReleaseWindowObject(MsgWindow);
+         MsqDestroyMessage(Message);
       }
-      
+      goto MessageFound;
+   }
+
+   /* Check for sent messages again. */
+   while (co_MsqDispatchOneSentMessage(ThreadQueue))
+      ;
+
+   /* Check for paint messages. */
+   if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, PsGetWin32Thread(), &Msg->Msg, RemoveMessages))
+   {
+      Msg->FreeLParam = FALSE;
       return TRUE;
-    }
-    
-    USHORT HitTest;
-    if((Msg->Msg.hwnd && Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST) &&
-       IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, FALSE))
-      /* FIXME - check message filter again, if the message doesn't match anymore,
-                 search again */
-    {
-      /* eat the message, search again */
-      goto CheckMessages;
-    }
-    
-    return TRUE;
-  }
-
-  return Present;
+   }
+
+   /* Check for WM_(SYS)TIMER messages */
+   Present = MsqGetTimerMessage(ThreadQueue, hWnd, MsgFilterMin, MsgFilterMax,
+                                &Msg->Msg, RemoveMessages);
+   if (Present)
+   {
+      Msg->FreeLParam = FALSE;
+      goto MessageFound;
+   }
+
+   if(Present)
+   {
+MessageFound:
+
+      if(RemoveMessages)
+      {
+         PWINDOW_OBJECT MsgWindow = NULL;
+
+         if(Msg->Msg.hwnd && (MsgWindow = UserGetWindowObject(Msg->Msg.hwnd)) &&
+               Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST)
+         {
+            USHORT HitTest;
+
+            UserRefObjectCo(MsgWindow, &Ref);
+
+            if(co_IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, TRUE))
+               /* FIXME - check message filter again, if the message doesn't match anymore,
+                          search again */
+            {
+               UserDerefObjectCo(MsgWindow);
+               /* eat the message, search again */
+               goto CheckMessages;
+            }
+
+            if(ThreadQueue->CaptureWindow == NULL)
+            {
+               co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
+               if((Msg->Msg.message != WM_MOUSEMOVE && Msg->Msg.message != WM_NCMOUSEMOVE) &&
+                     IS_BTN_MESSAGE(Msg->Msg.message, DOWN) &&
+                     co_IntActivateWindowMouse(ThreadQueue, &Msg->Msg, MsgWindow, &HitTest))
+               {
+                  UserDerefObjectCo(MsgWindow);
+                  /* eat the message, search again */
+                  goto CheckMessages;
+               }
+            }
+            
+            UserDerefObjectCo(MsgWindow);
+         }
+         else
+         {
+            co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
+         }
+
+//         if(MsgWindow)
+//         {
+//            UserDerefObject(MsgWindow);
+//         }
+
+         return TRUE;
+      }
+
+      USHORT HitTest;
+      if((Msg->Msg.hwnd && Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST) &&
+            co_IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, FALSE))
+         /* FIXME - check message filter again, if the message doesn't match anymore,
+                    search again */
+      {
+         /* eat the message, search again */
+         goto CheckMessages;
+      }
+
+      return TRUE;
+   }
+
+   return Present;
 }
 
 BOOL STDCALL
 NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
-                  HWND Wnd,
+                  HWND hWnd,
                   UINT MsgFilterMin,
                   UINT MsgFilterMax,
                   UINT RemoveMsg)
 {
-  NTSTATUS Status;
-  BOOL Present;
-  NTUSERGETMESSAGEINFO Info;
-  PWINDOW_OBJECT Window;
-  PMSGMEMORY MsgMemoryEntry;
-  PVOID UserMem;
-  UINT Size;
-  USER_MESSAGE Msg;
-
-  /* Validate input */
-  if (NULL != Wnd)
-    {
-      Window = IntGetWindowObject(Wnd);
-      if (NULL == Window)
-        {
-          Wnd = NULL;
-        }
-      else
-        {
-          IntReleaseWindowObject(Window);
-        }
-    }
+   NTSTATUS Status;
+   BOOL Present;
+   NTUSERGETMESSAGEINFO Info;
+   PWINDOW_OBJECT Window;
+   PMSGMEMORY MsgMemoryEntry;
+   PVOID UserMem;
+   UINT Size;
+   USER_MESSAGE Msg;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserPeekMessage\n");
+   UserEnterExclusive();
+
+   /* Validate input */
+   if (hWnd && hWnd != INVALID_HANDLE_VALUE)
+   {
+      if (!(Window = UserGetWindowObject(hWnd)))
+      {
+         RETURN(-1);
+      }
+   }
 
-  if (MsgFilterMax < MsgFilterMin)
-    {
+   if (MsgFilterMax < MsgFilterMin)
+   {
       MsgFilterMin = 0;
       MsgFilterMax = 0;
-    }
+   }
 
-  Present = IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
-  if (Present)
-    {
+   Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
+   if (Present)
+   {
       Info.Msg = Msg.Msg;
       /* See if this message type is present in the table */
       MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
       if (NULL == MsgMemoryEntry)
-        {
-          /* Not present, no copying needed */
-          Info.LParamSize = 0;
-        }
+      {
+         /* Not present, no copying needed */
+         Info.LParamSize = 0;
+      }
       else
-        {
-          /* Determine required size */
-          Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
-                               Info.Msg.lParam);
-          /* Allocate required amount of user-mode memory */
-          Info.LParamSize = Size;
-          UserMem = NULL;
-          Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
-                                           &Info.LParamSize, 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);
-          if (! NT_SUCCESS(Status))
-            {
-              ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
-                                  &Info.LParamSize, MEM_DECOMMIT);
-              SetLastNtError(Status);
-              return (BOOL) -1;
-            }
-          Info.Msg.lParam = (LPARAM) UserMem;
-        }
-      if (Msg.FreeLParam && 0 != Msg.Msg.lParam)
-        {
-          ExFreePool((void *) Msg.Msg.lParam);
-        }
+      {
+         /* Determine required size */
+         Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
+                              Info.Msg.lParam);
+         /* Allocate required amount of user-mode memory */
+         Info.LParamSize = Size;
+         UserMem = NULL;
+         Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
+                                          &Info.LParamSize, 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);
+         if (! NT_SUCCESS(Status))
+         {
+            ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
+                                &Info.LParamSize, MEM_DECOMMIT);
+            SetLastNtError(Status);
+            RETURN( (BOOL) -1);
+         }
+         Info.Msg.lParam = (LPARAM) UserMem;
+      }
+      if (RemoveMsg && Msg.FreeLParam && 0 != Msg.Msg.lParam)
+      {
+         ExFreePool((void *) Msg.Msg.lParam);
+      }
       Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
       if (! NT_SUCCESS(Status))
-        {
-          SetLastNtError(Status);
-          return (BOOL) -1;
-        }
-    }
+      {
+         SetLastNtError(Status);
+         RETURN( (BOOL) -1);
+      }
+   }
+
+   RETURN( Present);
 
-  return Present;
+CLEANUP:
+   DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 static BOOL FASTCALL
-IntWaitMessage(HWND Wnd,
-               UINT MsgFilterMin,
-               UINT MsgFilterMax)
+co_IntWaitMessage(HWND Wnd,
+                  UINT MsgFilterMin,
+                  UINT MsgFilterMax)
 {
-  PUSER_MESSAGE_QUEUE ThreadQueue;
-  NTSTATUS Status;
-  USER_MESSAGE Msg;
+   PUSER_MESSAGE_QUEUE ThreadQueue;
+   NTSTATUS Status;
+   USER_MESSAGE Msg;
 
-  ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
+   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
 
-  do
-    {
-      if (IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
-       {
-         return TRUE;
-       }
+   do
+   {
+      if (co_IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
+      {
+         return TRUE;
+      }
 
       /* Nothing found. Wait for new messages. */
-      Status = MsqWaitForNewMessages(ThreadQueue, Wnd, MsgFilterMin, MsgFilterMax);
-    }
-  while ((STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) || STATUS_TIMEOUT == Status);
+      Status = co_MsqWaitForNewMessages(ThreadQueue, Wnd, MsgFilterMin, MsgFilterMax);
+   }
+   while ((STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) || STATUS_TIMEOUT == Status);
 
-  SetLastNtError(Status);
+   SetLastNtError(Status);
 
-  return FALSE;
+   return FALSE;
 }
 
 BOOL STDCALL
 NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
-                HWND Wnd,
-                UINT MsgFilterMin,
-                UINT MsgFilterMax)
+                 HWND hWnd,
+                 UINT MsgFilterMin,
+                 UINT MsgFilterMax)
 /*
  * FUNCTION: Get a message from the calling thread's message queue.
  * ARGUMENTS:
@@ -894,248 +965,257 @@ NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
  *                     retrieved.
  */
 {
-  BOOL GotMessage;
-  NTUSERGETMESSAGEINFO Info;
-  NTSTATUS Status;
-  PWINDOW_OBJECT Window;
-  PMSGMEMORY MsgMemoryEntry;
-  PVOID UserMem;
-  UINT Size;
-  USER_MESSAGE Msg;
-
-  /* Validate input */
-  if (NULL != Wnd)
-    {
-      Window = IntGetWindowObject(Wnd);
-      if(!Window)
-        Wnd = NULL;
-      else
-        IntReleaseWindowObject(Window);
-    }
-  if (MsgFilterMax < MsgFilterMin)
-    {
+   BOOL GotMessage;
+   NTUSERGETMESSAGEINFO Info;
+   NTSTATUS Status;
+   PWINDOW_OBJECT Window = NULL;
+   PMSGMEMORY MsgMemoryEntry;
+   PVOID UserMem;
+   UINT Size;
+   USER_MESSAGE Msg;
+   DECLARE_RETURN(BOOL);
+//   USER_REFERENCE_ENTRY Ref;
+
+   DPRINT("Enter NtUserGetMessage\n");
+   UserEnterExclusive();
+
+   /* Validate input */
+   if (hWnd && !(Window = UserGetWindowObject(hWnd)))
+   {
+      RETURN(-1);
+   }
+   
+//   if (Window) UserRefObjectCo(Window, &Ref);
+   
+   if (MsgFilterMax < MsgFilterMin)
+   {
       MsgFilterMin = 0;
       MsgFilterMax = 0;
-    }
+   }
 
-  do
-    {
-      GotMessage = IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
+   do
+   {
+      GotMessage = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
       if (GotMessage)
-       {
-          Info.Msg = Msg.Msg;
-          /* See if this message type is present in the table */
-          MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
-          if (NULL == MsgMemoryEntry)
-            {
-              /* Not present, no copying needed */
-              Info.LParamSize = 0;
-            }
-          else
+      {
+         Info.Msg = Msg.Msg;
+         /* See if this message type is present in the table */
+         MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
+         if (NULL == MsgMemoryEntry)
+         {
+            /* Not present, no copying needed */
+            Info.LParamSize = 0;
+         }
+         else
+         {
+            /* Determine required size */
+            Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
+                                 Info.Msg.lParam);
+            /* Allocate required amount of user-mode memory */
+            Info.LParamSize = Size;
+            UserMem = NULL;
+            Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
+                                             &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
+
+            if (! NT_SUCCESS(Status))
             {
-              /* Determine required size */
-              Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
-                                   Info.Msg.lParam);
-              /* Allocate required amount of user-mode memory */
-              Info.LParamSize = Size;
-              UserMem = NULL;
-              Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
-                                               &Info.LParamSize, 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);
-              if (! NT_SUCCESS(Status))
-                {
-                  ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
-                                      &Info.LParamSize, MEM_DECOMMIT);
-                  SetLastNtError(Status);
-                  return (BOOL) -1;
-                }
-              Info.Msg.lParam = (LPARAM) UserMem;
+               SetLastNtError(Status);
+               RETURN( (BOOL) -1);
             }
-          if (Msg.FreeLParam && 0 != Msg.Msg.lParam)
+            /* Transfer lParam data to user-mode mem */
+            Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
+            if (! NT_SUCCESS(Status))
             {
-              ExFreePool((void *) Msg.Msg.lParam);
+               ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
+                                   &Info.LParamSize, MEM_DECOMMIT);
+               SetLastNtError(Status);
+               RETURN( (BOOL) -1);
             }
-         Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
-         if (! NT_SUCCESS(Status))
-           {
-             SetLastNtError(Status);
-             return (BOOL) -1;
-           }
-       }
-      else if (! IntWaitMessage(Wnd, MsgFilterMin, MsgFilterMax))
-        {
-          return (BOOL) -1;
-       }
-    }
-  while (! GotMessage);
-
-  return WM_QUIT != Info.Msg.message;
+            Info.Msg.lParam = (LPARAM) UserMem;
+         }
+         if (Msg.FreeLParam && 0 != Msg.Msg.lParam)
+         {
+            ExFreePool((void *) Msg.Msg.lParam);
+         }
+         Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
+         if (! NT_SUCCESS(Status))
+         {
+            SetLastNtError(Status);
+            RETURN( (BOOL) -1);
+         }
+      }
+      else if (! co_IntWaitMessage(hWnd, MsgFilterMin, MsgFilterMax))
+      {
+         RETURN( (BOOL) -1);
+      }
+   }
+   while (! GotMessage);
+
+   RETURN( WM_QUIT != Info.Msg.message);
+
+CLEANUP:
+//   if (Window) UserDerefObjectCo(Window);
+
+   DPRINT("Leave NtUserGetMessage\n");
+   UserLeave();
+   END_CLEANUP;
 }
 
 DWORD
 STDCALL
 NtUserMessageCall(
-  DWORD Unknown0,
-  DWORD Unknown1,
-  DWORD Unknown2,
-  DWORD Unknown3,
-  DWORD Unknown4,
-  DWORD Unknown5,
-  DWORD Unknown6)
+   DWORD Unknown0,
+   DWORD Unknown1,
+   DWORD Unknown2,
+   DWORD Unknown3,
+   DWORD Unknown4,
+   DWORD Unknown5,
+   DWORD Unknown6)
 {
-  UNIMPLEMENTED
+   UNIMPLEMENTED
 
-  return 0;
+   return 0;
 }
 
 static NTSTATUS FASTCALL
 CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
 {
-  NTSTATUS Status;
-  
-  PVOID KernelMem;
-  UINT Size;
+   NTSTATUS Status;
+
+   PVOID KernelMem;
+   UINT Size;
 
-  *KernelModeMsg = *UserModeMsg;
+   *KernelModeMsg = *UserModeMsg;
 
-  /* See if this message type is present in the table */
-  if (NULL == MsgMemoryEntry)
-    {
+   /* See if this message type is present in the table */
+   if (NULL == MsgMemoryEntry)
+   {
       /* Not present, no copying needed */
       return STATUS_SUCCESS;
-    }
+   }
 
-  /* Determine required size */
-  Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+   /* Determine required size */
+   Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
 
-  if (0 != Size)
-    {
+   if (0 != Size)
+   {
       /* Allocate kernel mem */
       KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
       if (NULL == KernelMem)
-        {
-          DPRINT1("Not enough memory to copy message to kernel mem\n");
-          return STATUS_NO_MEMORY;
-        }
+      {
+         DPRINT1("Not enough memory to copy message to kernel mem\n");
+         return STATUS_NO_MEMORY;
+      }
       KernelModeMsg->lParam = (LPARAM) KernelMem;
 
       /* Copy data if required */
       if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
-        {
-          Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
-          if (! NT_SUCCESS(Status))
-            {
-              DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
-              ExFreePool(KernelMem);
-              return Status;
-            }
-        }
+      {
+         Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
+         if (! NT_SUCCESS(Status))
+         {
+            DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
+            ExFreePool(KernelMem);
+            return Status;
+         }
+      }
       else
-        {
-          /* Make sure we don't pass any secrets to usermode */
-          RtlZeroMemory(KernelMem, Size);
-        }
-    }
-  else
-    {
+      {
+         /* Make sure we don't pass any secrets to usermode */
+         RtlZeroMemory(KernelMem, Size);
+      }
+   }
+   else
+   {
       KernelModeMsg->lParam = 0;
-    }
+   }
 
-  return STATUS_SUCCESS;
+   return STATUS_SUCCESS;
 }
 
 static NTSTATUS FASTCALL
 CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
 {
-  NTSTATUS Status;
-  PMSGMEMORY MsgMemoryEntry;
-  UINT Size;
-
-  /* See if this message type is present in the table */
-  MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
-  if (NULL == MsgMemoryEntry)
-    {
+   NTSTATUS Status;
+   PMSGMEMORY MsgMemoryEntry;
+   UINT Size;
+
+   /* See if this message type is present in the table */
+   MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
+   if (NULL == MsgMemoryEntry)
+   {
       /* Not present, no copying needed */
       return STATUS_SUCCESS;
-    }
+   }
 
-  /* Determine required size */
-  Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+   /* Determine required size */
+   Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
 
-  if (0 != Size)
-    {
+   if (0 != Size)
+   {
       /* Copy data if required */
       if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
-        {
-          Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
-          if (! NT_SUCCESS(Status))
-            {
-              DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
-              ExFreePool((PVOID) KernelModeMsg->lParam);
-              return Status;
-            }
-        }
+      {
+         Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
+         if (! NT_SUCCESS(Status))
+         {
+            DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
+            ExFreePool((PVOID) KernelModeMsg->lParam);
+            return Status;
+         }
+      }
 
       ExFreePool((PVOID) KernelModeMsg->lParam);
-    }
+   }
 
-  return STATUS_SUCCESS;
+   return STATUS_SUCCESS;
 }
 
-BOOL STDCALL
-NtUserPostMessage(HWND Wnd,
-                 UINT Msg,
-                 WPARAM wParam,
-                 LPARAM lParam)
+BOOL FASTCALL
+UserPostMessage(HWND Wnd,
+                UINT Msg,
+                WPARAM wParam,
+                LPARAM lParam)
 {
-  PWINDOW_OBJECT Window;
-  MSG UserModeMsg, KernelModeMsg;
-  LARGE_INTEGER LargeTickCount;
-  NTSTATUS Status;
-  PMSGMEMORY MsgMemoryEntry;
-
-  if (WM_QUIT == Msg)
-    {
+   MSG UserModeMsg, KernelModeMsg;
+   LARGE_INTEGER LargeTickCount;
+   NTSTATUS Status;
+   PMSGMEMORY MsgMemoryEntry;
+
+   if (WM_QUIT == Msg)
+   {
       MsqPostQuitMessage(PsGetWin32Thread()->MessageQueue, wParam);
-    }
-  else if (Wnd == HWND_BROADCAST)
-    {
+   }
+   else if (Wnd == HWND_BROADCAST)
+   {
       HWND *List;
       PWINDOW_OBJECT DesktopWindow;
       ULONG i;
 
-      DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
+      DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
       List = IntWinListChildren(DesktopWindow);
-      IntReleaseWindowObject(DesktopWindow);
+      
       if (List != NULL)
-        {
-          for (i = 0; List[i]; i++)
-            NtUserPostMessage(List[i], Msg, wParam, lParam);
-          ExFreePool(List);
-        }      
-    }
-  else
-    {
-      PSYSTEM_CURSORINFO CurInfo;
-      Window = IntGetWindowObject(Wnd);
+      {
+         for (i = 0; List[i]; i++)
+            UserPostMessage(List[i], Msg, wParam, lParam);
+         ExFreePool(List);
+      }
+   }
+   else
+   {
+      PWINDOW_OBJECT Window;
+      
+      Window = UserGetWindowObject(Wnd);
       if (NULL == Window)
-        {
-          SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-          return FALSE;
-        }
+      {
+         return FALSE;
+      }
       if(Window->Status & WINDOWSTATUS_DESTROYING)
       {
-        IntReleaseWindowObject(Window);
-        DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
-        /* FIXME - last error code? */
-        return FALSE;
+         DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
+         /* FIXME - last error code? */
+         return FALSE;
       }
 
       UserModeMsg.hwnd = Wnd;
@@ -1145,244 +1225,278 @@ NtUserPostMessage(HWND Wnd,
       MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
       Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
       if (! NT_SUCCESS(Status))
-        {
-          SetLastWin32Error(ERROR_INVALID_PARAMETER);
-          return FALSE;
-        }
-      CurInfo = IntGetSysCursorInfo(PsGetWin32Thread()->Desktop->WindowStation);
-      KernelModeMsg.pt.x = CurInfo->x;
-      KernelModeMsg.pt.y = CurInfo->y;
+      {
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         return FALSE;
+      }
+      IntGetCursorLocation(PsGetWin32Thread()->Desktop->WindowStation,
+                           &KernelModeMsg.pt);
       KeQueryTickCount(&LargeTickCount);
       KernelModeMsg.time = LargeTickCount.u.LowPart;
       MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
                      NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
                      QS_POSTMESSAGE);
-      IntReleaseWindowObject(Window);
-    }
+   }
 
-  return TRUE;
+   return TRUE;
 }
 
+
+BOOL STDCALL
+NtUserPostMessage(HWND hWnd,
+                  UINT Msg,
+                  WPARAM wParam,
+                  LPARAM lParam)
+{
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserPostMessage\n");
+   UserEnterExclusive();
+
+   RETURN(UserPostMessage(hWnd, Msg, wParam, lParam));
+
+CLEANUP:
+   DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
+}
+
+
+
 BOOL STDCALL
 NtUserPostThreadMessage(DWORD idThread,
-                       UINT Msg,
-                       WPARAM wParam,
-                       LPARAM lParam)
+                        UINT Msg,
+                        WPARAM wParam,
+                        LPARAM lParam)
 {
-  MSG UserModeMsg, KernelModeMsg;
-  PETHREAD peThread;
-  PW32THREAD pThread;
-  NTSTATUS Status;
-  PMSGMEMORY MsgMemoryEntry;
-
-  Status = PsLookupThreadByThreadId((void *)idThread,&peThread);
-  
-  if( Status == STATUS_SUCCESS ) {
-    pThread = peThread->Tcb.Win32Thread;
-    if( !pThread || !pThread->MessageQueue )
+   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;
+         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))
+      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;
+         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;
-  }
+      MsqPostMessage(pThread->MessageQueue, &KernelModeMsg,
+                     NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
+                     QS_POSTMESSAGE);
+      ObDereferenceObject( peThread );
+      RETURN( TRUE);
+   }
+   else
+   {
+      SetLastNtError( Status );
+      RETURN( FALSE);
+   }
+
+CLEANUP:
+   DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 DWORD STDCALL
 NtUserQuerySendMessage(DWORD Unknown0)
 {
-  UNIMPLEMENTED;
+   UNIMPLEMENTED;
 
-  return 0;
+   return 0;
 }
 
 LRESULT FASTCALL
-IntSendMessage(HWND hWnd,
-               UINT Msg,
-               WPARAM wParam,
-               LPARAM lParam)
+co_IntSendMessage(HWND hWnd,
+                  UINT Msg,
+                  WPARAM wParam,
+                  LPARAM lParam)
 {
-  ULONG_PTR Result = 0;
-  if(IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
-  {
-    return (LRESULT)Result;
-  }
-  return 0;
+   ULONG_PTR Result = 0;
+   if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
+   {
+      return (LRESULT)Result;
+   }
+   return 0;
 }
 
-static LRESULT FASTCALL
-IntSendMessageTimeoutSingle(HWND hWnd,
-                            UINT Msg,
-                            WPARAM wParam,
-                            LPARAM lParam,
-                            UINT uFlags,
-                            UINT uTimeout,
-                            ULONG_PTR *uResult)
+static 
+LRESULT FASTCALL
+co_IntSendMessageTimeoutSingle(HWND hWnd,
+                               UINT Msg,
+                               WPARAM wParam,
+                               LPARAM lParam,
+                               UINT uFlags,
+                               UINT uTimeout,
+                               ULONG_PTR *uResult)
 {
-  ULONG_PTR Result;
-  NTSTATUS Status;
-  PWINDOW_OBJECT Window;
-  PMSGMEMORY MsgMemoryEntry;
-  INT lParamBufferSize;
-  LPARAM lParamPacked;
-  PW32THREAD Win32Thread;
-
-  /* FIXME: Call hooks. */
-  Window = IntGetWindowObject(hWnd);
-  if (!Window)
-    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-      return FALSE;
-    }
+   ULONG_PTR Result;
+   NTSTATUS Status;
+   PWINDOW_OBJECT Window = NULL;
+   PMSGMEMORY MsgMemoryEntry;
+   INT lParamBufferSize;
+   LPARAM lParamPacked;
+   PW32THREAD Win32Thread;
+   DECLARE_RETURN(LRESULT);
+   USER_REFERENCE_ENTRY Ref;
+
+   /* FIXME: Call hooks. */
+   if (!(Window = UserGetWindowObject(hWnd)))
+   {
+       RETURN( FALSE);
+   }
+   
+   UserRefObjectCo(Window, &Ref);
 
-  Win32Thread = PsGetWin32Thread();
+   Win32Thread = PsGetWin32Thread();
 
-  if (NULL != Win32Thread &&
-      Window->MessageQueue == Win32Thread->MessageQueue)
-    {
+   if (NULL != Win32Thread &&
+         Window->MessageQueue == Win32Thread->MessageQueue)
+   {
       if (Win32Thread->IsExiting)
-        {
-          /* Never send messages to exiting threads */
-          IntReleaseWindowObject(Window);
-          return FALSE;
-        }
+      {
+         /* Never send messages to exiting threads */
+          RETURN( FALSE);
+      }
 
       /* See if this message type is present in the table */
       MsgMemoryEntry = FindMsgMemory(Msg);
       if (NULL == MsgMemoryEntry)
-        {
-          lParamBufferSize = -1;
-        }
+      {
+         lParamBufferSize = -1;
+      }
       else
-        {
-          lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
-        }
+      {
+         lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+      }
 
       if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam)))
-        {
-          IntReleaseWindowObject(Window);
-          DPRINT1("Failed to pack message parameters\n");
-          return FALSE;
-        }
+      {
+         DPRINT1("Failed to pack message parameters\n");
+          RETURN( FALSE);
+      }
       if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
-        {
-          Result = (ULONG_PTR)IntCallWindowProc(Window->WndProcW, FALSE, hWnd, Msg, wParam,
-                                                lParamPacked,lParamBufferSize);
-        }
+      {
+         Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcW, FALSE, hWnd, Msg, wParam,
+                  lParamPacked,lParamBufferSize);
+      }
       else
-        {
-          Result = (ULONG_PTR)IntCallWindowProc(Window->WndProcA, TRUE, hWnd, Msg, wParam,
-                                                lParamPacked,lParamBufferSize);
-        }
-      
+      {
+         Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcA, TRUE, hWnd, Msg, wParam,
+                  lParamPacked,lParamBufferSize);
+      }
+
       if(uResult)
       {
-        *uResult = Result;
+         *uResult = Result;
       }
-      
+
       if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam)))
-        {
-          IntReleaseWindowObject(Window);
-          DPRINT1("Failed to unpack message parameters\n");
-          return TRUE;
-        }
+      {
+         DPRINT1("Failed to unpack message parameters\n");
+          RETURN( TRUE);
+      }
 
-      IntReleaseWindowObject(Window);
-      return TRUE;
-    }
-  
-  if(uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->MessageQueue))
-  {
-    IntReleaseWindowObject(Window);
-    /* FIXME - Set a LastError? */
-    return FALSE;
-  }
-  
-  if(Window->Status & WINDOWSTATUS_DESTROYING)
-  {
-    IntReleaseWindowObject(Window);
-    /* FIXME - last error? */
-    DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
-    return FALSE;
-  }
-  
-  Status = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam, 
-                          uTimeout, (uFlags & SMTO_BLOCK), uResult);
-  IntReleaseWindowObject(Window);
-  if (STATUS_TIMEOUT == Status)
-    {
+       RETURN( TRUE);
+   }
+
+   if(uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->MessageQueue))
+   {
+      /* FIXME - Set a LastError? */
+       RETURN( FALSE);
+   }
+
+   if(Window->Status & WINDOWSTATUS_DESTROYING)
+   {
+      /* FIXME - last error? */
+      DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+       RETURN( FALSE);
+   }
+
+   Status = co_MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam,
+                              uTimeout, (uFlags & SMTO_BLOCK), FALSE, uResult);
+
+
+   if (STATUS_TIMEOUT == Status)
+   {
       /* MSDN says GetLastError() should return 0 after timeout */
       SetLastWin32Error(0);
-      return FALSE;
-    }
-  else if (! NT_SUCCESS(Status))
-    {
+       RETURN( FALSE);
+   }
+   else if (! NT_SUCCESS(Status))
+   {
       SetLastNtError(Status);
-      return FALSE;
-    }
+       RETURN( FALSE);
+   }
 
-  return TRUE;
+   RETURN( TRUE);
+   
+CLEANUP:
+   if (Window) UserDerefObjectCo(Window);
+   END_CLEANUP;
 }
 
 LRESULT FASTCALL
-IntSendMessageTimeout(HWND hWnd,
-                      UINT Msg,
-                      WPARAM wParam,
-                      LPARAM lParam,
-                      UINT uFlags,
-                      UINT uTimeout,
-                      ULONG_PTR *uResult)
+co_IntSendMessageTimeout(HWND hWnd,
+                         UINT Msg,
+                         WPARAM wParam,
+                         LPARAM lParam,
+                         UINT uFlags,
+                         UINT uTimeout,
+                         ULONG_PTR *uResult)
 {
-  PWINDOW_OBJECT DesktopWindow;
-  HWND *Children;
-  HWND *Child;
-
-  if (HWND_BROADCAST != hWnd)
-    {
-      return IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
-    }
-
-  DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
-  if (NULL == DesktopWindow)
-    {
+   PWINDOW_OBJECT DesktopWindow;
+   HWND *Children;
+   HWND *Child;
+
+   if (HWND_BROADCAST != hWnd)
+   {
+      return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+   }
+
+   DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+   if (NULL == DesktopWindow)
+   {
       SetLastWin32Error(ERROR_INTERNAL_ERROR);
       return 0;
-    }
-  Children = IntWinListChildren(DesktopWindow);
-  IntReleaseWindowObject(DesktopWindow);
-  if (NULL == Children)
-    {
+   }
+
+   Children = IntWinListChildren(DesktopWindow);
+   if (NULL == Children)
+   {
       return 0;
-    }
+   }
 
-  for (Child = Children; NULL != *Child; Child++)
-    {
-      IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
-    }
+   for (Child = Children; NULL != *Child; Child++)
+   {
+      co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+   }
 
-  ExFreePool(Children);
+   ExFreePool(Children);
 
-  return (LRESULT) TRUE;
+   return (LRESULT) TRUE;
 }
 
 
@@ -1390,229 +1504,251 @@ IntSendMessageTimeout(HWND hWnd,
    another thread, otherwise it sends the message. It does not support broadcast
    messages! */
 LRESULT FASTCALL
-IntPostOrSendMessage(HWND hWnd,
-                     UINT Msg,
-                     WPARAM wParam,
-                     LPARAM lParam)
+co_IntPostOrSendMessage(HWND hWnd,
+                        UINT Msg,
+                        WPARAM wParam,
+                        LPARAM lParam)
 {
-  ULONG_PTR Result;
-  PWINDOW_OBJECT Window;
-  
-  if(hWnd == HWND_BROADCAST)
-  {
-    return 0;
-  }
-  
-  Window = IntGetWindowObject(hWnd);
-  if(!Window)
-  {
-    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-    return 0;
-  }
-  
-  if(Window->MessageQueue != PsGetWin32Thread()->MessageQueue)
-  {
-    Result = NtUserPostMessage(hWnd, Msg, wParam, lParam);
-  }
-  else
-  {
-    if(!IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
-    {
-      Result = 0;
-    }
-  }
-  
-  IntReleaseWindowObject(Window);
-  
-  return (LRESULT)Result;
+   ULONG_PTR Result;
+   PWINDOW_OBJECT Window;
+
+   if(hWnd == HWND_BROADCAST)
+   {
+      return 0;
+   }
+
+   if(!(Window = UserGetWindowObject(hWnd)))
+   {
+      return 0;
+   }
+
+   if(Window->MessageQueue != PsGetWin32Thread()->MessageQueue)
+   {
+      Result = UserPostMessage(hWnd, Msg, wParam, lParam);
+   }
+   else
+   {
+      if(!co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
+      {
+         Result = 0;
+      }
+   }
+
+   return (LRESULT)Result;
 }
 
 LRESULT FASTCALL
-IntDoSendMessage(HWND Wnd,
-                UINT Msg,
-                WPARAM wParam,
-                LPARAM lParam,
-                PDOSENDMESSAGE dsm,
-                PNTUSERSENDMESSAGEINFO UnsafeInfo)
+co_IntDoSendMessage(HWND hWnd,
+                    UINT Msg,
+                    WPARAM wParam,
+                    LPARAM lParam,
+                    PDOSENDMESSAGE dsm,
+                    PNTUSERSENDMESSAGEINFO UnsafeInfo)
 {
-  LRESULT Result = TRUE;
-  NTSTATUS Status;
-  PWINDOW_OBJECT Window;
-  NTUSERSENDMESSAGEINFO Info;
-  MSG UserModeMsg;
-  MSG KernelModeMsg;
-  PMSGMEMORY MsgMemoryEntry;
-
-  RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
-
-  /* FIXME: Call hooks. */
-  if (HWND_BROADCAST != Wnd)
-    {
-      Window = IntGetWindowObject(Wnd);
+   LRESULT Result = TRUE;
+   NTSTATUS Status;
+   PWINDOW_OBJECT Window;
+   NTUSERSENDMESSAGEINFO Info;
+   MSG UserModeMsg;
+   MSG KernelModeMsg;
+   PMSGMEMORY MsgMemoryEntry;
+
+   RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
+
+   /* FIXME: Call hooks. */
+   if (HWND_BROADCAST != hWnd)
+   {
+      Window = UserGetWindowObject(hWnd);
       if (NULL == Window)
-        {
-          /* Tell usermode to not touch this one */
-          Info.HandledByKernel = TRUE;
-          MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
-          SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
-          return 0;
-        }
-    }
-
-  /* FIXME: Check for an exiting window. */
-
-  /* See if the current thread can handle the message */
-  if (HWND_BROADCAST != Wnd && NULL != PsGetWin32Thread() &&
-      Window->MessageQueue == PsGetWin32Thread()->MessageQueue)
-    {
+      {
+         /* Tell usermode to not touch this one */
+         Info.HandledByKernel = TRUE;
+         MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+         return 0;
+      }
+   }
+
+   /* FIXME: Check for an exiting window. */
+
+   /* See if the current thread can handle the message */
+   if (HWND_BROADCAST != hWnd && NULL != PsGetWin32Thread() &&
+         Window->MessageQueue == PsGetWin32Thread()->MessageQueue)
+   {
       /* Gather the information usermode needs to call the window proc directly */
       Info.HandledByKernel = FALSE;
       if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
-        {
-          if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000))
-            {
-              /* Both Unicode and Ansi winprocs are real, see what usermode prefers */
-              Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
-                                        sizeof(BOOL));
-              if (! NT_SUCCESS(Status))
-                {
-                  Info.Ansi = ! Window->Unicode;
-                }
-              Info.Proc = (Info.Ansi ? Window->WndProcA : Window->WndProcW);
-            }
-          else
+      {
+         if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000))
+         {
+            /* Both Unicode and Ansi winprocs are real, see what usermode prefers */
+            Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
+                                      sizeof(BOOL));
+            if (! NT_SUCCESS(Status))
             {
-              /* Real Unicode winproc */
-              Info.Ansi = FALSE;
-              Info.Proc = Window->WndProcW;
+               Info.Ansi = ! Window->Unicode;
             }
-        }
+            Info.Proc = (Info.Ansi ? Window->WndProcA : Window->WndProcW);
+         }
+         else
+         {
+            /* Real Unicode winproc */
+            Info.Ansi = FALSE;
+            Info.Proc = Window->WndProcW;
+         }
+      }
       else
-        {
-          /* Must have real Ansi winproc */
-          Info.Ansi = TRUE;
-          Info.Proc = Window->WndProcA;
-        }
-      IntReleaseWindowObject(Window);
-    }
-  else
-    {
+      {
+         /* Must have real Ansi winproc */
+         Info.Ansi = TRUE;
+         Info.Proc = Window->WndProcA;
+      }
+   }
+   else
+   {
       /* Must be handled by other thread */
-      if (HWND_BROADCAST != Wnd)
-        {
-          IntReleaseWindowObject(Window);
-        }
+//      if (HWND_BROADCAST != hWnd)
+//      {
+//         UserDerefObject(Window);
+//      }
       Info.HandledByKernel = TRUE;
-      UserModeMsg.hwnd = Wnd;
+      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))
-        {
-          MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
-          SetLastWin32Error(ERROR_INVALID_PARAMETER);
-          return (dsm ? 0 : -1);
-        }
+      {
+         MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         return (dsm ? 0 : -1);
+      }
       if(!dsm)
       {
-        Result = IntSendMessage(KernelModeMsg.hwnd, KernelModeMsg.message,
-                                KernelModeMsg.wParam, KernelModeMsg.lParam);
+         Result = co_IntSendMessage(KernelModeMsg.hwnd, KernelModeMsg.message,
+                                    KernelModeMsg.wParam, KernelModeMsg.lParam);
       }
       else
       {
-        Result = IntSendMessageTimeout(KernelModeMsg.hwnd, KernelModeMsg.message,
-                                       KernelModeMsg.wParam, KernelModeMsg.lParam,
-                                       dsm->uFlags, dsm->uTimeout, &dsm->Result);
+         Result = co_IntSendMessageTimeout(KernelModeMsg.hwnd, KernelModeMsg.message,
+                                           KernelModeMsg.wParam, KernelModeMsg.lParam,
+                                           dsm->uFlags, dsm->uTimeout, &dsm->Result);
       }
       Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
       if (! NT_SUCCESS(Status))
-        {
-          MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
-          SetLastWin32Error(ERROR_INVALID_PARAMETER);
-          return(dsm ? 0 : -1);
-        }
-    }
-
-  Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
-  if (! NT_SUCCESS(Status))
-    {
+      {
+         MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         return(dsm ? 0 : -1);
+      }
+   }
+
+   Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+   if (! NT_SUCCESS(Status))
+   {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
-    }
+   }
 
-  return (LRESULT)Result;
+   return (LRESULT)Result;
 }
 
 LRESULT STDCALL
 NtUserSendMessageTimeout(HWND hWnd,
-                        UINT Msg,
-                        WPARAM wParam,
-                        LPARAM lParam,
-                        UINT uFlags,
-                        UINT uTimeout,
-                        ULONG_PTR *uResult,
-                        PNTUSERSENDMESSAGEINFO UnsafeInfo)
+                         UINT Msg,
+                         WPARAM wParam,
+                         LPARAM lParam,
+                         UINT uFlags,
+                         UINT uTimeout,
+                         ULONG_PTR *uResult,
+                         PNTUSERSENDMESSAGEINFO UnsafeInfo)
 {
-  DOSENDMESSAGE dsm;
-  LRESULT Result;
-
-  dsm.uFlags = uFlags;
-  dsm.uTimeout = uTimeout;
-  Result = IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
-  if(uResult != NULL && Result != 0)
-  {
-    NTSTATUS Status;
-    
-    Status = MmCopyToCaller(uResult, &dsm.Result, sizeof(ULONG_PTR));
-    if(!NT_SUCCESS(Status))
-    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return FALSE;
-    }
-  }
-  return Result;
+   DOSENDMESSAGE dsm;
+   LRESULT Result;
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserSendMessageTimeout\n");
+   UserEnterExclusive();
+
+   dsm.uFlags = uFlags;
+   dsm.uTimeout = uTimeout;
+   Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
+   if(uResult != NULL && Result != 0)
+   {
+      NTSTATUS Status;
+
+      Status = MmCopyToCaller(uResult, &dsm.Result, sizeof(ULONG_PTR));
+      if(!NT_SUCCESS(Status))
+      {
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         RETURN( FALSE);
+      }
+   }
+   RETURN( Result);
+
+CLEANUP:
+   DPRINT("Leave NtUserSendMessageTimeout, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 LRESULT STDCALL
 NtUserSendMessage(HWND Wnd,
-                 UINT Msg,
-                 WPARAM wParam,
-                 LPARAM lParam,
+                  UINT Msg,
+                  WPARAM wParam,
+                  LPARAM lParam,
                   PNTUSERSENDMESSAGEINFO UnsafeInfo)
 {
-  return IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo);
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("Enter NtUserSendMessage\n");
+   UserEnterExclusive();
+
+   RETURN(co_IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo));
+
+CLEANUP:
+   DPRINT("Leave NtUserSendMessage, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 BOOL STDCALL
 NtUserSendMessageCallback(HWND hWnd,
-                         UINT Msg,
-                         WPARAM wParam,
-                         LPARAM lParam,
-                         SENDASYNCPROC lpCallBack,
-                         ULONG_PTR dwData)
+                          UINT Msg,
+                          WPARAM wParam,
+                          LPARAM lParam,
+                          SENDASYNCPROC lpCallBack,
+                          ULONG_PTR dwData)
 {
-  UNIMPLEMENTED;
+   UNIMPLEMENTED;
 
-  return 0;
+   return 0;
 }
 
 BOOL STDCALL
 NtUserSendNotifyMessage(HWND hWnd,
-                       UINT Msg,
-                       WPARAM wParam,
-                       LPARAM lParam)
+                        UINT Msg,
+                        WPARAM wParam,
+                        LPARAM lParam)
 {
-  UNIMPLEMENTED;
+   UNIMPLEMENTED;
 
-  return 0;
+   return 0;
 }
 
 BOOL STDCALL
 NtUserWaitMessage(VOID)
 {
+   DECLARE_RETURN(BOOL);
+
+   DPRINT("EnterNtUserWaitMessage\n");
+   UserEnterExclusive();
 
-  return IntWaitMessage(NULL, 0, 0);
+   RETURN(co_IntWaitMessage(NULL, 0, 0));
+
+CLEANUP:
+   DPRINT("Leave NtUserWaitMessage, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 DWORD STDCALL
@@ -1620,10 +1756,12 @@ NtUserGetQueueStatus(BOOL ClearChanges)
 {
    PUSER_MESSAGE_QUEUE Queue;
    DWORD Result;
+   DECLARE_RETURN(DWORD);
 
-   Queue = PsGetWin32Thread()->MessageQueue;
+   DPRINT("Enter NtUserGetQueueStatus\n");
+   UserEnterExclusive();
 
-   IntLockMessageQueue(Queue);
+   Queue = PsGetWin32Thread()->MessageQueue;
 
    Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
    if (ClearChanges)
@@ -1631,27 +1769,30 @@ NtUserGetQueueStatus(BOOL ClearChanges)
       Queue->ChangedBits = 0;
    }
 
-   IntUnLockMessageQueue(Queue);
+   RETURN( Result);
 
-   return Result;
+CLEANUP:
+   DPRINT("Leave NtUserGetQueueStatus, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 BOOL STDCALL
 IntInitMessagePumpHook()
 {
-       PsGetCurrentThread()->Tcb.Win32Thread->MessagePumpHookValue++;
-       return TRUE;
+   ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->MessagePumpHookValue++;
+   return TRUE;
 }
 
 BOOL STDCALL
 IntUninitMessagePumpHook()
 {
-       if (PsGetCurrentThread()->Tcb.Win32Thread->MessagePumpHookValue <= 0)
-       {
-               return FALSE;
-       }
-       PsGetCurrentThread()->Tcb.Win32Thread->MessagePumpHookValue--;
-       return TRUE;
+   if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->MessagePumpHookValue <= 0)
+   {
+      return FALSE;
+   }
+   ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->MessagePumpHookValue--;
+   return TRUE;
 }
 
 /* EOF */