Adding support for Event hooks. Start using the server info structure and pass the...
authorJames Tabor <james.tabor@reactos.org>
Thu, 17 Apr 2008 01:48:34 +0000 (01:48 +0000)
committerJames Tabor <james.tabor@reactos.org>
Thu, 17 Apr 2008 01:48:34 +0000 (01:48 +0000)
svn path=/trunk/; revision=32993

12 files changed:
reactos/dll/win32/user32/misc/dllmain.c
reactos/dll/win32/user32/windows/hook.c
reactos/include/reactos/win32k/callback.h
reactos/include/reactos/win32k/ntuser.h
reactos/subsystems/win32/win32k/include/callback.h
reactos/subsystems/win32/win32k/include/hook.h
reactos/subsystems/win32/win32k/ntuser/callback.c
reactos/subsystems/win32/win32k/ntuser/event.c [new file with mode: 0644]
reactos/subsystems/win32/win32k/ntuser/hook.c
reactos/subsystems/win32/win32k/ntuser/ntstubs.c
reactos/subsystems/win32/win32k/ntuser/window.c
reactos/subsystems/win32/win32k/win32k.rbuild

index 1682c8e..63c10d8 100644 (file)
@@ -8,6 +8,7 @@ PUSER_HANDLE_TABLE gHandleTable = NULL;
 PUSER_HANDLE_ENTRY gHandleEntries = NULL;
 PW32PROCESSINFO g_pi = NULL; /* User Mode Pointer */
 PW32PROCESSINFO g_kpi = NULL; /* Kernel Mode Pointer */
+PSERVERINFO g_psi = NULL;
 
 PW32PROCESSINFO
 GetW32ProcessInfo(VOID);
@@ -56,9 +57,12 @@ Init(VOID)
       (PVOID)User32SetupDefaultCursors;
    NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] =
       (PVOID)User32CallHookProcFromKernel;
+   NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_EVENTPROC] =
+      (PVOID)User32CallEventProcFromKernel;
 
    g_pi = GetW32ProcessInfo();
    g_kpi = SharedPtrToKernel(g_pi);
+   g_psi = SharedPtrToUser(g_pi->psi);
    gHandleTable = SharedPtrToUser(g_pi->UserHandleTable);
    gHandleEntries = SharedPtrToUser(gHandleTable->handles);
 
index f1ddbd0..227223f 100644 (file)
@@ -33,8 +33,7 @@
 #include <wine/debug.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(user32);
-
-DWORD Bogus_SrvEventActivity = 0; // Fixme, need to ref to share data.
+extern PSERVERINFO g_psi;
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
@@ -263,7 +262,7 @@ NotifyWinEvent(
 // "Servers call NotifyWinEvent to announce the event to the system after the
 // event has occurred; they must never notify the system of an event before
 // the event has occurred." msdn on NotifyWinEvent.
-  if (Bogus_SrvEventActivity & GetMaskFromEvent(event)) // Check to see.
+  if (g_psi->SrvEventActivity & GetMaskFromEvent(event)) // Check to see.
       NtUserNotifyWinEvent(event, hwnd, idObject, idChild);
 }
 
@@ -318,7 +317,7 @@ IsWinEventHookInstalled(
 {
   if ((PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo)
   {
-     return (Bogus_SrvEventActivity & GetMaskFromEvent(event)) != 0;
+     return (g_psi->SrvEventActivity & GetMaskFromEvent(event)) != 0;
   }
   return FALSE;
 }
@@ -454,3 +453,24 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
 
   return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
 }
+
+NTSTATUS STDCALL
+User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+  PEVENTPROC_CALLBACK_ARGUMENTS Common;
+
+  Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Arguments;
+  
+  Common->Proc(Common->hook,
+              Common->event,
+               Common->hwnd,
+           Common->idObject,
+            Common->idChild,
+      Common->dwEventThread,
+      Common->dwmsEventTime);
+  
+  return ZwCallbackReturn(NULL, 0, STATUS_SUCCESS);
+}
+
+
+
index a3d6340..903a457 100644 (file)
@@ -6,7 +6,8 @@
 #define USER32_CALLBACK_LOADSYSMENUTEMPLATE   (2)
 #define USER32_CALLBACK_LOADDEFAULTCURSORS    (3)
 #define USER32_CALLBACK_HOOKPROC              (4)
-#define USER32_CALLBACK_MAXIMUM               (4)
+#define USER32_CALLBACK_EVENTPROC             (5)
+#define USER32_CALLBACK_MAXIMUM               (5)
 
 typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
 {
@@ -50,6 +51,23 @@ typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
   /* WCHAR szClass[] */
 } HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS, *PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS;
 
+typedef VOID (*WINEVENTPROC)(HWINEVENTHOOK,DWORD,HWND,LONG,LONG,DWORD,DWORD);
+
+typedef struct _EVENTPROC_CALLBACK_ARGUMENTS
+{
+  HWINEVENTHOOK hook;
+  DWORD event;
+  HWND hwnd; 
+  LONG idObject;
+  LONG idChild;
+  DWORD dwEventThread;
+  DWORD dwmsEventTime;
+  WINEVENTPROC Proc;
+  BOOLEAN Ansi;
+  UINT ModuleNameLength;
+  WCHAR ModuleName[1];
+} EVENTPROC_CALLBACK_ARGUMENTS, *PEVENTPROC_CALLBACK_ARGUMENTS;
+
 NTSTATUS STDCALL
 User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
 NTSTATUS STDCALL
@@ -60,5 +78,7 @@ NTSTATUS STDCALL
 User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength);
 NTSTATUS STDCALL
 User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
+NTSTATUS STDCALL
+User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
 
 #endif /* __INCLUDE_USER32_CALLBACK_H */
index b670175..4dd7f32 100644 (file)
@@ -1679,7 +1679,7 @@ NtUserNotifyProcessCreate(
     DWORD dwUnknown3,
     DWORD dwUnknown4);
 
-DWORD
+VOID
 NTAPI
 NtUserNotifyWinEvent(
   DWORD Event,
@@ -2345,7 +2345,7 @@ NTAPI
 NtUserUnhookWindowsHookEx(
   HHOOK Hook);
 
-DWORD
+BOOL
 NTAPI
 NtUserUnhookWinEvent(
   HWINEVENTHOOK hWinEventHook);
index 99ac6eb..f9ca3cc 100644 (file)
@@ -35,6 +35,16 @@ co_IntCallHookProc(INT HookId,
                 BOOLEAN Ansi,
                 PUNICODE_STRING ModuleName);
 
+LRESULT STDCALL
+co_IntCallEventProc(HWINEVENTHOOK hook,
+                           DWORD event,
+                             HWND hwnd,
+                         LONG idObject,
+                          LONG idChild,
+                   DWORD dwEventThread,
+                   DWORD dwmsEventTime,
+                     WINEVENTPROC Proc);
+
 VOID FASTCALL
 IntCleanupThreadCallbacks(PW32THREAD W32Thread);
 
index 1c160e0..2eb0aca 100644 (file)
@@ -23,7 +23,27 @@ typedef struct tagHOOKTABLE
   UINT       Counts[NB_HOOKS]; /* use counts for each hook chain */
 } HOOKTABLE, *PHOOKTABLE;
 
+typedef struct tagEVENTHOOK
+{
+  LIST_ENTRY     Chain;      /* Event chain entry */
+  HWINEVENTHOOK  Self;       /* user handle for this event */
+  PETHREAD       Thread;     /* Thread owning the event */
+  UINT           eventMin;
+  UINT           eventMax; 
+  WINEVENTPROC   Proc;       /* Event function */
+  BOOLEAN        Ansi;       /* Is it an Ansi event? */
+  ULONG          Flags;      /* Some internal flags */
+  UNICODE_STRING ModuleName; /* Module name for global events */
+} EVENTHOOK, *PEVENTHOOK;
+
+typedef struct tagEVENTTABLE
+{
+  LIST_ENTRY Events;
+  UINT       Counts;
+} EVENTTABLE, *PEVENTTABLE;
+
 LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam);
+LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, LONG, LONG);
 VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread);
 PHOOK FASTCALL IntGetHookObject(HHOOK);
 
index 0ee8fd9..335d909 100644 (file)
@@ -465,4 +465,69 @@ co_IntCallHookProc(INT HookId,
    return Result;
 }
 
+LRESULT
+STDCALL
+co_IntCallEventProc(HWINEVENTHOOK hook,
+                           DWORD event,
+                             HWND hWnd,
+                         LONG idObject,
+                          LONG idChild,
+                   DWORD dwEventThread,
+                   DWORD dwmsEventTime,
+                     WINEVENTPROC Proc)
+{
+   LRESULT Result;
+   NTSTATUS Status;
+   PEVENTPROC_CALLBACK_ARGUMENTS Common;
+   ULONG ArgumentLength, ResultLength;
+   PVOID Argument, ResultPointer, pWnd;
+
+   ArgumentLength = sizeof(EVENTPROC_CALLBACK_ARGUMENTS);
+
+   Argument = IntCbAllocateMemory(ArgumentLength);
+   if (NULL == Argument)
+   {
+      DPRINT1("EventProc callback failed: out of memory\n");
+      return 0;
+   }
+   Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Argument;
+   Common->hook = hook;
+   Common->event = event;
+   Common->hwnd = hWnd;
+   Common->idObject = idObject;
+   Common->idChild = idChild;
+   Common->dwEventThread = dwEventThread;
+   Common->dwmsEventTime = dwmsEventTime;
+   Common->Proc = Proc;
+
+   ResultPointer = NULL;
+   ResultLength = sizeof(LRESULT);
+
+   IntSetTebWndCallback (&hWnd, &pWnd);
+
+   UserLeaveCo();
+
+   Status = KeUserModeCallback(USER32_CALLBACK_EVENTPROC,
+                               Argument,
+                               ArgumentLength,
+                               &ResultPointer,
+                               &ResultLength);
+
+   /* Simulate old behaviour: copy into our local buffer */
+   Result = *(LRESULT*)ResultPointer;
+
+   UserEnterCo();
+
+   IntRestoreTebWndCallback (hWnd, pWnd);
+
+   IntCbFreeMemory(Argument);
+  
+   if (!NT_SUCCESS(Status))
+   {
+      return 0;
+   }
+
+   return Result;
+}
+
 /* EOF */
diff --git a/reactos/subsystems/win32/win32k/ntuser/event.c b/reactos/subsystems/win32/win32k/ntuser/event.c
new file mode 100644 (file)
index 0000000..76c34f6
--- /dev/null
@@ -0,0 +1,124 @@
+
+#include <w32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+extern PSERVERINFO gpsi;
+//static PEVENTTABLE GlobalEvents;
+
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+static
+DWORD
+FASTCALL
+GetMaskFromEvent(DWORD Event)
+{
+  DWORD Ret = 0;
+
+  if ( Event > EVENT_OBJECT_STATECHANGE )
+  {
+    if ( Event == EVENT_OBJECT_LOCATIONCHANGE ) return SRV_EVENT_LOCATIONCHANGE;
+    if ( Event == EVENT_OBJECT_NAMECHANGE )     return SRV_EVENT_NAMECHANGE;
+    if ( Event == EVENT_OBJECT_VALUECHANGE )    return SRV_EVENT_VALUECHANGE;
+    return SRV_EVENT_CREATE;
+  }
+
+  if ( Event == EVENT_OBJECT_STATECHANGE ) return SRV_EVENT_STATECHANGE;
+
+  Ret = SRV_EVENT_RUNNING;
+
+  if ( Event < EVENT_SYSTEM_MENUSTART )    return SRV_EVENT_CREATE;
+
+  if ( Event <= EVENT_SYSTEM_MENUPOPUPEND )
+  {
+    Ret = SRV_EVENT_MENU;
+  }
+  else
+  {
+    if ( Event <= EVENT_CONSOLE_CARET-1 )         return SRV_EVENT_CREATE;
+    if ( Event <= EVENT_CONSOLE_END_APPLICATION ) return SRV_EVENT_END_APPLICATION;
+    if ( Event != EVENT_OBJECT_FOCUS )            return SRV_EVENT_CREATE;
+  }
+  return Ret;
+}
+
+
+static
+DWORD
+FASTCALL
+TimeStamp(VOID)
+{
+ return (DWORD)((ULONGLONG)SharedUserData->TickCountLowDeprecated * SharedUserData->TickCountMultiplier / 16777216);
+}
+
+/* FUNCTIONS *****************************************************************/
+
+LRESULT
+FASTCALL
+co_EVENT_CallEvents( DWORD event,
+                       HWND hwnd, 
+                   LONG idObject,
+                    LONG idChild)
+{
+
+   PEVENTHOOK peh = UserHeapAlloc(sizeof(EVENTHOOK));
+
+   if ((gpsi->SrvEventActivity & GetMaskFromEvent(event))) return 0; // No events to run.
+
+   LRESULT Result = co_IntCallEventProc(peh->Self,
+                                            event,
+                                             hwnd,
+                                         idObject,
+                                          idChild,
+        (DWORD)(NtCurrentTeb()->Cid).UniqueThread,
+                                      TimeStamp(),
+                                        peh->Proc);
+   return Result;
+}
+
+
+VOID
+STDCALL
+NtUserNotifyWinEvent(
+   DWORD Event,
+   HWND  hWnd,
+   LONG  idObject,
+   LONG  idChild)
+{
+   UNIMPLEMENTED
+}
+
+HWINEVENTHOOK
+STDCALL
+NtUserSetWinEventHook(
+   UINT eventMin,
+   UINT eventMax,
+   HMODULE hmodWinEventProc,
+   PUNICODE_STRING puString,
+   WINEVENTPROC lpfnWinEventProc,
+   DWORD idProcess,
+   DWORD idThread,
+   UINT dwflags)
+{
+   gpsi->SrvEventActivity |= GetMaskFromEvent(eventMin);
+   gpsi->SrvEventActivity &= ~GetMaskFromEvent(eventMin);
+
+   UNIMPLEMENTED
+
+   return 0;
+}
+
+
+BOOL
+STDCALL
+NtUserUnhookWinEvent(
+   HWINEVENTHOOK hWinEventHook)
+{
+   UNIMPLEMENTED
+
+   return FALSE;
+}
+
+/* EOF */
index 315ca64..11ef68e 100644 (file)
@@ -1,26 +1,8 @@
-/*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
 /*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Window hooks
- * FILE:             subsys/win32k/ntuser/hook.c
+ * FILE:             subsystem/win32/win32k/ntuser/hook.c
  * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
  * REVISION HISTORY:
  *       06-06-2001  CSH  Created
 #define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
 
 static PHOOKTABLE GlobalHooks;
-DWORD Bogus_SrvEventActivity = 0;
 
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
-static
-DWORD
-FASTCALL
-GetMaskFromEvent(DWORD Event)
-{
-  DWORD Ret = 0;
-
-  if ( Event > EVENT_OBJECT_STATECHANGE )
-  {
-    if ( Event == EVENT_OBJECT_LOCATIONCHANGE ) return SRV_EVENT_LOCATIONCHANGE;
-    if ( Event == EVENT_OBJECT_NAMECHANGE )     return SRV_EVENT_NAMECHANGE;
-    if ( Event == EVENT_OBJECT_VALUECHANGE )    return SRV_EVENT_VALUECHANGE;
-    return SRV_EVENT_CREATE;
-  }
-
-  if ( Event == EVENT_OBJECT_STATECHANGE ) return SRV_EVENT_STATECHANGE;
-
-  Ret = SRV_EVENT_RUNNING;
-
-  if ( Event < EVENT_SYSTEM_MENUSTART )    return SRV_EVENT_CREATE;
-
-  if ( Event <= EVENT_SYSTEM_MENUPOPUPEND )
-  {
-    Ret = SRV_EVENT_MENU;
-  }
-  else
-  {
-    if ( Event <= EVENT_CONSOLE_CARET-1 )         return SRV_EVENT_CREATE;
-    if ( Event <= EVENT_CONSOLE_END_APPLICATION ) return SRV_EVENT_END_APPLICATION;
-    if ( Event != EVENT_OBJECT_FOCUS )            return SRV_EVENT_CREATE;
-  }
-  return Ret;
-}
 
 /* create a new hook table */
 static PHOOKTABLE
@@ -734,25 +682,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-HWINEVENTHOOK
-STDCALL
-NtUserSetWinEventHook(
-   UINT eventMin,
-   UINT eventMax,
-   HMODULE hmodWinEventProc,
-   PUNICODE_STRING puString,
-   WINEVENTPROC lpfnWinEventProc,
-   DWORD idProcess,
-   DWORD idThread,
-   UINT dwflags)
-{
-
-   Bogus_SrvEventActivity |= GetMaskFromEvent(eventMin); // Fake it out for now.
-   Bogus_SrvEventActivity &= ~GetMaskFromEvent(eventMin);
-   UNIMPLEMENTED
-
-   return 0;
-}
 
 BOOL
 STDCALL
@@ -801,15 +730,5 @@ CLEANUP:
    UserLeave();
    END_CLEANUP;
 }
-
-DWORD
-STDCALL
-NtUserUnhookWinEvent(
-   HWINEVENTHOOK hWinEventHook)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
 /* EOF */
index f6f0795..1d1d1a8 100644 (file)
@@ -426,19 +426,6 @@ NtUserNotifyIMEStatus(
    return 0;
 }
 
-DWORD
-STDCALL
-NtUserNotifyWinEvent(
-   DWORD Event,
-   HWND  hWnd,
-   LONG  idObject,
-   LONG  idChild)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
 DWORD
 STDCALL
 NtUserQueryUserCounters(
index aeed206..7c3b3bc 100644 (file)
@@ -2056,7 +2056,7 @@ AllocErr:
       IntUnlinkWindow(Window);
       RETURN((HWND)0);
    }
-#if 0
+
    Result = co_EVENT_CallEvents(EVENT_OBJECT_CREATE, Window->hSelf, OBJID_WINDOW, 0);
 
    if (Result == (LRESULT)-1)
@@ -2065,7 +2065,7 @@ AllocErr:
       DPRINT1("IntCreateWindowEx(): event CREATE hook failed. No cleanup performed!\n");
       RETURN((HWND)0);
    }
-#endif
+
    /* Send move and size messages. */
    if (!(Window->Flags & WINDOWOBJECT_NEED_SIZE))
    {
index 6994b36..611e2e0 100644 (file)
                <file>csr.c</file>
                <file>cursoricon.c</file>
                <file>desktop.c</file>
+               <file>event.c</file>
                <file>focus.c</file>
                <file>guicheck.c</file>
                <file>hook.c</file>