[NtUser]
authorJames Tabor <james.tabor@reactos.org>
Mon, 1 Aug 2016 19:13:48 +0000 (19:13 +0000)
committerJames Tabor <james.tabor@reactos.org>
Mon, 1 Aug 2016 19:13:48 +0000 (19:13 +0000)
- Fix a recursion issue while processing posted messages. Related to CORE-10471. Dedicated to Thomas Faber for Free before Use testing.
- Pass extra information along with posted messages.
- Trigger an event when cursor position has changed.

svn path=/trunk/; revision=72076

reactos/win32ss/user/ntuser/message.c
reactos/win32ss/user/ntuser/msgqueue.c

index 523eb55..f4c75b2 100644 (file)
@@ -1078,6 +1078,10 @@ co_IntGetPeekMessage( PMSG pMsg,
 
            if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
            {
+              if (!RtlEqualMemory(&pti->ptLast, &pMsg->pt, sizeof(POINT)))
+              {
+                 pti->TIF_flags |= TIF_MSGPOSCHANGED;
+              }
               pti->timeLast = pMsg->time;
               pti->ptLast   = pMsg->pt;
            }
@@ -1278,6 +1282,7 @@ co_IntSendMessage( HWND hWnd,
                    LPARAM lParam )
 {
     ULONG_PTR Result = 0;
+
     if (co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
     {
         return (LRESULT)Result;
index e37e252..1914aee 100644 (file)
@@ -15,6 +15,7 @@ DBG_DEFAULT_CHANNEL(UserMsgQ);
 
 static PPAGED_LOOKASIDE_LIST pgMessageLookasideList;
 static PPAGED_LOOKASIDE_LIST pgSendMsgLookasideList;
+INT PostMsgCount = 0;
 INT SendMsgCount = 0;
 PUSER_MESSAGE_QUEUE gpqCursor;
 ULONG_PTR gdwMouseMoveExtraInfo = 0;
@@ -743,20 +744,23 @@ MsqCreateMessage(LPMSG Msg)
 
    RtlZeroMemory(Message, sizeof(*Message));
    RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
-
+   PostMsgCount++;
    return Message;
 }
 
 VOID FASTCALL
 MsqDestroyMessage(PUSER_MESSAGE Message)
 {
+   TRACE("Post Destroy %d\n",PostMsgCount)
    if (Message->pti == NULL)
    {
       ERR("Double Free Message\n");
       return;
    }
+   RemoveEntryList(&Message->ListEntry);
    Message->pti = NULL;
    ExFreeToPagedLookasideList(pgMessageLookasideList, Message);
+   PostMsgCount--;
 }
 
 PUSER_SENT_MESSAGE FASTCALL
@@ -820,7 +824,6 @@ MsqRemoveWindowMessagesFromQueue(PWND Window)
             pti->QuitPosted = 1;
             pti->exitCode = PostedMessage->Msg.wParam;
          }
-         RemoveEntryList(&PostedMessage->ListEntry);
          ClearMsgBitsMask(pti, PostedMessage->QS_Flags);
          MsqDestroyMessage(PostedMessage);
          CurrentEntry = pti->PostedMessagesListHead.Flink;
@@ -1374,6 +1377,7 @@ MsqPostMessage(PTHREADINFO pti,
    Message->QS_Flags = MessageBits;
    Message->pti = pti;
    MsqWakeQueue(pti, MessageBits, TRUE);
+   TRACE("Post Message %d\n",PostMsgCount);
 }
 
 VOID FASTCALL
@@ -1468,7 +1472,7 @@ IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
    }
 }
 
-BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, UINT first, UINT last)
+BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
 {
     MSG clk_msg;
     POINT pt;
@@ -1653,6 +1657,12 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, U
         }
     }
 
+    if (pti->TIF_flags & TIF_MSGPOSCHANGED)
+    {
+        pti->TIF_flags &= ~TIF_MSGPOSCHANGED;
+        IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
+    }
+
     /* message is accepted now (but still get dropped) */
 
     event.message = msg->message;
@@ -1665,14 +1675,14 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, U
     hook.pt           = msg->pt;
     hook.hwnd         = msg->hwnd;
     hook.wHitTestCode = hittest;
-    hook.dwExtraInfo  = 0 /* extra_info */ ;
+    hook.dwExtraInfo  = ExtraInfo;
     if (co_HOOK_CallHooks( WH_MOUSE, *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
                         message, (LPARAM)&hook ))
     {
         hook.pt           = msg->pt;
         hook.hwnd         = msg->hwnd;
         hook.wHitTestCode = hittest;
-        hook.dwExtraInfo  = 0 /* extra_info */ ;
+        hook.dwExtraInfo  = ExtraInfo;
         co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook );
 
         ERR("WH_MOUSE dropped mouse message!\n");
@@ -1860,11 +1870,11 @@ BOOL co_IntProcessKeyboardMessage(MSG* Msg, BOOL* RemoveMessages)
     return Ret;
 }
 
-BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, BOOL* NotForUs, UINT first, UINT last)
+BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
 {
     if ( IS_MOUSE_MESSAGE(Msg->message))
     {
-        return co_IntProcessMouseMessage(Msg, RemoveMessages, NotForUs, first, last);
+        return co_IntProcessMouseMessage(Msg, RemoveMessages, NotForUs, ExtraInfo, first, last);
     }
     else if ( IS_KBD_MESSAGE(Msg->message))
     {
@@ -1916,6 +1926,7 @@ co_MsqPeekHardwareMessage(IN PTHREADINFO pti,
    MSG msg;
    ULONG_PTR idSave;
    DWORD QS_Flags;
+   LONG_PTR ExtraInfo;
    BOOL Ret = FALSE;
    PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
 
@@ -1964,18 +1975,18 @@ co_MsqPeekHardwareMessage(IN PTHREADINFO pti,
          MessageQueue->idSysPeek = (ULONG_PTR)CurrentMessage;
 
          msg = CurrentMessage->Msg;
+         ExtraInfo = CurrentMessage->ExtraInfo;
          QS_Flags = CurrentMessage->QS_Flags;
 
          NotForUs = FALSE;
 
          UpdateKeyStateFromMsg(MessageQueue, &msg);
-         AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, &NotForUs, MsgFilterLow, MsgFilterHigh);
+         AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, &NotForUs, ExtraInfo, MsgFilterLow, MsgFilterHigh);
 
          if (Remove)
          {
-             if (CurrentMessage->pti != NULL)
+             if (CurrentMessage->pti != NULL && (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage))
              {
-                RemoveEntryList(&CurrentMessage->ListEntry);
                 MsqDestroyMessage(CurrentMessage);
              }
              ClearMsgBitsMask(pti, QS_Flags);
@@ -1999,7 +2010,7 @@ co_MsqPeekHardwareMessage(IN PTHREADINFO pti,
             }
             pti->ptLast   = msg.pt;
             pti->timeLast = msg.time;
-            //MessageQueue->ExtraInfo = ExtraInfo;
+            MessageQueue->ExtraInfo = ExtraInfo;
             Ret = TRUE;
             break;
          }
@@ -2054,7 +2065,6 @@ MsqPeekMessage(IN PTHREADINFO pti,
          {
              if (CurrentMessage->pti != NULL)
              {
-                RemoveEntryList(&CurrentMessage->ListEntry);
                 MsqDestroyMessage(CurrentMessage);
              }
              ClearMsgBitsMask(pti, QS_Flags);
@@ -2183,8 +2193,9 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
    /* cleanup posted messages */
    while (!IsListEmpty(&pti->PostedMessagesListHead))
    {
-      CurrentEntry = RemoveHeadList(&pti->PostedMessagesListHead);
+      CurrentEntry = pti->PostedMessagesListHead.Flink;
       CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
+      ERR("Thread Cleanup Post Messages %p\n",CurrentMessage);
       if (CurrentMessage->dwQEvent)
       {
          if (CurrentMessage->dwQEvent == POSTEVENT_NWE)
@@ -2271,6 +2282,8 @@ VOID FASTCALL
 MsqCleanupMessageQueue(PTHREADINFO pti)
 {
    PUSER_MESSAGE_QUEUE MessageQueue;
+   PLIST_ENTRY CurrentEntry;
+   PUSER_MESSAGE CurrentMessage;
 
    MessageQueue = pti->MessageQueue;
    MessageQueue->cThreads--;
@@ -2280,6 +2293,18 @@ MsqCleanupMessageQueue(PTHREADINFO pti)
       if (MessageQueue->ptiSysLock == pti) MessageQueue->ptiSysLock = NULL;
    }
 
+   if (MessageQueue->cThreads == 0) //// Fix a crash related to CORE-10471 testing.
+   {
+      /* cleanup posted messages */
+      while (!IsListEmpty(&MessageQueue->HardwareMessagesListHead))
+      {
+         CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;       
+         CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
+         ERR("MQ Cleanup Post Messages %p\n",CurrentMessage);
+         MsqDestroyMessage(CurrentMessage);
+      }
+   } ////
+
    if (MessageQueue->CursorObject)
    {
        PCURICON_OBJECT pCursor = MessageQueue->CursorObject;