[Wine32k|User32]
authorJames Tabor <james.tabor@reactos.org>
Sat, 20 Nov 2010 04:24:44 +0000 (04:24 +0000)
committerJames Tabor <james.tabor@reactos.org>
Sat, 20 Nov 2010 04:24:44 +0000 (04:24 +0000)
- Implement client thread information for the beginning of QS flag support and signaling synchronization of messages.
- Set and clear idle event when setting clearing masks. This fixed the idle foreground hook call from user mode.
- Fixed wine ListBox and ReactOS ComboBox tests. Critical note: SendMessageA/W, when IsThreadHooked is used and any global hooks are affirmed, all messages are sent to Win32k and the result is, A to W and W to A mismatch via UMToKM. Fixing Global hook support exposed a critical bug in ReactOS message system. Enable the appropriate hooks will temporarily remedy this bug.
- All patches are from a checked out revision from 49475. Upping ntuser.h, win32k and user32 to sync.

svn path=/trunk/; revision=49653

12 files changed:
reactos/dll/win32/user32/include/user32p.h
reactos/dll/win32/user32/windows/hook.c
reactos/dll/win32/user32/windows/message.c
reactos/include/reactos/win32k/ntuser.h
reactos/subsystems/win32/win32k/include/misc.h
reactos/subsystems/win32/win32k/include/msgqueue.h
reactos/subsystems/win32/win32k/main/dllmain.c
reactos/subsystems/win32/win32k/ntuser/desktop.c
reactos/subsystems/win32/win32k/ntuser/message.c
reactos/subsystems/win32/win32k/ntuser/misc.c
reactos/subsystems/win32/win32k/ntuser/msgqueue.c
reactos/subsystems/win32/win32k/ntuser/simplecall.c

index 7bcf68c..d000164 100644 (file)
@@ -28,7 +28,7 @@
 
 /* One/Two Param Functions */
 #define NtUserMsqSetWakeMask(dwWaitMask) \
-  (HANDLE)NtUserCallOneParam(dwWaitMask, ONEPARAM_ROUTINE_MSQSETWAKEMASK)
+  (HANDLE)NtUserCallOneParam(dwWaitMask, ONEPARAM_ROUTINE_GETINPUTEVENT)
 
 #define NtUserMsqClearWakeMask() \
   NtUserCallNoParam(NOPARAM_ROUTINE_MSQCLEARWAKEMASK)
index 7df8e25..ff982ee 100644 (file)
@@ -19,8 +19,8 @@
 /*
  *
  * PROJECT:         ReactOS user32.dll
- * FILE:            lib/user32/windows/input.c
- * PURPOSE:         Input
+ * FILE:            dll/win32/user32/windows/hook.c
+ * PURPOSE:         Hooks
  * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
  * UPDATE HISTORY:
  *      09-05-2001  CSH  Created
@@ -155,7 +155,8 @@ CallMsgFilterA(
   int nCode)
 {
   MSG Msg;
-  if (NtCurrentTeb()->Win32ThreadInfo && IsThreadHooked(GetWin32ClientInfo()))
+  if ( NtCurrentTeb()->Win32ThreadInfo &&
+      (ISITHOOKED(WH_MSGFILTER) || ISITHOOKED(WH_SYSMSGFILTER)) )
   {
      if ( lpMsg->message & ~WM_MAXIMUM )
      {
@@ -179,7 +180,8 @@ CallMsgFilterW(
   int nCode)
 {
   MSG Msg;
-  if (NtCurrentTeb()->Win32ThreadInfo && IsThreadHooked(GetWin32ClientInfo()))
+  if ( NtCurrentTeb()->Win32ThreadInfo &&
+      (ISITHOOKED(WH_MSGFILTER) || ISITHOOKED(WH_SYSMSGFILTER)) )
   {
      if ( lpMsg->message & ~WM_MAXIMUM )
      {
index 2645c87..300bfc7 100644 (file)
@@ -2066,14 +2066,16 @@ SendMessageW(HWND Wnd,
   {
       if ( Window != NULL &&
            Window->head.pti == ti &&
-          !IsThreadHooked(GetWin32ClientInfo()) &&
+//          !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
+          !ISITHOOKED(WH_CALLWNDPROC) &&
+          !ISITHOOKED(WH_CALLWNDPROCRET) &&
           !(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
       {
           /* NOTE: We can directly send messages to the window procedure
                    if *all* the following conditions are met:
 
                    * Window belongs to calling thread
-                   * The calling thread is not being hooked
+                   * The calling thread is not being hooked for CallWndProc
                    * Not calling a server side proc:
                      Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
            */
@@ -2137,14 +2139,16 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
   {
       if ( Window != NULL &&
            Window->head.pti == ti &&
-          !IsThreadHooked(GetWin32ClientInfo()) &&
+//          !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
+          !ISITHOOKED(WH_CALLWNDPROC) &&
+          !ISITHOOKED(WH_CALLWNDPROCRET) &&
           !(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
       {
           /* NOTE: We can directly send messages to the window procedure
                    if *all* the following conditions are met:
 
                    * Window belongs to calling thread
-                   * The calling thread is not being hooked
+                   * The calling thread is not being hooked for CallWndProc
                    * Not calling a server side proc: 
                      Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
            */
@@ -2694,9 +2698,8 @@ USER_MESSAGE_PUMP_ADDRESSES gmph = {sizeof(USER_MESSAGE_PUMP_ADDRESSES),
 DWORD gfMessagePumpHook = 0;
 
 BOOL WINAPI IsInsideMessagePumpHook()
-{  // Fixme: Need to fully implement this! FF uses this and polls it when Min/Max
+{  // FF uses this and polls it when Min/Max
    PCLIENTTHREADINFO pcti = GetWin32ClientInfo()->pClientThreadInfo;
-//   FIXME("IIMPH %x\n",pcti);
    return (gfMessagePumpHook && pcti && (pcti->dwcPumpHook > 0));
 }
 
index 64071cb..5c4a335 100644 (file)
@@ -3161,7 +3161,6 @@ typedef struct tagKMDDELPARAM
 #define ONEPARAM_ROUTINE_SWITCHCARETSHOWING   0xfffe0008
 #define ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING 0xfffe000d
 #define ONEPARAM_ROUTINE_GETDESKTOPMAPPING    0xfffe000e
-#define ONEPARAM_ROUTINE_MSQSETWAKEMASK       0xfffe0027
 #define ONEPARAM_ROUTINE_GETCURSORPOSITION    0xfffe0048 // use ONEPARAM_ or TWOPARAM routine ?
 #define TWOPARAM_ROUTINE_GETWINDOWRGNBOX    0xfffd0048 // user mode
 #define TWOPARAM_ROUTINE_GETWINDOWRGN       0xfffd0049 // user mode
index cfe4788..340e9ef 100644 (file)
@@ -24,7 +24,7 @@ extern HGDIOBJ StockObjects[];
 extern SHORT gusLanguageID;
 
 SHORT FASTCALL IntGdiGetLanguageID(VOID);
-DWORD APIENTRY IntGetQueueStatus(BOOL ClearChanges);
+DWORD APIENTRY IntGetQueueStatus(DWORD);
 VOID FASTCALL IntUserManualGuiCheck(LONG Check);
 PVOID APIENTRY HackSecureVirtualMemory(IN PVOID,IN SIZE_T,IN ULONG,OUT PVOID *);
 VOID APIENTRY HackUnsecureVirtualMemory(IN PVOID);
index 4356714..621195c 100644 (file)
@@ -275,4 +275,7 @@ MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount)
     return (LONG)(TickCount->QuadPart * (KeQueryTimeIncrement() / 10000));
 }
 
+VOID FASTCALL IdlePing(VOID);
+VOID FASTCALL IdlePong(VOID);
+
 /* EOF */
index 5ed49f1..d0bbae1 100644 (file)
@@ -279,7 +279,6 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
         { /* Attempt to startup client support which should have been initialized in IntSetThreadDesktop. */
            PCLIENTINFO pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
            Win32Thread->pClientInfo = pci;
-           pci->pClientThreadInfo = NULL;
            pci->ppi = Win32Thread->ppi;
            pci->fsHooks = Win32Thread->fsHooks;
            if (Win32Thread->KeyboardLayout) pci->hKL = Win32Thread->KeyboardLayout->hkl;
@@ -291,6 +290,10 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
 
               pci->pDeskInfo = (PVOID)((ULONG_PTR)Win32Thread->pDeskInfo - pci->ulClientDelta);
            }
+           if (Win32Thread->pcti && pci->pDeskInfo)
+              pci->pClientThreadInfo = (PVOID)((ULONG_PTR)Win32Thread->pcti - pci->ulClientDelta);
+           else
+              pci->pClientThreadInfo = NULL;
         }
         else
         {
@@ -332,6 +335,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
         IntSetThreadDesktop(NULL,
                             TRUE);
 
+
         PsSetThreadWin32Thread(Thread, NULL);
     }
 
index 91b5a53..138b322 100644 (file)
@@ -1835,7 +1835,6 @@ IntUnmapDesktopView(IN PDESKTOP DesktopObject)
 static NTSTATUS
 IntMapDesktopView(IN PDESKTOP DesktopObject)
 {
-    PTHREADINFO ti;
     PPROCESSINFO CurrentWin32Process;
     PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
     PVOID UserBase = NULL;
@@ -1898,19 +1897,6 @@ IntMapDesktopView(IN PDESKTOP DesktopObject)
 
     ObReferenceObject(DesktopObject);
 
-    /* create a W32THREADINFO structure if not already done, or update it */
-    ti = GetW32ThreadInfo();
-    GetWin32ClientInfo()->ulClientDelta = DesktopHeapGetUserDelta();
-    if (ti != NULL)
-    {
-        if (GetWin32ClientInfo()->pDeskInfo == NULL)
-        {
-           GetWin32ClientInfo()->pDeskInfo = 
-                (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - 
-                                          GetWin32ClientInfo()->ulClientDelta);
-        }
-    }
-
     return STATUS_SUCCESS;
 }
 
@@ -1922,6 +1908,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
     PTHREADINFO W32Thread;
     NTSTATUS Status;
     BOOL MapHeap;
+    CLIENTTHREADINFO ctiSave;
 
     DPRINT("IntSetThreadDesktop() DO=%p, FOF=%d\n", DesktopObject, FreeOnFailure);
     MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
@@ -1948,9 +1935,27 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
                 SetLastNtError(Status);
                 return FALSE;
             }
+            W32Thread->pDeskInfo = DesktopObject->pDeskInfo;
+        }
+
+        RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO));
+
+        if (W32Thread->pcti && OldDesktop)
+        {
+           RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO));
+           DPRINT("Free ClientThreadInfo\n");
+           DesktopHeapFree(OldDesktop, W32Thread->pcti);
+           W32Thread->pcti = NULL;
+        }
+
+        if (!W32Thread->pcti && DesktopObject)
+        { 
+           DPRINT("Allocate ClientThreadInfo\n");
+           W32Thread->pcti = DesktopHeapAlloc( DesktopObject,
+                                               sizeof(CLIENTTHREADINFO));
+           RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO));
         }
 
-        /* Hack for system threads */
         if (NtCurrentTeb())
         {
             PCLIENTINFO pci = GetWin32ClientInfo();
@@ -1958,6 +1963,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
             if (DesktopObject)
             {
                 pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta);
+                if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta);
             }
         }
 
index 833e149..8cabf9f 100644 (file)
@@ -1901,7 +1901,7 @@ UserSendNotifyMessage( HWND hWnd,
 
 
 DWORD APIENTRY
-IntGetQueueStatus(BOOL ClearChanges)
+IntGetQueueStatus(DWORD Changes)
 {
     PTHREADINFO pti;
     PUSER_MESSAGE_QUEUE Queue;
@@ -1909,13 +1909,19 @@ IntGetQueueStatus(BOOL ClearChanges)
 
     pti = PsGetCurrentThreadWin32Thread();
     Queue = pti->MessageQueue;
+// wine:
+    Changes &= (QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT);
 
-    Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
-    if (ClearChanges)
+    Result = MAKELONG(Queue->ChangedBits & Changes, Queue->QueueBits & Changes);
+
+    if (pti->pcti)
     {
-        Queue->ChangedBits = 0;
+       pti->pcti->fsChangeBits = Queue->ChangedBits;
+       pti->pcti->fsChangeBits &= ~Changes;
     }
 
+    Queue->ChangedBits &= ~Changes;
+
     return Result;
 }
 
@@ -2089,7 +2095,6 @@ NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
 {
     NTUSERGETMESSAGEINFO Info;
     NTSTATUS Status;
-    /* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
     PMSGMEMORY MsgMemoryEntry;
     PVOID UserMem;
     ULONG Size;
@@ -2110,7 +2115,7 @@ NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
 
     UserLeave();
 
-    Info.Msg = Msg; //.Msg;
+    Info.Msg = Msg;
     /* See if this message type is present in the table */
     MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
 
index 48ef50b..d884d0c 100644 (file)
@@ -125,7 +125,7 @@ NtUserGetThreadState(
          break;
 
       case THREADSTATE_GETINPUTSTATE:
-         ret = HIWORD(IntGetQueueStatus(FALSE)) & (QS_KEY | QS_MOUSEBUTTON);
+         ret = LOWORD(IntGetQueueStatus(QS_POSTMESSAGE|QS_TIMER|QS_PAINT|QS_SENDMESSAGE|QS_INPUT)) & (QS_KEY | QS_MOUSEBUTTON);
          break;
    }
 
@@ -472,8 +472,6 @@ GetW32ThreadInfo(VOID)
     /* initialize it */
     pti->ppi = ppi = GetW32ProcessInfo();
 
-    pti->pcti = &pti->cti; // FIXME Need to set it in desktop.c!
-
     if (pti->rpdesk != NULL)
     {
        pti->pDeskInfo = pti->rpdesk->pDeskInfo;
@@ -494,7 +492,6 @@ GetW32ThreadInfo(VOID)
 
         Teb->Win32ThreadInfo = (PW32THREAD) pti;
 
-        pci->pClientThreadInfo = NULL; // FIXME Need to set it in desktop.c!
         pci->ppi = ppi;
         pci->fsHooks = pti->fsHooks;
         if (pti->KeyboardLayout) pci->hKL = pti->KeyboardLayout->hkl;
@@ -506,6 +503,11 @@ GetW32ThreadInfo(VOID)
 
            pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta);
         }
+        if (pti->pcti && pci->pDeskInfo)
+           pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta);
+        else
+           pci->pClientThreadInfo = NULL;
+
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
index d501aa1..f705aed 100644 (file)
@@ -77,6 +77,11 @@ IntMsqSetWakeMask(DWORD WakeMask)
    MessageQueue->WakeMask = WakeMask;
    MessageEventHandle = MessageQueue->NewMessagesHandle;
 
+   if (Win32Thread->pcti)
+      Win32Thread->pcti->fsWakeMask = WakeMask;
+
+   IdlePing();
+
    return MessageEventHandle;
 }
 
@@ -94,6 +99,11 @@ IntMsqClearWakeMask(VOID)
 // HACK!!!!!!! Newbies that wrote this should hold your head down in shame! (jt)
    MessageQueue->WakeMask = ~0;
 
+   if (Win32Thread->pcti)
+      Win32Thread->pcti->fsWakeMask = 0;
+
+   IdlePong();
+
    return TRUE;
 }
 
index 29d3595..953f936 100644 (file)
@@ -252,7 +252,7 @@ NtUserCallOneParam(
             RETURN( FALSE);
          }
 
-      case ONEPARAM_ROUTINE_MSQSETWAKEMASK:
+      case ONEPARAM_ROUTINE_GETINPUTEVENT:
          RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param));
 
       case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
@@ -269,12 +269,7 @@ NtUserCallOneParam(
 
       case ONEPARAM_ROUTINE_GETQUEUESTATUS:
       {
-         DWORD Ret;
-         WORD changed_bits, wake_bits;
-         Ret = IntGetQueueStatus(FALSE);
-         changed_bits = LOWORD(Ret);
-         wake_bits = HIWORD(Ret);
-         RETURN( MAKELONG(changed_bits & Param, wake_bits & Param));
+         RETURN (IntGetQueueStatus((DWORD)Param));
       }
       case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
          /* FIXME: Should use UserEnterShared */