mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Incomplete implementation of hooks
svn path=/trunk/; revision=6965
This commit is contained in:
parent
dc8bfd1046
commit
ae68da49b6
22 changed files with 1376 additions and 120 deletions
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
32
reactos/subsys/win32k/include/hook.h
Normal file
32
reactos/subsys/win32k/include/hook.h
Normal 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 */
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue