[User32|Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / message.c
index b66f31d..030b1c9 100644 (file)
@@ -16,7 +16,6 @@
 #include <debug.h>
 
 BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
-HWND FASTCALL co_UserSetCapture(HWND hWnd);
 
 #define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
 
@@ -320,6 +319,7 @@ PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Non
     {
         PMSGMEMORY MsgMemoryEntry;
         PVOID PackedData;
+        SIZE_T size;
 
         MsgMemoryEntry = FindMsgMemory(Msg);
 
@@ -328,7 +328,13 @@ PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Non
             /* Keep previous behavior */
             return STATUS_SUCCESS;
         }
-        PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
+        size = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+        if (!size)
+        {
+           DPRINT1("No size for lParamPacked\n");
+           return STATUS_SUCCESS;
+        }
+        PackedData = ExAllocatePoolWithTag(NonPagedPool, size, TAG_MSG);
         RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
         *lParamPacked = (LPARAM)PackedData;
     }
@@ -729,7 +735,8 @@ co_IntPeekMessage( PMSG Msg,
         }
 
         /* Now check for normal messages. */
-        if ((ProcessMask & QS_POSTMESSAGE) &&
+        if (( (ProcessMask & QS_POSTMESSAGE) ||
+              (ProcessMask & QS_HOTKEY) ) &&
             MsqPeekMessage( ThreadQueue,
                             RemoveMessages,
                             Window,
@@ -854,9 +861,12 @@ co_IntWaitMessage( PWND Window,
         {
             SetLastNtError(Status);
             DPRINT1("Exit co_IntWaitMessage on error!\n");
-
             return FALSE;
         }
+        if (Status == STATUS_USER_APC || Status == STATUS_TIMEOUT)
+        {
+           return FALSE;
+        }
     }
     while ( TRUE );
 
@@ -933,11 +943,7 @@ co_IntGetPeekMessage( PMSG pMsg,
 
            co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg);
 
-           if ( bGMSG )
-           {
-              Present = (WM_QUIT != pMsg->message);
-              break;
-           }
+           if ( bGMSG ) break;
         }
 
         if ( bGMSG )
@@ -946,7 +952,9 @@ co_IntGetPeekMessage( PMSG pMsg,
                                                Window,
                                                MsgFilterMin,
                                                MsgFilterMax);
-           if ( !NT_SUCCESS(Status) )
+           if ( !NT_SUCCESS(Status) ||
+                Status == STATUS_USER_APC ||
+                Status == STATUS_TIMEOUT )
            {
               Present = -1;
               break;
@@ -1038,7 +1046,6 @@ UserPostMessage( HWND Wnd,
     PTHREADINFO pti;
     MSG Message, KernelModeMsg;
     LARGE_INTEGER LargeTickCount;
-    PMSGMEMORY MsgMemoryEntry;
 
     Message.hwnd = Wnd;
     Message.message = Msg;
@@ -1048,11 +1055,18 @@ UserPostMessage( HWND Wnd,
     KeQueryTickCount(&LargeTickCount);
     Message.time = MsqCalculateMessageTime(&LargeTickCount);
 
-    MsgMemoryEntry = FindMsgMemory(Message.message);
+    if (is_pointer_message(Message.message))
+    {
+        EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
+        return FALSE;
+    }
 
     if( Msg >= WM_DDE_FIRST && Msg <= WM_DDE_LAST )
     {
         NTSTATUS Status;
+        PMSGMEMORY MsgMemoryEntry;
+
+        MsgMemoryEntry = FindMsgMemory(Message.message);
 
         Status = CopyMsgToKernelMem(&KernelModeMsg, &Message, MsgMemoryEntry);
         if (! NT_SUCCESS(Status))
@@ -1071,12 +1085,6 @@ UserPostMessage( HWND Wnd,
         return TRUE;
     }
 
-    if (is_pointer_message(Message.message))
-    {
-        EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
-        return FALSE;
-    }
-
     if (!Wnd)
     {
         return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
@@ -1270,8 +1278,8 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
 
     if (STATUS_TIMEOUT == Status)
     {
-        /*
-MSDN says:
+/*
+    MSDN says:
     Microsoft Windows 2000: If GetLastError returns zero, then the function
     timed out.
     XP+ : If the function fails or times out, the return value is zero.
@@ -1396,17 +1404,8 @@ co_IntSendMessageWithCallBack( HWND hWnd,
 
     Win32Thread = PsGetCurrentThreadWin32Thread();
 
-    IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
-
     if (Win32Thread == NULL)
     {
-        ASSERT(FALSE);
-        RETURN(FALSE);
-    }
-
-    if (Win32Thread->TIF_flags & TIF_INCLEANUP)
-    {
-        /* Never send messages to exiting threads */
         RETURN(FALSE);
     }
 
@@ -1427,9 +1426,18 @@ co_IntSendMessageWithCallBack( HWND hWnd,
         RETURN( FALSE);
     }
 
-    /* If this is not a callback and it can be sent now, then send it. */
-    if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+    /* If it can be sent now, then send it. */
+    if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
     {
+        if (Win32Thread->TIF_flags & TIF_INCLEANUP)
+        {
+            UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE);
+            /* Never send messages to exiting threads */
+            RETURN(FALSE);
+        }
+
+        IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+
         ObReferenceObject(Win32Thread->pEThread);
         Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
                                                   !Window->Unicode,
@@ -1443,11 +1451,22 @@ co_IntSendMessageWithCallBack( HWND hWnd,
             *uResult = Result;
         }
         ObDereferenceObject(Win32Thread->pEThread);
+
+        IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+
+        if (CompletionCallback)
+        {
+            co_IntCallSentMessageCallback(CompletionCallback,
+                                          hWnd,
+                                          Msg,
+                                          CompletionCallbackContext,
+                                          Result);
+        }
     }
 
-    IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
 
-    if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+
+    if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
     {
         if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
         {
@@ -1462,6 +1481,12 @@ co_IntSendMessageWithCallBack( HWND hWnd,
         RETURN( FALSE);
     }
 
+    IntReferenceMessageQueue(Window->head.pti->MessageQueue);
+    /* Take reference on this MessageQueue if its a callback. It will be released 
+       when message is processed or removed from target hwnd MessageQueue */
+    if (CompletionCallback)
+       IntReferenceMessageQueue(Win32Thread->MessageQueue);
+
     Message->Msg.hwnd = hWnd;
     Message->Msg.message = Msg;
     Message->Msg.wParam = wParam;
@@ -1472,17 +1497,15 @@ co_IntSendMessageWithCallBack( HWND hWnd,
     Message->QS_Flags = 0;
     Message->SenderQueue = NULL; // mjmartin, you are right! This is null.
     Message->CallBackSenderQueue = Win32Thread->MessageQueue;
-
-    IntReferenceMessageQueue(Window->head.pti->MessageQueue);
+    Message->DispatchingListEntry.Flink = NULL;
     Message->CompletionCallback = CompletionCallback;
     Message->CompletionCallbackContext = CompletionCallbackContext;
-    Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
+    Message->HookMessage = MSQ_NORMAL;
     Message->HasPackedLParam = (lParamBufferSize > 0);
-
     Message->QS_Flags = QS_SENDMESSAGE;
-    MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE);
 
     InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
+    MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, TRUE);
     IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
 
     RETURN(TRUE);
@@ -1852,7 +1875,7 @@ NtUserGetMessage(PMSG pMsg,
 
     UserLeave();
 
-    if (Ret)
+    if (Ret == TRUE)
     {
         _SEH2_TRY
         {
@@ -1867,6 +1890,9 @@ NtUserGetMessage(PMSG pMsg,
         _SEH2_END;
     }
 
+    if ((INT)Ret != -1)
+       Ret = Ret ? (WM_QUIT != pMsg->message) : FALSE;
+
     return Ret;
 }