Incomplete implementation of hooks

svn path=/trunk/; revision=6965
This commit is contained in:
Gé van Geldorp 2003-12-12 14:22:37 +00:00
parent dc8bfd1046
commit ae68da49b6
22 changed files with 1376 additions and 120 deletions

View file

@ -815,13 +815,18 @@ extern "C" {
#define WH_JOURNALPLAYBACK (1) #define WH_JOURNALPLAYBACK (1)
#define WH_JOURNALRECORD (0) #define WH_JOURNALRECORD (0)
#define WH_KEYBOARD (2) #define WH_KEYBOARD (2)
#define WH_KEYBOARD_LL (13)
#define WH_MOUSE (7) #define WH_MOUSE (7)
#define WH_MOUSE_LL (14)
#define WH_MSGFILTER (-1) #define WH_MSGFILTER (-1)
#define WH_SHELL (10) #define WH_SHELL (10)
#define WH_SYSMSGFILTER (6) #define WH_SYSMSGFILTER (6)
#define WH_MSGFILTER (-1) #define WH_MSGFILTER (-1)
#define WH_FOREGROUNDIDLE (11) #define WH_FOREGROUNDIDLE (11)
#define WH_MINHOOK (-1)
#define WH_MAXHOOK (14)
/* DefineDosDevice */ /* DefineDosDevice */
#define DDD_RAW_TARGET_PATH (1) #define DDD_RAW_TARGET_PATH (1)
#define DDD_REMOVE_DEFINITION (2) #define DDD_REMOVE_DEFINITION (2)

View file

@ -13,7 +13,8 @@
#define USER32_CALLBACK_SENDSTYLECHANGED (9) #define USER32_CALLBACK_SENDSTYLECHANGED (9)
#define USER32_CALLBACK_LOADSYSMENUTEMPLATE (10) #define USER32_CALLBACK_LOADSYSMENUTEMPLATE (10)
#define USER32_CALLBACK_LOADDEFAULTCURSORS (11) #define USER32_CALLBACK_LOADDEFAULTCURSORS (11)
#define USER32_CALLBACK_MAXIMUM (11) #define USER32_CALLBACK_HOOKPROC (12)
#define USER32_CALLBACK_MAXIMUM (12)
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
{ {
@ -101,6 +102,26 @@ typedef struct _SENDSTYLECHANGED_CALLBACK_ARGUMENTS
DWORD WhichStyle; DWORD WhichStyle;
} SENDSTYLECHANGED_CALLBACK_ARGUMENTS, *PSENDSTYLECHANGED_CALLBACK_ARGUMENTS; } SENDSTYLECHANGED_CALLBACK_ARGUMENTS, *PSENDSTYLECHANGED_CALLBACK_ARGUMENTS;
typedef struct _HOOKPROC_CALLBACK_ARGUMENTS
{
INT HookId;
INT Code;
WPARAM wParam;
LPARAM lParam;
HOOKPROC Proc;
BOOLEAN Ansi;
UINT ModuleNameLength;
WCHAR ModuleName[1];
} HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS;
typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
{
CREATESTRUCTW Cs; /* lpszName and lpszClass replaced by offsets */
HWND WndInsertAfter;
/* WCHAR szName[] */
/* WCHAR szClass[] */
} HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS, *PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS;
NTSTATUS STDCALL NTSTATUS STDCALL
User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength); User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL NTSTATUS STDCALL
@ -125,5 +146,7 @@ NTSTATUS STDCALL
User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength); User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL NTSTATUS STDCALL
User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength); User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL
User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
#endif /* __INCLUDE_USER32_CALLBACK_H */ #endif /* __INCLUDE_USER32_CALLBACK_H */

View file

@ -152,13 +152,13 @@ NtUserCallMsgFilter(
DWORD Unknown0, DWORD Unknown0,
DWORD Unknown1); DWORD Unknown1);
DWORD LRESULT
STDCALL STDCALL
NtUserCallNextHookEx( NtUserCallNextHookEx(
DWORD Unknown0, HHOOK Hook,
DWORD Unknown1, int Code,
DWORD Unknown2, WPARAM wParam,
DWORD Unknown3); LPARAM lParam);
#define NOPARAM_ROUTINE_REGISTER_PRIMITIVE 0xffff0001 /* Private ROS */ #define NOPARAM_ROUTINE_REGISTER_PRIMITIVE 0xffff0001 /* Private ROS */
#define NOPARAM_ROUTINE_DESTROY_CARET 0xffff0002 #define NOPARAM_ROUTINE_DESTROY_CARET 0xffff0002
@ -1566,15 +1566,15 @@ NtUserSetWindowsHookAW(
DWORD Unknown1, DWORD Unknown1,
DWORD Unknown2); DWORD Unknown2);
DWORD HHOOK
STDCALL STDCALL
NtUserSetWindowsHookEx( NtUserSetWindowsHookEx(
DWORD Unknown0, HINSTANCE Mod,
DWORD Unknown1, PUNICODE_STRING ModuleName,
DWORD Unknown2, DWORD ThreadId,
DWORD Unknown3, int HookId,
DWORD Unknown4, HOOKPROC HookProc,
DWORD Unknown5); BOOL Ansi);
DWORD DWORD
STDCALL STDCALL
@ -1688,10 +1688,10 @@ NtUserTranslateMessage(
LPMSG lpMsg, LPMSG lpMsg,
HKL dwhkl ); HKL dwhkl );
DWORD BOOL
STDCALL STDCALL
NtUserUnhookWindowsHookEx( NtUserUnhookWindowsHookEx(
DWORD Unknown0); HHOOK Hook);
DWORD DWORD
STDCALL STDCALL

View file

@ -2,7 +2,7 @@
#define __WINE_DEBUG_H #define __WINE_DEBUG_H
#include "../roscfg.h" #include "../roscfg.h"
#ifndef DBG #if ! defined(DBG) || ! defined(YDEBUG)
#define NDEBUG #define NDEBUG
#endif #endif
#include "../debug.h" #include "../debug.h"

View file

@ -1,4 +1,4 @@
/* $Id: stubs.c,v 1.40 2003/11/16 22:44:39 sedwards Exp $ /* $Id: stubs.c,v 1.41 2003/12/12 14:22:36 gvg Exp $
* *
* reactos/lib/gdi32/misc/stubs.c * reactos/lib/gdi32/misc/stubs.c
* *
@ -513,28 +513,6 @@ InvertRgn(
return FALSE; return FALSE;
} }
/*
* @unimplemented
*/
BOOL
STDCALL
Pie(
HDC a0,
int a1,
int a2,
int a3,
int a4,
int a5,
int a6,
int a7,
int a8
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/* /*
* @unimplemented * @unimplemented
*/ */

View file

@ -81,3 +81,23 @@ Ellipse(HDC hDc,
{ {
return NtGdiEllipse(hDc, Left, Top, Right, Bottom); return NtGdiEllipse(hDc, Left, Top, Right, Bottom);
} }
/*
* @implemented
*/
BOOL
STDCALL
Pie(HDC hDc,
int Left,
int Top,
int Right,
int Bottom,
int XRadialStart,
int YRadialStart,
int XRadialEnd,
int YRadialEnd)
{
return NtGdiPie(hDc, Left, Top, Right, Bottom, XRadialStart, YRadialStart,
XRadialEnd, YRadialEnd);
}

View file

@ -185,7 +185,7 @@ static HRESULT WINAPI IStream_fnSetSize(IStream *iface, ULARGE_INTEGER libNewSiz
ICOM_THIS(ISHFileStream, iface); ICOM_THIS(ISHFileStream, iface);
#endif #endif
TRACE("(%p,%ld)\n", This, libNewSize.s.LowPart); TRACE("(%p,%ld)\n", This, libNewSize.u.LowPart);
IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */
return E_NOTIMPL; return E_NOTIMPL;
} }
@ -203,7 +203,7 @@ static HRESULT WINAPI IStream_fnCopyTo(IStream *iface, IStream* pstm, ULARGE_INT
ULONGLONG ulSize; ULONGLONG ulSize;
HRESULT hRet = S_OK; HRESULT hRet = S_OK;
TRACE("(%p,%p,%ld,%p,%p)\n", This, pstm, cb.s.LowPart, pcbRead, pcbWritten); TRACE("(%p,%p,%ld,%p,%p)\n", This, pstm, cb.u.LowPart, pcbRead, pcbWritten);
if (pcbRead) if (pcbRead)
pcbRead->QuadPart = 0; pcbRead->QuadPart = 0;
@ -278,7 +278,7 @@ static HRESULT WINAPI IStream_fnLockUnlockRegion(IStream *iface, ULARGE_INTEGER
#ifndef NDEBUG #ifndef NDEBUG
ICOM_THIS(ISHFileStream, iface); ICOM_THIS(ISHFileStream, iface);
#endif #endif
TRACE("(%p,%ld,%ld,%ld)\n", This, libOffset.s.LowPart, cb.s.LowPart, dwLockType); TRACE("(%p,%ld,%ld,%ld)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType);
return E_NOTIMPL; return E_NOTIMPL;
} }

View file

@ -19,6 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifdef DBG
#undef DBG
#define DBG 1
#endif
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#ifdef __REACTOS__ #ifdef __REACTOS__

View file

@ -78,6 +78,8 @@ Init(VOID)
(PVOID)User32LoadSysMenuTemplateForKernel; (PVOID)User32LoadSysMenuTemplateForKernel;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] = NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] =
(PVOID)User32SetupDefaultCursors; (PVOID)User32SetupDefaultCursors;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] =
(PVOID)User32CallHookProcFromKernel;
/* Allocate an index for user32 thread local data. */ /* Allocate an index for user32 thread local data. */
User32TlsIndex = TlsAlloc(); User32TlsIndex = TlsAlloc();

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: hook.c,v 1.11 2003/11/09 13:50:04 navaraf Exp $ /* $Id: hook.c,v 1.12 2003/12/12 14:22:37 gvg Exp $
* *
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c * FILE: lib/user32/windows/input.c
@ -30,20 +30,22 @@
#include <windows.h> #include <windows.h>
#include <user32.h> #include <user32.h>
#include <user32/callback.h>
#define NDEBUG
#include <debug.h> #include <debug.h>
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* /*
* @unimplemented * @implemented
*/ */
WINBOOL WINBOOL
STDCALL STDCALL
UnhookWindowsHookEx( UnhookWindowsHookEx(
HHOOK hhk) HHOOK Hook)
{ {
UNIMPLEMENTED; return NtUserUnhookWindowsHookEx(Hook);
return FALSE;
} }
#if 0 #if 0
WINBOOL WINBOOL
@ -92,13 +94,41 @@ CallMsgFilterW(
LRESULT LRESULT
STDCALL STDCALL
CallNextHookEx( CallNextHookEx(
HHOOK hhk, HHOOK Hook,
int nCode, int Code,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
UNIMPLEMENTED; return NtUserCallNextHookEx(Hook, Code, wParam, lParam);
return (LRESULT)0; }
STATIC
HHOOK
FASTCALL
IntSetWindowsHook(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId,
BOOL bAnsi)
{
WCHAR ModuleName[MAX_PATH];
UNICODE_STRING USModuleName;
if (NULL != hMod)
{
if (0 == GetModuleFileNameW(hMod, ModuleName, MAX_PATH))
{
return NULL;
}
RtlInitUnicodeString(&USModuleName, ModuleName);
}
else
{
RtlInitUnicodeString(&USModuleName, NULL);
}
return NtUserSetWindowsHookEx(hMod, &USModuleName, dwThreadId, idHook, lpfn, bAnsi);
} }
/* /*
@ -106,10 +136,9 @@ CallNextHookEx(
*/ */
HHOOK HHOOK
STDCALL STDCALL
SetWindowsHookW ( int idHook, HOOKPROC lpfn ) SetWindowsHookW(int idHook, HOOKPROC lpfn)
{ {
UNIMPLEMENTED; return IntSetWindowsHook(idHook, lpfn, NULL, 0, FALSE);
return FALSE;
} }
/* /*
@ -117,10 +146,9 @@ SetWindowsHookW ( int idHook, HOOKPROC lpfn )
*/ */
HHOOK HHOOK
STDCALL STDCALL
SetWindowsHookA ( int idHook, HOOKPROC lpfn ) SetWindowsHookA(int idHook, HOOKPROC lpfn)
{ {
UNIMPLEMENTED; return IntSetWindowsHook(idHook, lpfn, NULL, 0, TRUE);
return FALSE;
} }
/* /*
@ -225,8 +253,7 @@ SetWindowsHookExA(
HINSTANCE hMod, HINSTANCE hMod,
DWORD dwThreadId) DWORD dwThreadId)
{ {
UNIMPLEMENTED; return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, TRUE);
return 0;
} }
@ -241,7 +268,89 @@ SetWindowsHookExW(
HINSTANCE hMod, HINSTANCE hMod,
DWORD dwThreadId) DWORD dwThreadId)
{ {
UNIMPLEMENTED; return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE);
return 0;
} }
NTSTATUS STDCALL
User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{
PHOOKPROC_CALLBACK_ARGUMENTS Common;
LRESULT Result;
CREATESTRUCTW Csw;
CBT_CREATEWNDW CbtCreatewndw;
UNICODE_STRING UString;
CREATESTRUCTA Csa;
CBT_CREATEWNDA CbtCreatewnda;
ANSI_STRING AString;
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra;
WPARAM wParam;
LPARAM lParam;
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
switch(Common->HookId)
{
case WH_CBT:
switch(Common->Code)
{
case HCBT_CREATEWND:
CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS)
((PCHAR) Common + Common->lParam);
Csw = CbtCreatewndExtra->Cs;
Csw.lpszName = (LPCWSTR)((PCHAR) CbtCreatewndExtra
+ (ULONG) CbtCreatewndExtra->Cs.lpszName);
if (0 != HIWORD(CbtCreatewndExtra->Cs.lpszClass))
{
Csw.lpszClass = (LPCWSTR)((PCHAR) CbtCreatewndExtra
+ LOWORD((ULONG) CbtCreatewndExtra->Cs.lpszClass));
}
wParam = Common->wParam;
if (Common->Ansi)
{
memcpy(&Csa, &Csw, sizeof(CREATESTRUCTW));
RtlInitUnicodeString(&UString, Csw.lpszName);
RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
Csa.lpszName = AString.Buffer;
if (0 != HIWORD(Csw.lpszClass))
{
RtlInitUnicodeString(&UString, Csw.lpszClass);
RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
Csa.lpszClass = AString.Buffer;
}
CbtCreatewnda.lpcs = &Csa;
CbtCreatewnda.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
lParam = (LPARAM) &CbtCreatewnda;
}
else
{
CbtCreatewndw.lpcs = &Csw;
CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
lParam = (LPARAM) &CbtCreatewndw;
}
break;
default:
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
}
Result = Common->Proc(Common->Code, wParam, lParam);
switch(Common->Code)
{
case HCBT_CREATEWND:
if (Common->Ansi)
{
if (0 != HIWORD(Csa.lpszClass))
{
RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR) Csa.lpszClass);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR) Csa.lpszName);
}
break;
}
break;
default:
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
}
return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
}

View file

@ -49,4 +49,13 @@ IntLoadSysMenuTemplate();
BOOL STDCALL BOOL STDCALL
IntLoadDefaultCursors(BOOL SetDefault); IntLoadDefaultCursors(BOOL SetDefault);
LRESULT STDCALL
IntCallHookProc(INT HookId,
INT Code,
WPARAM wParam,
LPARAM lParam,
HOOKPROC Proc,
BOOLEAN Ansi,
PUNICODE_STRING ModuleName);
#endif /* _WIN32K_CALLBACK_H */ #endif /* _WIN32K_CALLBACK_H */

View file

@ -0,0 +1,32 @@
#ifndef _WIN32K_HOOK_H
#define _WIN32K_HOOK_H
#include <windows.h>
#include <internal/ps.h>
typedef struct tagHOOK
{
LIST_ENTRY Chain; /* Hook chain entry */
HHOOK Self; /* user handle for this hook */
PETHREAD Thread; /* Thread owning the hook */
int HookId; /* Hook table index */
HOOKPROC Proc; /* Hook function */
BOOLEAN Ansi; /* Is it an Ansi hook? */
UNICODE_STRING ModuleName; /* Module name for global hooks */
} HOOK, *PHOOK;
#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
typedef struct tagHOOKTABLE
{
FAST_MUTEX Lock;
LIST_ENTRY Hooks[NB_HOOKS]; /* array of hook chains */
UINT Counts[NB_HOOKS]; /* use counts for each hook chain */
} HOOKTABLE, *PHOOKTABLE;
LRESULT FASTCALL HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam);
VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread);
#endif /* _WIN32K_HOOK_H */
/* EOF */

View file

@ -3,6 +3,7 @@
#include <internal/ex.h> #include <internal/ex.h>
#include <windows.h> #include <windows.h>
#include "hook.h"
typedef struct _USER_MESSAGE typedef struct _USER_MESSAGE
{ {
@ -73,6 +74,8 @@ typedef struct _USER_MESSAGE_QUEUE
HWND MenuOwner; HWND MenuOwner;
/* Identifes the menu state */ /* Identifes the menu state */
BYTE MenuState; BYTE MenuState;
/* Window hooks */
PHOOKTABLE Hooks;
/* queue state tracking */ /* queue state tracking */
WORD WakeBits; WORD WakeBits;
@ -150,6 +153,9 @@ BOOL IntInitMessagePumpHook();
BOOL IntUninitMessagePumpHook(); BOOL IntUninitMessagePumpHook();
#define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
PHOOKTABLE FASTCALL MsqGetHooks(PUSER_MESSAGE_QUEUE Queue);
VOID FASTCALL MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks);
#endif /* _WIN32K_MSGQUEUE_H */ #endif /* _WIN32K_MSGQUEUE_H */
/* EOF */ /* EOF */

View file

@ -12,7 +12,8 @@ typedef enum {
otWindow, otWindow,
otMenu, otMenu,
otAcceleratorTable, otAcceleratorTable,
otCursorIcon otCursorIcon,
otHookProc
} USER_OBJECT_TYPE; } USER_OBJECT_TYPE;
typedef struct _USER_OBJECT_HEADER typedef struct _USER_OBJECT_HEADER

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dllmain.c,v 1.59 2003/12/07 23:02:57 gvg Exp $ /* $Id: dllmain.c,v 1.60 2003/12/12 14:22:37 gvg Exp $
* *
* Entry Point for win32k.sys * Entry Point for win32k.sys
*/ */
@ -43,6 +43,7 @@
#include <include/hotkey.h> #include <include/hotkey.h>
#include <include/accelerator.h> #include <include/accelerator.h>
#include <include/guicheck.h> #include <include/guicheck.h>
#include <include/hook.h>
#define NDEBUG #define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
@ -161,6 +162,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
DbgPrint (" Destroy thread\n"); DbgPrint (" Destroy thread\n");
#endif #endif
HOOK_DestroyThreadHooks(Thread);
RemoveTimersThread(Thread->Cid.UniqueThread); RemoveTimersThread(Thread->Cid.UniqueThread);
UnregisterThreadHotKeys(Thread); UnregisterThreadHotKeys(Thread);
DestroyThreadWindows(Thread); DestroyThreadWindows(Thread);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: object.c,v 1.6 2003/05/18 17:16:17 ea Exp $ /* $Id: object.c,v 1.7 2003/12/12 14:22:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -66,13 +66,13 @@ ObmpPerformRetentionChecks(PUSER_OBJECT_HEADER ObjectHeader)
{ {
if (ObjectHeader->RefCount < 0) if (ObjectHeader->RefCount < 0)
{ {
DbgPrint("ObjectHeader 0x%X has invalid reference count (%d)\n", DPRINT1("ObjectHeader 0x%X has invalid reference count (%d)\n",
ObjectHeader, ObjectHeader->RefCount); ObjectHeader, ObjectHeader->RefCount);
} }
if (ObjectHeader->HandleCount < 0) if (ObjectHeader->HandleCount < 0)
{ {
DbgPrint("Object 0x%X has invalid handle count (%d)\n", DPRINT1("Object 0x%X has invalid handle count (%d)\n",
ObjectHeader, ObjectHeader->HandleCount); ObjectHeader, ObjectHeader->HandleCount);
} }
@ -101,6 +101,11 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
PLIST_ENTRY Current; PLIST_ENTRY Current;
ULONG i; ULONG i;
if (NULL == Handle)
{
return NULL;
}
Current = HandleTable->ListHead.Flink; Current = HandleTable->ListHead.Flink;
for (i = 0; i < Count; i++) for (i = 0; i < Count; i++)
@ -108,6 +113,7 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
Current = Current->Flink; Current = Current->Flink;
if (Current == &(HandleTable->ListHead)) if (Current == &(HandleTable->ListHead))
{ {
DPRINT1("Invalid handle\n");
return NULL; return NULL;
} }
} }
@ -195,6 +201,7 @@ ObmpDeleteHandle(PUSER_HANDLE_TABLE HandleTable,
Entry = ObmpGetObjectByHandle(HandleTable, Handle); Entry = ObmpGetObjectByHandle(HandleTable, Handle);
if (Entry == NULL) if (Entry == NULL)
{ {
DPRINT1("Invalid handle\n");
ObmpUnlockHandleTable(HandleTable); ObmpUnlockHandleTable(HandleTable);
return NULL; return NULL;
} }
@ -404,7 +411,7 @@ ObmCreateHandle(PUSER_HANDLE_TABLE HandleTable,
Block->Handles[i].ObjectBody = ObjectBody; Block->Handles[i].ObjectBody = ObjectBody;
ObmpUnlockHandleTable(HandleTable); ObmpUnlockHandleTable(HandleTable);
*HandleReturn = (HANDLE)((Handle + i) << 2); *HandleReturn = (HANDLE)((Handle + i) << 2);
return ERROR_SUCCESS; return STATUS_SUCCESS;
} }
} }
@ -419,6 +426,7 @@ ObmCreateHandle(PUSER_HANDLE_TABLE HandleTable,
sizeof(USER_HANDLE_BLOCK)); sizeof(USER_HANDLE_BLOCK));
if (!NewBlock) if (!NewBlock)
{ {
DPRINT1("Unable to allocate new handle block\n");
*HandleReturn = (PHANDLE)NULL; *HandleReturn = (PHANDLE)NULL;
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -471,6 +479,7 @@ ObmReferenceObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType)) if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType))
{ {
DPRINT1("Object type mismatch\n");
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -518,6 +527,7 @@ ObmCreateHandleTable(VOID)
sizeof(USER_HANDLE_TABLE)); sizeof(USER_HANDLE_TABLE));
if (!HandleTable) if (!HandleTable)
{ {
DPRINT1("Unable to create handle table\n");
return NULL; return NULL;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: callback.c,v 1.18 2003/12/07 23:02:57 gvg Exp $ /* $Id: callback.c,v 1.19 2003/12/12 14:22:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -43,6 +43,8 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#define TAG_CALLBACK TAG('C', 'B', 'C', 'K')
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID STDCALL VOID STDCALL
@ -417,4 +419,111 @@ IntLoadDefaultCursors(BOOL SetDefault)
return (BOOL)Result; return (BOOL)Result;
} }
LRESULT STDCALL
IntCallHookProc(INT HookId,
INT Code,
WPARAM wParam,
LPARAM lParam,
HOOKPROC Proc,
BOOLEAN Ansi,
PUNICODE_STRING ModuleName)
{
ULONG ArgumentLength;
PVOID Argument;
LRESULT Result;
NTSTATUS Status;
PVOID ResultPointer;
ULONG ResultLength;
PHOOKPROC_CALLBACK_ARGUMENTS Common;
CBT_CREATEWNDW *CbtCreateWnd;
PCHAR Extra;
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra;
ArgumentLength = sizeof(HOOKPROC_CALLBACK_ARGUMENTS) - sizeof(WCHAR)
+ ModuleName->Length;
switch(HookId)
{
case WH_CBT:
switch(Code)
{
case HCBT_CREATEWND:
CbtCreateWnd = (CBT_CREATEWNDW *) lParam;
ArgumentLength += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS)
+ (wcslen(CbtCreateWnd->lpcs->lpszName)
+ 1) * sizeof(WCHAR);
if (0 != HIWORD(CbtCreateWnd->lpcs->lpszClass))
{
ArgumentLength += (wcslen(CbtCreateWnd->lpcs->lpszClass)
+ 1) * sizeof(WCHAR);
}
break;
default:
DPRINT1("Trying to call unsupported CBT hook %d\n", Code);
return 0;
}
break;
default:
DPRINT1("Trying to call unsupported window hook %d\n", HookId);
return 0;
}
Argument = ExAllocatePoolWithTag(PagedPool, ArgumentLength, TAG_CALLBACK);
if (NULL == Argument)
{
DPRINT1("HookProc callback failed: out of memory\n");
return 0;
}
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Argument;
Common->HookId = HookId;
Common->Code = Code;
Common->wParam = wParam;
Common->lParam = lParam;
Common->Proc = Proc;
Common->Ansi = Ansi;
Common->ModuleNameLength = ModuleName->Length;
memcpy(Common->ModuleName, ModuleName->Buffer, ModuleName->Length);
Extra = (PCHAR) Common->ModuleName + Common->ModuleNameLength;
switch(HookId)
{
case WH_CBT:
switch(Code)
{
case HCBT_CREATEWND:
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS) Extra;
CbtCreatewndExtra->Cs = *(CbtCreateWnd->lpcs);
CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter;
Extra = (PCHAR) (CbtCreatewndExtra + 1);
memcpy(Extra, CbtCreateWnd->lpcs->lpszName,
(wcslen(CbtCreateWnd->lpcs->lpszName) + 1) * sizeof(WCHAR));
CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
Extra += (wcslen(CbtCreateWnd->lpcs->lpszName) + 1) * sizeof(WCHAR);
if (0 != HIWORD(CbtCreateWnd->lpcs->lpszClass))
{
memcpy(Extra, CbtCreateWnd->lpcs->lpszClass,
(wcslen(CbtCreateWnd->lpcs->lpszClass) + 1) * sizeof(WCHAR));
CbtCreatewndExtra->Cs.lpszClass =
(LPCWSTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
}
break;
}
break;
}
ResultPointer = &Result;
ResultLength = sizeof(LRESULT);
Status = NtW32Call(USER32_CALLBACK_HOOKPROC,
Argument,
ArgumentLength,
&ResultPointer,
&ResultLength);
if (!NT_SUCCESS(Status))
{
return 0;
}
return Result;
}
/* EOF */ /* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: hook.c,v 1.2 2003/05/18 17:16:17 ea Exp $ /* $Id: hook.c,v 1.3 2003/12/12 14:22:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -25,22 +25,393 @@
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY: * REVISION HISTORY:
* 06-06-2001 CSH Created * 06-06-2001 CSH Created
* NOTE: Most of this code was adapted from Wine,
* Copyright (C) 2002 Alexandre Julliard
*/ */
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <win32k/win32k.h> #include <win32k/win32k.h>
#include <include/callback.h>
#include <include/error.h>
#include <include/hook.h>
#include <include/object.h>
#include <include/msgqueue.h>
#include <include/winsta.h>
#include <internal/ps.h>
#include <internal/safe.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <win32k/debug1.h>
DWORD #define TAG_HOOK TAG('W', 'N', 'H', 'K')
#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK)
STATIC PHOOKTABLE GlobalHooks;
/* create a new hook table */
STATIC FASTCALL PHOOKTABLE
IntAllocHookTable(void)
{
PHOOKTABLE Table;
UINT i;
Table = ExAllocatePoolWithTag(PagedPool, sizeof(HOOKTABLE), TAG_HOOK);
if (NULL != Table)
{
ExInitializeFastMutex(&Table->Lock);
for (i = 0; i < NB_HOOKS; i++)
{
InitializeListHead(&Table->Hooks[i]);
Table->Counts[i] = 0;
}
}
return Table;
}
/* create a new hook and add it to the specified table */
STATIC FASTCALL PHOOK
IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinStaObj)
{
PHOOK Hook;
PHOOKTABLE Table = Global ? GlobalHooks : MsqGetHooks(Thread->Win32Thread->MessageQueue);
HANDLE Handle;
if (NULL == Table)
{
Table = IntAllocHookTable();
if (NULL == Table)
{
return NULL;
}
if (Global)
{
GlobalHooks = Table;
}
else
{
MsqSetHooks(Thread->Win32Thread->MessageQueue, Table);
}
}
Hook = ObmCreateObject(WinStaObj->HandleTable, &Handle,
otHookProc, sizeof(HOOK));
if (NULL == Hook)
{
return NULL;
}
Hook->Self = Handle;
Hook->Thread = Thread;
Hook->HookId = HookId;
RtlInitUnicodeString(&Hook->ModuleName, NULL);
ExAcquireFastMutex(&Table->Lock);
InsertHeadList(&Table->Hooks[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
ExReleaseFastMutex(&Table->Lock);
return Hook;
}
/* get the hook table that a given hook belongs to */
STATIC PHOOKTABLE FASTCALL
IntGetTable(PHOOK Hook)
{
if (NULL == Hook->Thread || WH_KEYBOARD_LL == Hook->HookId ||
WH_MOUSE_LL == Hook->HookId)
{
return GlobalHooks;
}
return MsqGetHooks(Hook->Thread->Win32Thread->MessageQueue);
}
/* get the first hook in the chain */
STATIC PHOOK FASTCALL
IntGetFirstHook(PHOOKTABLE Table, int HookId)
{
PLIST_ENTRY Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink;
return Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)]
? NULL : CONTAINING_RECORD(Elem, HOOK, Chain);
}
/* find the first non-deleted hook in the chain */
STATIC PHOOK FASTCALL
IntGetFirstValidHook(PHOOKTABLE Table, int HookId)
{
PHOOK Hook;
PLIST_ENTRY Elem;
ExAcquireFastMutex(&Table->Lock);
Hook = IntGetFirstHook(Table, HookId);
while (NULL != Hook && NULL == Hook->Proc)
{
Elem = Hook->Chain.Flink;
Hook = (Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)]
? NULL : CONTAINING_RECORD(Elem, HOOK, Chain));
}
ExReleaseFastMutex(&Table->Lock);
return Hook;
}
/* find the next hook in the chain, skipping the deleted ones */
STATIC PHOOK FASTCALL
IntGetNextHook(PHOOK Hook)
{
PHOOKTABLE Table = IntGetTable(Hook);
int HookId = Hook->HookId;
PLIST_ENTRY Elem;
ExAcquireFastMutex(&Table->Lock);
Elem = Hook->Chain.Flink;
while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)])
{
Hook = CONTAINING_RECORD(Elem, HOOK, Chain);
if (NULL != Hook->Proc)
{
ExReleaseFastMutex(&Table->Lock);
return Hook;
}
}
ExReleaseFastMutex(&Table->Lock);
if (NULL != GlobalHooks && Table != GlobalHooks) /* now search through the global table */
{
return IntGetFirstValidHook(GlobalHooks, HookId);
}
return NULL;
}
/* free a hook, removing it from its chain */
STATIC VOID FASTCALL
IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
{
RemoveEntryList(&Hook->Chain);
RtlFreeUnicodeString(&Hook->ModuleName);
ObmCloseHandle(WinStaObj->HandleTable, Hook->Self);
}
/* remove a hook, freeing it if the chain is not in use */
STATIC FASTCALL VOID
IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
{
PHOOKTABLE Table = IntGetTable(Hook);
ASSERT(NULL != Table);
if (NULL == Table)
{
return;
}
ExAcquireFastMutex(&Table->Lock);
if (0 != Table->Counts[HOOKID_TO_INDEX(Hook->HookId)])
{
Hook->Proc = NULL; /* chain is in use, just mark it and return */
}
else
{
IntFreeHook(Table, Hook, WinStaObj);
}
ExReleaseFastMutex(&Table->Lock);
}
/* release a hook chain, removing deleted hooks if the use count drops to 0 */
STATIC VOID FASTCALL
IntReleaseHookChain(PHOOKTABLE Table, int HookId, PWINSTATION_OBJECT WinStaObj)
{
PLIST_ENTRY Elem;
PHOOK HookObj;
if (NULL == Table)
{
return;
}
ExAcquireFastMutex(&Table->Lock);
/* use count shouldn't already be 0 */
ASSERT(0 != Table->Counts[HOOKID_TO_INDEX(HookId)]);
if (0 == Table->Counts[HOOKID_TO_INDEX(HookId)])
{
ExReleaseFastMutex(&Table->Lock);
return;
}
if (0 == --Table->Counts[HOOKID_TO_INDEX(HookId)])
{
Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink;
while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)])
{
HookObj = CONTAINING_RECORD(Elem, HOOK, Chain);
Elem = Elem->Flink;
if (NULL == HookObj->Proc)
{
IntFreeHook(Table, HookObj, WinStaObj);
}
}
}
ExReleaseFastMutex(&Table->Lock);
}
LRESULT FASTCALL
HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
{
PHOOK Hook;
PHOOKTABLE Table = MsqGetHooks(PsGetWin32Thread()->MessageQueue);
LRESULT Result;
PWINSTATION_OBJECT WinStaObj;
NTSTATUS Status;
ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId)))
{
/* try global table */
Table = GlobalHooks;
if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId)))
{
return 0; /* no hook set */
}
}
if (Hook->Thread != PsGetCurrentThread())
{
DPRINT1("Calling hooks in other threads not implemented yet");
return 0;
}
ExAcquireFastMutex(&Table->Lock);
Table->Counts[HOOKID_TO_INDEX(HookId)]++;
ExReleaseFastMutex(&Table->Lock);
if (Table != GlobalHooks && GlobalHooks != NULL)
{
ExAcquireFastMutex(&GlobalHooks->Lock);
GlobalHooks->Counts[HOOKID_TO_INDEX(HookId)]++;
ExReleaseFastMutex(&GlobalHooks->Lock);
}
Result = IntCallHookProc(HookId, Code, wParam, lParam, Hook->Proc,
Hook->Ansi, &Hook->ModuleName);
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObj);
if(! NT_SUCCESS(Status))
{
DPRINT1("Invalid window station????\n");
}
else
{
IntReleaseHookChain(MsqGetHooks(PsGetWin32Thread()->MessageQueue), HookId, WinStaObj);
IntReleaseHookChain(GlobalHooks, HookId, WinStaObj);
ObDereferenceObject(WinStaObj);
}
return Result;
}
VOID FASTCALL
HOOK_DestroyThreadHooks(PETHREAD Thread)
{
int HookId;
PLIST_ENTRY Elem;
PHOOK HookObj;
PWINSTATION_OBJECT WinStaObj;
NTSTATUS Status;
if (NULL != GlobalHooks)
{
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObj);
if(! NT_SUCCESS(Status))
{
DPRINT1("Invalid window station????\n");
return;
}
ExAcquireFastMutex(&GlobalHooks->Lock);
for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++)
{
/* only low-level keyboard/mouse global hooks can be owned by a thread */
switch(HookId)
{
case WH_KEYBOARD_LL:
case WH_MOUSE_LL:
Elem = GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)].Flink;
while (Elem != &GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)])
{
HookObj = CONTAINING_RECORD(Elem, HOOK, Chain);
Elem = Elem->Flink;
if (HookObj->Thread == Thread)
{
IntRemoveHook(HookObj, WinStaObj);
}
}
break;
}
}
ExReleaseFastMutex(&GlobalHooks->Lock);
ObDereferenceObject(WinStaObj);
}
}
LRESULT
STDCALL STDCALL
NtUserCallNextHookEx( NtUserCallNextHookEx(
DWORD Unknown0, HHOOK Hook,
DWORD Unknown1, int Code,
DWORD Unknown2, WPARAM wParam,
DWORD Unknown3) LPARAM lParam)
{ {
UNIMPLEMENTED PHOOK HookObj, NextObj;
PWINSTATION_OBJECT WinStaObj;
NTSTATUS Status;
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObj);
if(! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
Status = ObmReferenceObjectByHandle(WinStaObj->HandleTable, Hook,
otHookProc, (PVOID *) &HookObj);
ObDereferenceObject(WinStaObj);
if (! NT_SUCCESS(Status))
{
DPRINT1("Invalid handle passed to NtUserCallNextHookEx\n");
SetLastNtError(Status);
return 0;
}
ASSERT(Hook == HookObj->Self);
if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread()))
{
DPRINT1("Thread mismatch\n");
ObmDereferenceObject(HookObj);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
NextObj = IntGetNextHook(HookObj);
ObmDereferenceObject(HookObj);
if (NULL != NextObj)
{
DPRINT1("Calling next hook not implemented\n");
UNIMPLEMENTED
SetLastWin32Error(ERROR_NOT_SUPPORTED);
return 0;
}
return 0; return 0;
} }
@ -57,19 +428,147 @@ NtUserSetWindowsHookAW(
return 0; return 0;
} }
DWORD HHOOK
STDCALL STDCALL
NtUserSetWindowsHookEx( NtUserSetWindowsHookEx(
DWORD Unknown0, HINSTANCE Mod,
DWORD Unknown1, PUNICODE_STRING UnsafeModuleName,
DWORD Unknown2, DWORD ThreadId,
DWORD Unknown3, int HookId,
DWORD Unknown4, HOOKPROC HookProc,
DWORD Unknown5) BOOL Ansi)
{ {
UNIMPLEMENTED PWINSTATION_OBJECT WinStaObj;
BOOLEAN Global;
PETHREAD Thread;
PHOOK Hook;
UNICODE_STRING ModuleName;
NTSTATUS Status;
HHOOK Handle;
return 0; if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId || NULL == HookProc)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
if (ThreadId) /* thread-local hook */
{
if (HookId == WH_JOURNALRECORD ||
HookId == WH_JOURNALPLAYBACK ||
HookId == WH_KEYBOARD_LL ||
HookId == WH_MOUSE_LL ||
HookId == WH_SYSMSGFILTER)
{
/* these can only be global */
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
Mod = NULL;
Global = FALSE;
if (! NT_SUCCESS(PsLookupThreadByThreadId((PVOID) ThreadId, &Thread)))
{
DPRINT1("Invalid thread id 0x%x\n", ThreadId);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
if (Thread->ThreadsProcess != PsGetCurrentProcess())
{
DPRINT1("Can't specify thread belonging to another process\n");
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
}
else /* system-global hook */
{
if (HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL)
{
Mod = NULL;
Thread = PsGetCurrentThread();
}
else if (NULL == Mod)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
else
{
Thread = NULL;
}
Global = TRUE;
}
/* We only (partially) support local WH_CBT hooks for now */
if (WH_CBT != HookId || Global)
{
UNIMPLEMENTED
SetLastWin32Error(ERROR_NOT_SUPPORTED);
return NULL;
}
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObj);
if(! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return (HANDLE) NULL;
}
Hook = IntAddHook(Thread, HookId, Global, WinStaObj);
if (NULL == Hook)
{
ObDereferenceObject(WinStaObj);
return NULL;
}
if (NULL != Mod)
{
Status = MmCopyFromCaller(&ModuleName, UnsafeModuleName, sizeof(UNICODE_STRING));
if (! NT_SUCCESS(Status))
{
ObmDereferenceObject(Hook);
IntRemoveHook(Hook, WinStaObj);
ObDereferenceObject(WinStaObj);
SetLastNtError(Status);
return NULL;
}
Hook->ModuleName.Buffer = ExAllocatePoolWithTag(PagedPool,
ModuleName.MaximumLength,
TAG_HOOK);
if (NULL == Hook->ModuleName.Buffer)
{
ObmDereferenceObject(Hook);
IntRemoveHook(Hook, WinStaObj);
ObDereferenceObject(WinStaObj);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
Hook->ModuleName.MaximumLength = ModuleName.MaximumLength;
Status = MmCopyFromCaller(Hook->ModuleName.Buffer,
ModuleName.Buffer,
ModuleName.MaximumLength);
if (! NT_SUCCESS(Status))
{
ObmDereferenceObject(Hook);
IntRemoveHook(Hook, WinStaObj);
ObDereferenceObject(WinStaObj);
SetLastNtError(Status);
return NULL;
}
Hook->ModuleName.Length = ModuleName.Length;
}
Hook->Proc = HookProc;
Hook->Ansi = Ansi;
Handle = Hook->Self;
ObmDereferenceObject(Hook);
ObDereferenceObject(WinStaObj);
return Handle;
} }
DWORD DWORD
@ -89,14 +588,43 @@ NtUserSetWinEventHook(
return 0; return 0;
} }
DWORD BOOL
STDCALL STDCALL
NtUserUnhookWindowsHookEx( NtUserUnhookWindowsHookEx(
DWORD Unknown0) HHOOK Hook)
{ {
UNIMPLEMENTED PWINSTATION_OBJECT WinStaObj;
PHOOK HookObj;
NTSTATUS Status;
return 0; Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObj);
if(! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
Status = ObmReferenceObjectByHandle(WinStaObj->HandleTable, Hook,
otHookProc, (PVOID *) &HookObj);
if (! NT_SUCCESS(Status))
{
DPRINT1("Invalid handle passed to NtUserUnhookWindowsHookEx\n");
ObDereferenceObject(WinStaObj);
SetLastNtError(Status);
return FALSE;
}
ASSERT(Hook == HookObj->Self);
IntRemoveHook(HookObj, WinStaObj);
ObmDereferenceObject(HookObj);
ObDereferenceObject(WinStaObj);
return TRUE;
} }
DWORD DWORD

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: msgqueue.c,v 1.41 2003/12/08 20:40:41 gvg Exp $ /* $Id: msgqueue.c,v 1.42 2003/12/12 14:22:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -861,4 +861,16 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
ExFreePool(MessageQueue); ExFreePool(MessageQueue);
} }
PHOOKTABLE FASTCALL
MsqGetHooks(PUSER_MESSAGE_QUEUE Queue)
{
return Queue->Hooks;
}
VOID FASTCALL
MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks)
{
Queue->Hooks = Hooks;
}
/* EOF */ /* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: windc.c,v 1.41 2003/12/03 08:19:03 gvg Exp $ /* $Id: windc.c,v 1.42 2003/12/12 14:22:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -390,7 +390,9 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
{ {
Dce = Window->Dce; Dce = Window->Dce;
/* FIXME: Implement this. */ /* FIXME: Implement this. */
#ifdef TODO
DbgBreakPoint(); DbgBreakPoint();
#endif
} }
if (NULL == Dce) if (NULL == Dce)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: window.c,v 1.156 2003/12/10 22:09:56 weiden Exp $ /* $Id: window.c,v 1.157 2003/12/12 14:22:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -50,6 +50,7 @@
#include <include/menu.h> #include <include/menu.h>
#include <include/hotkey.h> #include <include/hotkey.h>
#include <include/focus.h> #include <include/focus.h>
#include <include/hook.h>
#define NDEBUG #define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
@ -1033,8 +1034,8 @@ NtUserCreateWindowEx(DWORD dwExStyle,
POINT MaxPos; POINT MaxPos;
#endif #endif
CREATESTRUCTW Cs; CREATESTRUCTW Cs;
CBT_CREATEWNDW CbtCreate;
LRESULT Result; LRESULT Result;
DPRINT("NtUserCreateWindowEx\n");
DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
@ -1240,6 +1241,30 @@ NtUserCreateWindowEx(DWORD dwExStyle,
} }
WindowObject->ClientRect = WindowObject->WindowRect; WindowObject->ClientRect = WindowObject->WindowRect;
Cs.lpCreateParams = lpParam;
Cs.hInstance = hInstance;
Cs.hMenu = hMenu;
Cs.hwndParent = ParentWindowHandle;
Cs.cx = nWidth;
Cs.cy = nHeight;
Cs.x = x;
Cs.y = y;
Cs.style = dwStyle;
Cs.lpszName = lpWindowName->Buffer;
Cs.lpszClass = lpClassName->Buffer;
Cs.dwExStyle = dwExStyle;
CbtCreate.lpcs = &Cs;
CbtCreate.hwndInsertAfter = HWND_TOP;
if (HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate))
{
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
DPRINT1("CBT-hook returned !0\n");
return (HWND) NULL;
}
/* /*
* Get the size and position of the window. * Get the size and position of the window.
*/ */
@ -1276,28 +1301,13 @@ NtUserCreateWindowEx(DWORD dwExStyle,
IntCreateScrollBar(WindowObject, SB_HORZ); IntCreateScrollBar(WindowObject, SB_HORZ);
/* Send a NCCREATE message. */ /* Send a NCCREATE message. */
Cs.lpCreateParams = lpParam;
Cs.hInstance = hInstance;
Cs.hMenu = hMenu;
Cs.hwndParent = ParentWindowHandle;
Cs.cx = nWidth; Cs.cx = nWidth;
Cs.cy = nHeight; Cs.cy = nHeight;
Cs.x = x; Cs.x = x;
Cs.y = y; Cs.y = y;
Cs.style = dwStyle;
Cs.lpszName = lpWindowName->Buffer;
Cs.lpszClass = lpClassName->Buffer;
Cs.dwExStyle = dwExStyle;
// AG: For some reason these don't get set already. This might need moving
// elsewhere... What is actually done with WindowObject anyway, to retain
// its data?
DPRINT("[win32k.window] NtUserCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent); DPRINT("[win32k.window] NtUserCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent);
// NtUserSetWindowLong(Handle, GWL_STYLE, WindowObject->Style, TRUE);
// NtUserSetWindowLong(Handle, GWL_EXSTYLE, WindowObject->ExStyle, TRUE);
DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
// Any more?
DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n"); DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
Result = IntSendNCCREATEMessage(WindowObject->Self, &Cs); Result = IntSendNCCREATEMessage(WindowObject->Self, &Cs);
if (!Result) if (!Result)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: fillshap.c,v 1.35 2003/10/04 20:04:10 gvg Exp $ */ /* $Id: fillshap.c,v 1.36 2003/12/12 14:22:37 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
@ -136,7 +136,7 @@ NtGdiEllipse(HDC hDC,
BRUSHOBJ_UnlockBrush(dc->w.hBrush); BRUSHOBJ_UnlockBrush(dc->w.hBrush);
DC_UnlockDc(hDC); DC_UnlockDc(hDC);
return TRUE; return ret;
} }
Radius = (Right - Left) / 2; Radius = (Right - Left) / 2;
@ -231,22 +231,415 @@ NtGdiEllipse(HDC hDC,
BRUSHOBJ_UnlockBrush(dc->w.hBrush); BRUSHOBJ_UnlockBrush(dc->w.hBrush);
DC_UnlockDc(hDC); DC_UnlockDc(hDC);
return TRUE; return ret;
} }
typedef struct tagSHAPEPOINT
{
int X;
int Y;
int Type;
} SHAPEPOINT, *PSHAPEPOINT;
#define SHAPEPOINT_TYPE_CIRCLE 'C'
#define SHAPEPOINT_TYPE_LINE_RIGHT 'R' /* Fill at right side of line */
#define SHAPEPOINT_TYPE_LINE_LEFT 'L' /* Fill at left side of line */
#define SETPOINT(x, y, type) \
ShapePoints[*PointCount].X = (x); \
ShapePoints[*PointCount].Y = (y); \
ShapePoints[*PointCount].Type = (type); \
(*PointCount)++
#define SETCIRCLEPOINT(x, y) \
SETPOINT(x, y, SHAPEPOINT_TYPE_CIRCLE)
#ifdef TODO
STATIC VOID
FASTCALL
CirclePoints(UINT *PointCount, PSHAPEPOINT ShapePoints, int Left, int Top,
int Right, int Bottom)
{
int X, X18, X27, X36, X45;
int Y, Y14, Y23, Y58, Y67;
int d, Radius;
BOOL Even;
Even = (0 == (Right - Left) % 2);
Right--;
Bottom--;
Radius = (Right - Left) / 2;
if (Even)
{
X = 0;
Y = Radius;
d = 2 - Radius;
X18 = Right;
X27 = (Left + Right) / 2 + 1;
X36 = (Left + Right) / 2;
X45 = Left;
Y14 = Top + Radius;
Y23 = Top;
Y58 = Top + Radius + 1;
Y67 = Top + (Right - Left);
ShapePoints[*PointCount].X = X27;
SETCIRCLEPOINT(X27, Y23);
SETCIRCLEPOINT(X36, Y23);
SETCIRCLEPOINT(X18, Y14);
SETCIRCLEPOINT(X45, Y14);
SETCIRCLEPOINT(X18, Y58);
SETCIRCLEPOINT(X45, Y58);
SETCIRCLEPOINT(X27, Y67);
SETCIRCLEPOINT(X36, Y67);
}
else
{
X = 0;
Y = Radius;
d = 1 - Radius;
X18 = Right;
X27 = (Left + Right) / 2;
X36 = (Left + Right) / 2;
X45 = Left;
Y14 = Top + Radius;
Y23 = Top;
Y58 = Top + Radius;
Y67 = Top + (Right - Left);
SETCIRCLEPOINT(X27, Y23);
SETCIRCLEPOINT(X45, Y14);
SETCIRCLEPOINT(X18, Y58);
SETCIRCLEPOINT(X27, Y67);
}
while (X < Y)
{
if (d < 0)
{
d += 2 * X + (Even ? 4 : 3);
X27++;
X36--;
Y14--;
Y58++;
}
else
{
d += 2 * (X - Y) + 5;
Y--;
Y23++;
Y67--;
X18--;
X45++;
X27++;
X36--;
Y14--;
Y58++;
}
X++;
SETCIRCLEPOINT(X27, Y23);
SETCIRCLEPOINT(X36, Y23);
SETCIRCLEPOINT(X18, Y14);
SETCIRCLEPOINT(X45, Y14);
SETCIRCLEPOINT(X18, Y58);
SETCIRCLEPOINT(X45, Y58);
SETCIRCLEPOINT(X27, Y67);
SETCIRCLEPOINT(X36, Y67);
}
}
STATIC VOID
LinePoints(UINT *PointCount, PSHAPEPOINT ShapePoints, int Left, int Top,
int Right, int Bottom, int XTo, int YTo, BOOL Start)
{
LONG x, y, deltax, deltay, i, xchange, ychange, error;
int Type;
x = (Right + Left) / 2;
y = (Bottom + Top) / 2;
deltax = XTo - x;
deltay = YTo - y;
if (deltax < 0)
{
xchange = -1;
deltax = - deltax;
x--;
}
else
{
xchange = 1;
}
if (deltay < 0)
{
ychange = -1;
deltay = - deltay;
y--;
Type = (Start ? SHAPEPOINT_TYPE_LINE_LEFT : SHAPEPOINT_TYPE_LINE_RIGHT);
}
else
{
ychange = 1;
Type = (Start ? SHAPEPOINT_TYPE_LINE_RIGHT : SHAPEPOINT_TYPE_LINE_LEFT);
}
if (y == YTo)
{
for (i = x; i <= XTo; i++)
{
SETPOINT(i, y, Type);
}
}
else if (x == XTo)
{
for (i = y; i <= YTo; i++)
{
SETPOINT(x, i, Type);
}
}
else
{
error = 0;
if (deltax < deltay)
{
for (i = 0; i < deltay; i++)
{
SETPOINT(x, y, Type);
y = y + ychange;
error = error + deltax;
if (deltay <= error)
{
x = x + xchange;
error = error - deltay;
}
}
}
else
{
for (i = 0; i < deltax; i++)
{
SETPOINT(x, y, Type);
x = x + xchange;
error = error + deltay;
if (deltax <= error)
{
y = y + ychange;
error = error - deltax;
}
}
}
}
}
STATIC int
CDECL
CompareShapePoints(const void *pv1, const void *pv2)
{
if (((const PSHAPEPOINT) pv1)->Y < ((const PSHAPEPOINT) pv2)->Y)
{
return -1;
}
else if (((const PSHAPEPOINT) pv2)->Y < ((const PSHAPEPOINT) pv1)->Y)
{
return +1;
}
else if (((const PSHAPEPOINT) pv1)->X < ((const PSHAPEPOINT) pv2)->X)
{
return -1;
}
else if (((const PSHAPEPOINT) pv2)->X < ((const PSHAPEPOINT) pv1)->X)
{
return +1;
}
else
{
return 0;
}
}
#endif
BOOL BOOL
STDCALL STDCALL
NtGdiPie(HDC hDC, NtGdiPie(HDC hDC,
int LeftRect, int Left,
int TopRect, int Top,
int RightRect, int Right,
int BottomRect, int Bottom,
int XRadial1, int XRadialStart,
int YRadial1, int YRadialStart,
int XRadial2, int XRadialEnd,
int YRadial2) int YRadialEnd)
{ {
UNIMPLEMENTED; #ifdef TODO
PDC dc;
RECTL RectBounds;
PSURFOBJ SurfObj;
BRUSHOBJ PenBrushObj;
PBRUSHOBJ FillBrushObj;
PSHAPEPOINT ShapePoints;
UINT Point, PointCount;
BOOL ret = TRUE;
int Y, CircleStart, CircleEnd, LineStart, LineEnd;
BOOL FullFill;
if (Right <= Left || Bottom <= Top)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (Right - Left != Bottom - Top)
{
UNIMPLEMENTED;
}
dc = DC_LockDc ( hDC );
if (NULL == dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
if (NULL == FillBrushObj)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return FALSE;
}
Left += dc->w.DCOrgX;
Right += dc->w.DCOrgX;
Top += dc->w.DCOrgY;
Bottom += dc->w.DCOrgY;
XRadialStart += dc->w.DCOrgX;
YRadialStart += dc->w.DCOrgY;
XRadialEnd += dc->w.DCOrgX;
YRadialEnd += dc->w.DCOrgY;
RectBounds.left = Left;
RectBounds.right = Right;
RectBounds.top = Top;
RectBounds.bottom = Bottom;
SurfObj = (PSURFOBJ) AccessUserObject((ULONG)dc->Surface);
HPenToBrushObj(&PenBrushObj, dc->w.hPen);
/* Number of points for the circle is 4 * sqrt(2) * Radius, start
and end line have at most Radius points, so allocate at least
that much */
ShapePoints = ExAllocatePool(PagedPool, 8 * (Right - Left + 1) / 2 * sizeof(SHAPEPOINT));
if (NULL == ShapePoints)
{
BRUSHOBJ_UnlockBrush(dc->w.hBrush);
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
if (Left == Right)
{
PUTPIXEL(Left, Top, &PenBrushObj);
BRUSHOBJ_UnlockBrush(dc->w.hBrush);
DC_UnlockDc(hDC);
return ret;
}
PointCount = 0;
CirclePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom);
LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
XRadialStart, YRadialStart, TRUE);
LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
XRadialEnd, YRadialEnd, FALSE);
ASSERT(PointCount <= 8 * (Right - Left + 1) / 2);
EngSort((PBYTE) ShapePoints, sizeof(SHAPEPOINT), PointCount, CompareShapePoints);
FullFill = TRUE;
Point = 0;
while (Point < PointCount)
{
Y = ShapePoints[Point].Y;
/* Skip any line pixels before circle */
while (Point < PointCount && ShapePoints[Point].Y == Y
&& SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
{
Point++;
}
/* Handle left side of circle */
if (Point < PointCount && ShapePoints[Point].Y == Y)
{
CircleStart = ShapePoints[Point].X;
Point++;
while (Point < PointCount && ShapePoints[Point].Y == Y
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
{
Point++;
}
CircleEnd = ShapePoints[Point - 1].X;
PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj);
}
/* Handle line(s) (max 2) inside the circle */
while (Point < PointCount && ShapePoints[Point].Y == Y
&& SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
{
LineStart = ShapePoints[Point].X;
Point++;
while (Point < PointCount && ShapePoints[Point].Y == Y
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
&& ShapePoints[Point].Type == ShapePoints[Point - 1].Type)
{
Point++;
}
LineEnd = ShapePoints[Point - 1].X;
PUTLINE(LineStart, Y, LineEnd + 1, Y, &PenBrushObj);
}
/* Handle right side of circle */
while (Point < PointCount && ShapePoints[Point].Y == Y
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
{
CircleStart = ShapePoints[Point].X;
Point++;
while (Point < PointCount && ShapePoints[Point].Y == Y
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
{
Point++;
}
CircleEnd = ShapePoints[Point - 1].X;
PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj);
}
/* Skip any line pixels after circle */
while (Point < PointCount && ShapePoints[Point].Y == Y)
{
Point++;
}
}
ExFreePool(ShapePoints);
BRUSHOBJ_UnlockBrush(dc->w.hBrush);
DC_UnlockDc(hDC);
return ret;
#else
return TRUE;
#endif
} }
#if 0 #if 0