mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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_JOURNALRECORD (0)
|
||||
#define WH_KEYBOARD (2)
|
||||
#define WH_KEYBOARD_LL (13)
|
||||
#define WH_MOUSE (7)
|
||||
#define WH_MOUSE_LL (14)
|
||||
#define WH_MSGFILTER (-1)
|
||||
#define WH_SHELL (10)
|
||||
#define WH_SYSMSGFILTER (6)
|
||||
#define WH_MSGFILTER (-1)
|
||||
#define WH_FOREGROUNDIDLE (11)
|
||||
|
||||
#define WH_MINHOOK (-1)
|
||||
#define WH_MAXHOOK (14)
|
||||
|
||||
/* DefineDosDevice */
|
||||
#define DDD_RAW_TARGET_PATH (1)
|
||||
#define DDD_REMOVE_DEFINITION (2)
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
#define USER32_CALLBACK_SENDSTYLECHANGED (9)
|
||||
#define USER32_CALLBACK_LOADSYSMENUTEMPLATE (10)
|
||||
#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
|
||||
{
|
||||
|
@ -101,6 +102,26 @@ typedef struct _SENDSTYLECHANGED_CALLBACK_ARGUMENTS
|
|||
DWORD WhichStyle;
|
||||
} 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
|
||||
User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||
NTSTATUS STDCALL
|
||||
|
@ -125,5 +146,7 @@ NTSTATUS STDCALL
|
|||
User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||
NTSTATUS STDCALL
|
||||
User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength);
|
||||
NTSTATUS STDCALL
|
||||
User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||
|
||||
#endif /* __INCLUDE_USER32_CALLBACK_H */
|
||||
|
|
|
@ -152,13 +152,13 @@ NtUserCallMsgFilter(
|
|||
DWORD Unknown0,
|
||||
DWORD Unknown1);
|
||||
|
||||
DWORD
|
||||
LRESULT
|
||||
STDCALL
|
||||
NtUserCallNextHookEx(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1,
|
||||
DWORD Unknown2,
|
||||
DWORD Unknown3);
|
||||
HHOOK Hook,
|
||||
int Code,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
#define NOPARAM_ROUTINE_REGISTER_PRIMITIVE 0xffff0001 /* Private ROS */
|
||||
#define NOPARAM_ROUTINE_DESTROY_CARET 0xffff0002
|
||||
|
@ -1566,15 +1566,15 @@ NtUserSetWindowsHookAW(
|
|||
DWORD Unknown1,
|
||||
DWORD Unknown2);
|
||||
|
||||
DWORD
|
||||
HHOOK
|
||||
STDCALL
|
||||
NtUserSetWindowsHookEx(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1,
|
||||
DWORD Unknown2,
|
||||
DWORD Unknown3,
|
||||
DWORD Unknown4,
|
||||
DWORD Unknown5);
|
||||
HINSTANCE Mod,
|
||||
PUNICODE_STRING ModuleName,
|
||||
DWORD ThreadId,
|
||||
int HookId,
|
||||
HOOKPROC HookProc,
|
||||
BOOL Ansi);
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
|
@ -1688,10 +1688,10 @@ NtUserTranslateMessage(
|
|||
LPMSG lpMsg,
|
||||
HKL dwhkl );
|
||||
|
||||
DWORD
|
||||
BOOL
|
||||
STDCALL
|
||||
NtUserUnhookWindowsHookEx(
|
||||
DWORD Unknown0);
|
||||
HHOOK Hook);
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define __WINE_DEBUG_H
|
||||
|
||||
#include "../roscfg.h"
|
||||
#ifndef DBG
|
||||
#if ! defined(DBG) || ! defined(YDEBUG)
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#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
|
||||
*
|
||||
|
@ -513,28 +513,6 @@ InvertRgn(
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -81,3 +81,23 @@ Ellipse(HDC hDc,
|
|||
{
|
||||
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);
|
||||
#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 */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ static HRESULT WINAPI IStream_fnCopyTo(IStream *iface, IStream* pstm, ULARGE_INT
|
|||
ULONGLONG ulSize;
|
||||
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)
|
||||
pcbRead->QuadPart = 0;
|
||||
|
@ -278,7 +278,7 @@ static HRESULT WINAPI IStream_fnLockUnlockRegion(IStream *iface, ULARGE_INTEGER
|
|||
#ifndef NDEBUG
|
||||
ICOM_THIS(ISHFileStream, iface);
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef DBG
|
||||
#undef DBG
|
||||
#define DBG 1
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifdef __REACTOS__
|
||||
|
|
|
@ -78,6 +78,8 @@ Init(VOID)
|
|||
(PVOID)User32LoadSysMenuTemplateForKernel;
|
||||
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] =
|
||||
(PVOID)User32SetupDefaultCursors;
|
||||
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] =
|
||||
(PVOID)User32CallHookProcFromKernel;
|
||||
|
||||
/* Allocate an index for user32 thread local data. */
|
||||
User32TlsIndex = TlsAlloc();
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* FILE: lib/user32/windows/input.c
|
||||
|
@ -30,20 +30,22 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <user32.h>
|
||||
#include <user32/callback.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
WINBOOL
|
||||
STDCALL
|
||||
UnhookWindowsHookEx(
|
||||
HHOOK hhk)
|
||||
HHOOK Hook)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
return NtUserUnhookWindowsHookEx(Hook);
|
||||
}
|
||||
#if 0
|
||||
WINBOOL
|
||||
|
@ -92,13 +94,41 @@ CallMsgFilterW(
|
|||
LRESULT
|
||||
STDCALL
|
||||
CallNextHookEx(
|
||||
HHOOK hhk,
|
||||
int nCode,
|
||||
HHOOK Hook,
|
||||
int Code,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return (LRESULT)0;
|
||||
return NtUserCallNextHookEx(Hook, Code, wParam, lParam);
|
||||
}
|
||||
|
||||
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
|
||||
STDCALL
|
||||
SetWindowsHookW ( int idHook, HOOKPROC lpfn )
|
||||
SetWindowsHookW(int idHook, HOOKPROC lpfn)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
return IntSetWindowsHook(idHook, lpfn, NULL, 0, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -117,10 +146,9 @@ SetWindowsHookW ( int idHook, HOOKPROC lpfn )
|
|||
*/
|
||||
HHOOK
|
||||
STDCALL
|
||||
SetWindowsHookA ( int idHook, HOOKPROC lpfn )
|
||||
SetWindowsHookA(int idHook, HOOKPROC lpfn)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
return IntSetWindowsHook(idHook, lpfn, NULL, 0, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -225,8 +253,7 @@ SetWindowsHookExA(
|
|||
HINSTANCE hMod,
|
||||
DWORD dwThreadId)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -241,7 +268,89 @@ SetWindowsHookExW(
|
|||
HINSTANCE hMod,
|
||||
DWORD dwThreadId)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE);
|
||||
}
|
||||
|
||||
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
|
||||
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 */
|
||||
|
|
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 <windows.h>
|
||||
#include "hook.h"
|
||||
|
||||
typedef struct _USER_MESSAGE
|
||||
{
|
||||
|
@ -73,6 +74,8 @@ typedef struct _USER_MESSAGE_QUEUE
|
|||
HWND MenuOwner;
|
||||
/* Identifes the menu state */
|
||||
BYTE MenuState;
|
||||
/* Window hooks */
|
||||
PHOOKTABLE Hooks;
|
||||
|
||||
/* queue state tracking */
|
||||
WORD WakeBits;
|
||||
|
@ -150,6 +153,9 @@ BOOL IntInitMessagePumpHook();
|
|||
BOOL IntUninitMessagePumpHook();
|
||||
#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 */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -12,7 +12,8 @@ typedef enum {
|
|||
otWindow,
|
||||
otMenu,
|
||||
otAcceleratorTable,
|
||||
otCursorIcon
|
||||
otCursorIcon,
|
||||
otHookProc
|
||||
} USER_OBJECT_TYPE;
|
||||
|
||||
typedef struct _USER_OBJECT_HEADER
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
*/
|
||||
|
@ -43,6 +43,7 @@
|
|||
#include <include/hotkey.h>
|
||||
#include <include/accelerator.h>
|
||||
#include <include/guicheck.h>
|
||||
#include <include/hook.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <win32k/debug1.h>
|
||||
|
@ -161,6 +162,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
|
|||
DbgPrint (" Destroy thread\n");
|
||||
#endif
|
||||
|
||||
HOOK_DestroyThreadHooks(Thread);
|
||||
RemoveTimersThread(Thread->Cid.UniqueThread);
|
||||
UnregisterThreadHotKeys(Thread);
|
||||
DestroyThreadWindows(Thread);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -66,13 +66,13 @@ ObmpPerformRetentionChecks(PUSER_OBJECT_HEADER ObjectHeader)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,11 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
|
|||
PLIST_ENTRY Current;
|
||||
ULONG i;
|
||||
|
||||
if (NULL == Handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Current = HandleTable->ListHead.Flink;
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
|
@ -108,6 +113,7 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
|
|||
Current = Current->Flink;
|
||||
if (Current == &(HandleTable->ListHead))
|
||||
{
|
||||
DPRINT1("Invalid handle\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -195,6 +201,7 @@ ObmpDeleteHandle(PUSER_HANDLE_TABLE HandleTable,
|
|||
Entry = ObmpGetObjectByHandle(HandleTable, Handle);
|
||||
if (Entry == NULL)
|
||||
{
|
||||
DPRINT1("Invalid handle\n");
|
||||
ObmpUnlockHandleTable(HandleTable);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -404,7 +411,7 @@ ObmCreateHandle(PUSER_HANDLE_TABLE HandleTable,
|
|||
Block->Handles[i].ObjectBody = ObjectBody;
|
||||
ObmpUnlockHandleTable(HandleTable);
|
||||
*HandleReturn = (HANDLE)((Handle + i) << 2);
|
||||
return ERROR_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,6 +426,7 @@ ObmCreateHandle(PUSER_HANDLE_TABLE HandleTable,
|
|||
sizeof(USER_HANDLE_BLOCK));
|
||||
if (!NewBlock)
|
||||
{
|
||||
DPRINT1("Unable to allocate new handle block\n");
|
||||
*HandleReturn = (PHANDLE)NULL;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
@ -471,6 +479,7 @@ ObmReferenceObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
|
|||
|
||||
if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType))
|
||||
{
|
||||
DPRINT1("Object type mismatch\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
@ -518,6 +527,7 @@ ObmCreateHandleTable(VOID)
|
|||
sizeof(USER_HANDLE_TABLE));
|
||||
if (!HandleTable)
|
||||
{
|
||||
DPRINT1("Unable to create handle table\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -43,6 +43,8 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define TAG_CALLBACK TAG('C', 'B', 'C', 'K')
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
|
@ -417,4 +419,111 @@ IntLoadDefaultCursors(BOOL SetDefault)
|
|||
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 */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -25,22 +25,393 @@
|
|||
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISION HISTORY:
|
||||
* 06-06-2001 CSH Created
|
||||
* NOTE: Most of this code was adapted from Wine,
|
||||
* Copyright (C) 2002 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include <ddk/ntddk.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
|
||||
#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
|
||||
NtUserCallNextHookEx(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1,
|
||||
DWORD Unknown2,
|
||||
DWORD Unknown3)
|
||||
HHOOK Hook,
|
||||
int Code,
|
||||
WPARAM wParam,
|
||||
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;
|
||||
}
|
||||
|
@ -57,19 +428,147 @@ NtUserSetWindowsHookAW(
|
|||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
HHOOK
|
||||
STDCALL
|
||||
NtUserSetWindowsHookEx(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1,
|
||||
DWORD Unknown2,
|
||||
DWORD Unknown3,
|
||||
DWORD Unknown4,
|
||||
DWORD Unknown5)
|
||||
HINSTANCE Mod,
|
||||
PUNICODE_STRING UnsafeModuleName,
|
||||
DWORD ThreadId,
|
||||
int HookId,
|
||||
HOOKPROC HookProc,
|
||||
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
|
||||
|
@ -89,14 +588,43 @@ NtUserSetWinEventHook(
|
|||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
BOOL
|
||||
STDCALL
|
||||
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
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -861,4 +861,16 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE 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 */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -390,7 +390,9 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
|
|||
{
|
||||
Dce = Window->Dce;
|
||||
/* FIXME: Implement this. */
|
||||
#ifdef TODO
|
||||
DbgBreakPoint();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (NULL == Dce)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -50,6 +50,7 @@
|
|||
#include <include/menu.h>
|
||||
#include <include/hotkey.h>
|
||||
#include <include/focus.h>
|
||||
#include <include/hook.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <win32k/debug1.h>
|
||||
|
@ -1033,8 +1034,8 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
POINT MaxPos;
|
||||
#endif
|
||||
CREATESTRUCTW Cs;
|
||||
CBT_CREATEWNDW CbtCreate;
|
||||
LRESULT Result;
|
||||
DPRINT("NtUserCreateWindowEx\n");
|
||||
|
||||
DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
|
||||
|
||||
|
@ -1240,6 +1241,30 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
}
|
||||
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.
|
||||
*/
|
||||
|
@ -1276,28 +1301,13 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
|||
IntCreateScrollBar(WindowObject, SB_HORZ);
|
||||
|
||||
/* Send a NCCREATE message. */
|
||||
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;
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
// Any more?
|
||||
|
||||
DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
|
||||
Result = IntSendNCCREATEMessage(WindowObject->Self, &Cs);
|
||||
if (!Result)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
#include <windows.h>
|
||||
|
@ -136,7 +136,7 @@ NtGdiEllipse(HDC hDC,
|
|||
BRUSHOBJ_UnlockBrush(dc->w.hBrush);
|
||||
DC_UnlockDc(hDC);
|
||||
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Radius = (Right - Left) / 2;
|
||||
|
@ -231,22 +231,415 @@ NtGdiEllipse(HDC hDC,
|
|||
BRUSHOBJ_UnlockBrush(dc->w.hBrush);
|
||||
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
|
||||
STDCALL
|
||||
NtGdiPie(HDC hDC,
|
||||
int LeftRect,
|
||||
int TopRect,
|
||||
int RightRect,
|
||||
int BottomRect,
|
||||
int XRadial1,
|
||||
int YRadial1,
|
||||
int XRadial2,
|
||||
int YRadial2)
|
||||
int Left,
|
||||
int Top,
|
||||
int Right,
|
||||
int Bottom,
|
||||
int XRadialStart,
|
||||
int YRadialStart,
|
||||
int XRadialEnd,
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue