[Win32k|User32]

- Rewrite the Event and Hook procedures. See bug 5670 for more details.

svn path=/trunk/; revision=49231
This commit is contained in:
James Tabor 2010-10-23 05:36:12 +00:00
parent 26164e7b2e
commit e7c4137319
27 changed files with 1376 additions and 950 deletions

View file

@ -43,7 +43,8 @@
#include <pseh/pseh2.h>
#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
#define ISITHOOKED(HookId) (GetWin32ClientInfo()->fsHooks & HOOKID_TO_FLAG(HookId))
#define ISITHOOKED(HookId) (GetWin32ClientInfo()->fsHooks & HOOKID_TO_FLAG(HookId) ||\
(GetWin32ClientInfo()->pDeskInfo && GetWin32ClientInfo()->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId)))
/* Temporarily in here for now. */
typedef struct _USERAPIHOOKINFO
@ -194,3 +195,4 @@ VOID FASTCALL GetConnected(VOID);
BOOL FASTCALL DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi);
BOOL FASTCALL TestWindowProcess(PWND);
VOID UserGetWindowBorders(DWORD, DWORD, SIZE *, BOOL);
VOID FASTCALL IntNotifyWinEvent(DWORD, HWND, LONG, LONG, DWORD);

View file

@ -83,9 +83,6 @@
#define NtUserGetCursorPos(lpPoint) \
(BOOL)NtUserCallOneParam((DWORD_PTR)lpPoint, ONEPARAM_ROUTINE_GETCURSORPOSITION)
#define NtUserIsWindowInDestroy(hWnd) \
(BOOL)NtUserCallOneParam((DWORD_PTR)hWnd, ONEPARAM_ROUTINE_ISWINDOWINDESTROY)
#define NtUserEnableProcessWindowGhosting(bEnable) \
NtUserCallOneParam((DWORD_PTR)bEnable, ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING)

View file

@ -304,13 +304,13 @@ GetUser32Handle(HANDLE handle)
static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
{
FALSE, /* VALIDATE_TYPE_FREE (not used) */
FALSE, /* VALIDATE_TYPE_WIN FALSE */
FALSE, /* VALIDATE_TYPE_WIN */
TRUE, /* VALIDATE_TYPE_MENU FALSE */
TRUE, /* VALIDATE_TYPE_CURSOR */
TRUE, /* VALIDATE_TYPE_MWPOS */
TRUE, /* VALIDATE_TYPE_HOOK FALSE */
FALSE, /* VALIDATE_TYPE_HOOK */
FALSE, /* (not used) */
TRUE, /* VALIDATE_TYPE_CALLPROC FALSE */
FALSE, /* VALIDATE_TYPE_CALLPROC */
TRUE, /* VALIDATE_TYPE_ACCEL */
FALSE, /* (not used) */
FALSE, /* (not used) */

View file

@ -103,6 +103,7 @@ BOOL
FASTCALL
DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
{
BOOL Ret;
LARGE_STRING lsString;
if ( String )
@ -112,7 +113,12 @@ DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
else
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0);
}
return NtUserDefSetText(hWnd, (String ? &lsString : NULL));
Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL));
if (Ret)
IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
return Ret;
}
void
@ -1969,7 +1975,6 @@ RealDefWindowProcA(HWND hWnd,
{
DefWndNCPaint(hWnd, (HRGN)1, -1);
}
Result = 1;
break;
}

View file

@ -34,6 +34,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(user32);
typedef struct _NOTIFYEVENT
{
DWORD event;
LONG idObject;
LONG idChild;
DWORD flags;
} NOTIFYEVENT, *PNOTIFYEVENT;
/* PRIVATE FUNCTIONS *********************************************************/
static
@ -99,6 +107,29 @@ IntSetWindowsHook(
return NtUserSetWindowsHookEx(hMod, &USModuleName, dwThreadId, idHook, lpfn, bAnsi);
}
/*
Since ReactOS uses User32 as the main message source this was needed.
Base on the funny rules from the wine tests it left it with this option.
8^(
*/
VOID
FASTCALL
IntNotifyWinEvent(
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD flags
)
{
NOTIFYEVENT ne;
ne.event = event;
ne.idObject = idObject;
ne.idChild = idChild;
ne.flags = flags;
if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(event))
NtUserCallHwndParam(hwnd, (DWORD)&ne, HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT);
}
/* FUNCTIONS *****************************************************************/
@ -195,7 +226,7 @@ CallNextHookEx(
{
PCLIENTINFO ClientInfo;
DWORD Flags, Save;
PHOOK pHook;
PHOOK pHook, phkNext;
LRESULT lResult = 0;
GetConnected();
@ -204,9 +235,14 @@ CallNextHookEx(
if (!ClientInfo->phkCurrent) return 0;
pHook = SharedPtrToUser(ClientInfo->phkCurrent);
pHook = DesktopPtrToUser(ClientInfo->phkCurrent);
if (pHook->HookId == WH_CALLWNDPROC || pHook->HookId == WH_CALLWNDPROCRET)
if (!pHook->phkNext) return 0; // Nothing to do....
phkNext = DesktopPtrToUser(pHook->phkNext);
if ( phkNext->HookId == WH_CALLWNDPROC ||
phkNext->HookId == WH_CALLWNDPROCRET)
{
Save = ClientInfo->dwHookData;
Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK;
@ -215,7 +251,7 @@ CallNextHookEx(
if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK;
else ClientInfo->CI_flags &= ~CI_CURTHPRHOOK;
if (pHook->HookId == WH_CALLWNDPROC)
if (phkNext->HookId == WH_CALLWNDPROC)
{
PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam;
@ -225,7 +261,7 @@ CallNextHookEx(
pCWP->lParam,
(ULONG_PTR)&lResult,
FNID_CALLWNDPROC,
pHook->Ansi);
phkNext->Ansi);
}
else
{
@ -239,7 +275,7 @@ CallNextHookEx(
pCWPR->lParam,
(ULONG_PTR)&lResult,
FNID_CALLWNDPROCRET,
pHook->Ansi);
phkNext->Ansi);
}
ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK);
ClientInfo->dwHookData = Save;
@ -252,23 +288,27 @@ CallNextHookEx(
/*
* @unimplemented
* @implemented
*/
HHOOK
WINAPI
SetWindowsHookW(int idHook, HOOKPROC lpfn)
{
return IntSetWindowsHook(idHook, lpfn, NULL, 0, FALSE);
DWORD ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread);
return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, FALSE);
// return NtUserSetWindowsHookAW(idHook, lpfn, FALSE);
}
/*
* @unimplemented
* @implemented
*/
HHOOK
WINAPI
SetWindowsHookA(int idHook, HOOKPROC lpfn)
{
return IntSetWindowsHook(idHook, lpfn, NULL, 0, TRUE);
DWORD ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread);
return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, TRUE);
// return NtUserSetWindowsHookAW(idHook, lpfn, TRUE);
}
/*
@ -377,7 +417,7 @@ IsWinEventHookInstalled(
}
/*
* @unimplemented
* @implemented
*/
HHOOK
WINAPI
@ -392,7 +432,7 @@ SetWindowsHookExA(
/*
* @unimplemented
* @implemented
*/
HHOOK
WINAPI
@ -417,14 +457,15 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
WPARAM wParam = 0;
LPARAM lParam = 0;
PKBDLLHOOKSTRUCT KeyboardLlData;
PMSLLHOOKSTRUCT MouseLlData;
PMSG Msg;
PMOUSEHOOKSTRUCT MHook;
PCWPSTRUCT CWP;
PCWPRETSTRUCT CWPR;
PKBDLLHOOKSTRUCT pKeyboardLlData;
PMSLLHOOKSTRUCT pMouseLlData;
PMSG pMsg;
PMOUSEHOOKSTRUCT pMHook;
PCWPSTRUCT pCWP;
PCWPRETSTRUCT pCWPR;
PRECTL prl;
LPCBTACTIVATESTRUCT pcbtas;
BOOL Hit = FALSE;
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
@ -464,8 +505,8 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
}
break;
case HCBT_CLICKSKIPPED:
MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
lParam = (LPARAM) MHook;
pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
lParam = (LPARAM) pMHook;
break;
case HCBT_MOVESIZE:
prl = (PRECTL)((PCHAR) Common + Common->lParam);
@ -475,7 +516,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
pcbtas = (LPCBTACTIVATESTRUCT)((PCHAR) Common + Common->lParam);
lParam = (LPARAM) pcbtas;
break;
case HCBT_KEYSKIPPED:
case HCBT_KEYSKIPPED: /* The rest SEH support */
case HCBT_MINMAX:
case HCBT_SETFOCUS:
case HCBT_SYSCOMMAND:
@ -490,7 +531,17 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
}
if (Common->Proc)
Result = Common->Proc(Common->Code, wParam, lParam);
{
_SEH2_TRY
{
Result = Common->Proc(Common->Code, wParam, lParam);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
}
else
{
ERR("Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc);
@ -504,41 +555,67 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
break;
}
case WH_KEYBOARD_LL:
KeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) KeyboardLlData);
pKeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pKeyboardLlData);
break;
case WH_MOUSE_LL:
MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData);
pMouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMouseLlData);
break;
case WH_MOUSE:
MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MHook);
case WH_MOUSE: /* SEH support */
pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
_SEH2_TRY
{
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMHook);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
break;
case WH_CALLWNDPROC:
CWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWP);
pCWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
break;
case WH_CALLWNDPROCRET:
CWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWPR);
pCWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
break;
case WH_MSGFILTER:
case WH_MSGFILTER: /* All SEH support */
case WH_SYSMSGFILTER:
case WH_GETMESSAGE:
Msg = (PMSG)((PCHAR) Common + Common->lParam);
// FIXME("UHOOK Memory: %x: %x\n",Common, Msg);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) Msg);
pMsg = (PMSG)((PCHAR) Common + Common->lParam);
_SEH2_TRY
{
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMsg);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
break;
case WH_FOREGROUNDIDLE:
case WH_FOREGROUNDIDLE: /* <-- SEH support */
case WH_KEYBOARD:
case WH_SHELL:
Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
_SEH2_TRY
{
Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
break;
default:
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
}
if (Hit)
{
ERR("Hook Exception! Id: %d, Code %d, Proc 0x%x\n",Common->HookId,Common->Code,Common->Proc);
}
return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
}

View file

@ -138,6 +138,7 @@ EnableWindow(HWND hWnd,
if (Update)
{
IntNotifyWinEvent(EVENT_OBJECT_STATECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
SendMessageW(hWnd, WM_ENABLE, (LPARAM)bEnable, 0);
}
// Return nonzero if it was disabled, or zero if it wasn't:

View file

@ -1636,6 +1636,8 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
top_popup_hmenu = hmenu;
}
IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
/* Display the window */
SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0,
@ -3445,6 +3447,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
if (MenuInfo.Flags & MF_POPUP)
{
IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
DestroyWindow(MenuInfo.Wnd);
MenuInfo.Wnd = NULL;
@ -3518,7 +3521,11 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
MenuInfo.Wnd = hWnd;
MenuSetRosMenuInfo(&MenuInfo);
}
IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
hWnd,
MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
CHILDID_SELF, 0);
return TRUE;
}
/***********************************************************************
@ -3528,6 +3535,7 @@ static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup)
{
TRACE("hwnd=%p\n", hWnd);
IntNotifyWinEvent( EVENT_SYSTEM_MENUEND, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 );
ShowCaret(0);
top_popup = 0;
@ -3645,7 +3653,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
{
BOOL ret = FALSE;
if (!IsMenu(Menu))
if (!IsMenu(Menu))
{
SetLastError( ERROR_INVALID_MENU_HANDLE );
return FALSE;

View file

@ -2064,13 +2064,18 @@ SendMessageW(HWND Wnd,
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{
if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo()))
if ( Window != NULL &&
Window->head.pti == ti &&
!IsThreadHooked(GetWin32ClientInfo()) &&
!(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
{
/* NOTE: We can directly send messages to the window procedure
if *all* the following conditions are met:
* Window belongs to calling thread
* The calling thread is not being hooked
* Not calling a server side proc:
Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
*/
return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, FALSE);
@ -2130,13 +2135,18 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{
if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo()))
if ( Window != NULL &&
Window->head.pti == ti &&
!IsThreadHooked(GetWin32ClientInfo()) &&
!(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
{
/* NOTE: We can directly send messages to the window procedure
if *all* the following conditions are met:
* Window belongs to calling thread
* The calling thread is not being hooked
* Not calling a server side proc:
Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
*/
return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, TRUE);

View file

@ -2060,7 +2060,11 @@ AnyPopup(VOID)
BOOL WINAPI
IsWindowInDestroy(HWND hWnd)
{
return NtUserIsWindowInDestroy(hWnd);
PWND pwnd;
pwnd = ValidateHwnd(hWnd);
if (!pwnd)
return FALSE;
return ((pwnd->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY);
}
/*

View file

@ -51,13 +51,15 @@ VOID NTAPI RtlInitLargeAnsiString(IN OUT PLARGE_ANSI_STRING,IN PCSZ,IN INT);
VOID NTAPI RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING,IN PCWSTR,IN INT);
BOOL NTAPI RtlLargeStringToUnicodeString( PUNICODE_STRING, PLARGE_STRING);
#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
typedef struct _DESKTOPINFO
{
PVOID pvDesktopBase;
PVOID pvDesktopLimit;
struct _WND *spwnd;
DWORD fsHooks;
struct tagHOOK * aphkStart[16];
LIST_ENTRY aphkStart[NB_HOOKS];
HWND hTaskManWindow;
HWND hProgmanWindow;
@ -127,15 +129,23 @@ typedef struct _PROCMARKHEAD
/* Window Client Information structure */
struct _ETHREAD;
#define WEF_SETBYWNDPTI 0x0001
typedef struct tagHOOK
{
THRDESKHEAD head;
struct tagHOOK *phkNext; /* This is for user space. */
int HookId; /* Hook table index */
ULONG_PTR offPfn;
ULONG flags; /* Some internal flags */
INT ihmod;
PTHREADINFO ptiHooked;
struct _DESKTOP *rpdesk;
/* ReactOS */
LIST_ENTRY Chain; /* Hook chain entry */
struct _ETHREAD* Thread; /* Thread owning the hook */
int HookId; /* Hook table index */
HOOKPROC Proc; /* Hook function */
BOOLEAN Ansi; /* Is it an Ansi hook? */
ULONG Flags; /* Some internal flags */
UNICODE_STRING ModuleName; /* Module name for global hooks */
} HOOK, *PHOOK;
@ -3149,7 +3159,6 @@ typedef struct tagKMDDELPARAM
#define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006
#define ONEPARAM_ROUTINE_CSRSS_GUICHECK 0xffff0008
#define ONEPARAM_ROUTINE_SWITCHCARETSHOWING 0xfffe0008
#define ONEPARAM_ROUTINE_ISWINDOWINDESTROY 0xfffe000c
#define ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING 0xfffe000d
#define ONEPARAM_ROUTINE_GETDESKTOPMAPPING 0xfffe000e
#define ONEPARAM_ROUTINE_MSQSETWAKEMASK 0xfffe0027
@ -3167,6 +3176,7 @@ typedef struct tagKMDDELPARAM
#define TWOPARAM_ROUTINE_SETCARETPOS 0xfffd0060
#define TWOPARAM_ROUTINE_REGISTERLOGONPROC 0xfffd0062
#define TWOPARAM_ROUTINE_ROS_UPDATEUISTATE 0x1004
#define HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT 0x1005
DWORD
NTAPI

View file

@ -1,17 +1,10 @@
#pragma once
#define HOOK_THREAD_REFERENCED (0x1)
#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK)
#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
#define ISITHOOKED(HookId) (((PTHREADINFO)PsGetCurrentThreadWin32Thread())->fsHooks & HOOKID_TO_FLAG(HookId))
typedef struct tagHOOKTABLE
{
LIST_ENTRY Hooks[NB_HOOKS]; /* array of hook chains */
UINT Counts[NB_HOOKS]; /* use counts for each hook chain */
} HOOKTABLE, *PHOOKTABLE;
typedef struct tagEVENTHOOK
{
THROBJHEAD head;
@ -32,11 +25,22 @@ typedef struct tagEVENTTABLE
UINT Counts;
} EVENTTABLE, *PEVENTTABLE;
typedef struct _NOTIFYEVENT
{
DWORD event;
LONG idObject;
LONG idChild;
DWORD flags;
} NOTIFYEVENT, *PNOTIFYEVENT;
LRESULT FASTCALL co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, UINT_PTR, LONG_PTR);
VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread);
VOID FASTCALL EVENT_DestroyThreadEvents(PETHREAD Thread);
PHOOK FASTCALL IntGetHookObject(HHOOK);
PHOOK FASTCALL IntGetNextHook(PHOOK Hook);
LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi);
BOOL FASTCALL IntUnhookWindowsHook(int,HOOKPROC);
/* EOF */

View file

@ -87,9 +87,6 @@ typedef struct _USER_MESSAGE_QUEUE
/* Caret information for this queue */
PTHRDCARETINFO CaretInfo;
/* Window hooks */
PHOOKTABLE Hooks;
/* queue state tracking */
WORD WakeMask;
WORD QueueBits;
@ -212,9 +209,6 @@ BOOL APIENTRY IntInitMessagePumpHook();
BOOL APIENTRY 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);
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam);
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */

View file

@ -96,6 +96,7 @@ typedef struct _THREADINFO
LIST_ENTRY PtiLink;
POINT ptLast;
LIST_ENTRY aphkStart[NB_HOOKS];
CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL.
/* ReactOS */
LIST_ENTRY WindowListHead;
@ -150,6 +151,8 @@ typedef struct _W32PROCESS
LIST_ENTRY GDIBrushAttrFreeList;
} W32PROCESS, *PW32PROCESS;
#define CLIBS 32
typedef struct _PROCESSINFO
{
W32PROCESS;
@ -158,11 +161,15 @@ typedef struct _PROCESSINFO
struct _DESKTOP* rpdeskStartup;
PCLS pclsPrivateList;
PCLS pclsPublicList;
DWORD dwhmodLibLoadedMask;
HANDLE ahmodLibLoaded[CLIBS];
struct _WINSTATION_OBJECT *prpwinsta;
HWINSTA hwinsta;
ACCESS_MASK amwinsta;
DWORD dwHotkey;
HMONITOR hMonitor;
LUID luidSession;
USERSTARTUPINFO usi;
ULONG Flags;
DWORD dwLayout;
DWORD dwRegisteredClasses;
/* ReactOS */

View file

@ -104,7 +104,7 @@ IntShowOwnedPopups( PWND owner, BOOL fShow );
LRESULT FASTCALL
IntDefWindowProc( PWND Window, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi);
VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG);
VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG, DWORD);
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRING);
WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL);

View file

@ -175,6 +175,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
{
struct _EPROCESS *Process;
PTHREADINFO Win32Thread;
int i;
DECLARE_RETURN(NTSTATUS);
DPRINT("Enter Win32kThreadCallback\n");
@ -214,6 +215,10 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
InitializeListHead(&Win32Thread->WindowListHead);
InitializeListHead(&Win32Thread->W32CallbackListHead);
InitializeListHead(&Win32Thread->PtiLink);
for (i = 0; i < NB_HOOKS; i++)
{
InitializeListHead(&Win32Thread->aphkStart[i]);
}
/*
* inherit the thread desktop and process window station (if not yet inherited) from the process startup
@ -290,6 +295,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
Win32Thread->TIF_flags |= TIF_INCLEANUP;
DceFreeThreadDCE(Win32Thread);
HOOK_DestroyThreadHooks(Thread);
EVENT_DestroyThreadEvents(Thread);
/* Cleanup timers */
DestroyTimersForThread(Win32Thread);
KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);

View file

@ -324,20 +324,20 @@ co_IntCallHookProc(INT HookId,
PUNICODE_STRING ModuleName)
{
ULONG ArgumentLength;
PVOID Argument;
PVOID Argument = NULL;
LRESULT Result = 0;
NTSTATUS Status;
PVOID ResultPointer;
ULONG ResultLength;
PHOOKPROC_CALLBACK_ARGUMENTS Common;
CBT_CREATEWNDW *CbtCreateWnd =NULL;
CBT_CREATEWNDW *CbtCreateWnd = NULL;
PCHAR Extra;
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
UNICODE_STRING WindowName;
UNICODE_STRING ClassName;
PANSI_STRING asWindowName;
PANSI_STRING asClassName;
UNICODE_STRING WindowName, ClassName;
ANSI_STRING asWindowName, asClassName;
PTHREADINFO pti;
PWND pWnd;
BOOL Hit = FALSE;
ASSERT(Proc);
@ -356,33 +356,67 @@ co_IntCallHookProc(INT HookId,
switch(Code)
{
case HCBT_CREATEWND:
pWnd = UserGetWindowObject((HWND) wParam);
if (!pWnd)
{
DPRINT1("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n");
goto Fault_Exit;
}
CbtCreateWnd = (CBT_CREATEWNDW *) lParam;
ArgumentLength += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS);
asWindowName = (PANSI_STRING)&WindowName;
asClassName = (PANSI_STRING)&ClassName;
if (Ansi)
{
RtlInitAnsiString(asWindowName, (PCSZ)CbtCreateWnd->lpcs->lpszName);
ArgumentLength += WindowName.Length + sizeof(CHAR);
RtlInitAnsiString(&asWindowName, NULL);
_SEH2_TRY
{
ProbeForRead(CbtCreateWnd->lpcs->lpszName, sizeof(CHAR), 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
if (Hit) // Client is at deaths door.
goto Fault_Exit;
if (CbtCreateWnd->lpcs->lpszName)
RtlInitAnsiString(&asWindowName, (PCSZ)CbtCreateWnd->lpcs->lpszName);
ArgumentLength += asWindowName.Length + sizeof(CHAR);
}
else
{
RtlInitUnicodeString(&WindowName, CbtCreateWnd->lpcs->lpszName);
RtlInitUnicodeString(&WindowName, NULL);
_SEH2_TRY
{
ProbeForRead(CbtCreateWnd->lpcs->lpszName, sizeof(WCHAR), 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
if (Hit)
goto Fault_Exit;
if (CbtCreateWnd->lpcs->lpszName)
RtlInitUnicodeString(&WindowName, CbtCreateWnd->lpcs->lpszName);
ArgumentLength += WindowName.Length + sizeof(WCHAR);
}
if (! IS_ATOM(CbtCreateWnd->lpcs->lpszClass))
if (!IS_ATOM(CbtCreateWnd->lpcs->lpszClass))
{
if (Ansi)
{
RtlInitAnsiString(asClassName, (PCSZ)CbtCreateWnd->lpcs->lpszClass);
ArgumentLength += ClassName.Length + sizeof(CHAR);
RtlInitAnsiString(&asClassName, NULL);
if (CbtCreateWnd->lpcs->lpszClass)
RtlInitAnsiString(&asClassName, (PCSZ)CbtCreateWnd->lpcs->lpszClass);
ArgumentLength += asClassName.Length + sizeof(CHAR);
}
else
{
RtlInitUnicodeString(&ClassName, CbtCreateWnd->lpcs->lpszClass);
RtlInitUnicodeString(&ClassName, NULL);
if (CbtCreateWnd->lpcs->lpszClass)
RtlInitUnicodeString(&ClassName, CbtCreateWnd->lpcs->lpszClass);
ArgumentLength += ClassName.Length + sizeof(WCHAR);
}
}
@ -408,7 +442,7 @@ co_IntCallHookProc(INT HookId,
break;
default:
DPRINT1("Trying to call unsupported CBT hook %d\n", Code);
return 0;
goto Fault_Exit;
}
break;
case WH_KEYBOARD_LL:
@ -437,14 +471,14 @@ co_IntCallHookProc(INT HookId,
break;
default:
DPRINT1("Trying to call unsupported window hook %d\n", HookId);
return 0;
goto Fault_Exit;
}
Argument = IntCbAllocateMemory(ArgumentLength);
if (NULL == Argument)
{
DPRINT1("HookProc callback failed: out of memory\n");
return 0;
goto Fault_Exit;
}
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Argument;
Common->HookId = HookId;
@ -454,7 +488,8 @@ co_IntCallHookProc(INT HookId,
Common->Proc = Proc;
Common->Ansi = Ansi;
Common->ModuleNameLength = ModuleName->Length;
memcpy(Common->ModuleName, ModuleName->Buffer, ModuleName->Length);
if (ModuleName->Buffer)
RtlCopyMemory(Common->ModuleName, ModuleName->Buffer, ModuleName->Length);
Extra = (PCHAR) Common->ModuleName + Common->ModuleNameLength;
switch(HookId)
@ -468,32 +503,53 @@ co_IntCallHookProc(INT HookId,
RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs, sizeof(CREATESTRUCTW) );
CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter;
Extra = (PCHAR) (CbtCreatewndExtra + 1);
RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length);
CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
CbtCreatewndExtra->Cs.lpszClass = ClassName.Buffer;
Extra += WindowName.Length;
CbtCreatewndExtra->Cs.lpszClass = ClassName.Buffer; // if Atom
if (Ansi)
{
if (asWindowName.Buffer)
RtlCopyMemory(Extra, asWindowName.Buffer, asWindowName.Length);
CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
Extra += asWindowName.Length;
*((CHAR *) Extra) = '\0';
Extra += sizeof(CHAR);
}
else
{
if (asWindowName.Buffer)
RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length);
CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
Extra += WindowName.Length;
*((WCHAR *) Extra) = L'\0';
Extra += sizeof(WCHAR);
}
if (! IS_ATOM(ClassName.Buffer))
if (!IS_ATOM(ClassName.Buffer))
{
RtlCopyMemory(Extra, ClassName.Buffer, ClassName.Length);
CbtCreatewndExtra->Cs.lpszClass =
(LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
Extra += ClassName.Length;
if (Ansi)
{
if (asClassName.Buffer)
RtlCopyMemory(Extra, asClassName.Buffer, asClassName.Length);
CbtCreatewndExtra->Cs.lpszClass =
(LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
Extra += asClassName.Length;
*((CHAR *) Extra) = '\0';
Extra += sizeof(CHAR);
}
else
{
if (ClassName.Buffer)
RtlCopyMemory(Extra, ClassName.Buffer, ClassName.Length);
CbtCreatewndExtra->Cs.lpszClass =
(LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
Extra += ClassName.Length;
*((WCHAR *) Extra) = L'\0';
Extra += sizeof(WCHAR);
}
}
break;
case HCBT_CLICKSKIPPED:
@ -535,7 +591,6 @@ co_IntCallHookProc(INT HookId,
case WH_GETMESSAGE:
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSG));
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
// DPRINT1("KHOOK Memory: %x\n",Common);
break;
case WH_FOREGROUNDIDLE:
case WH_KEYBOARD:
@ -565,37 +620,47 @@ co_IntCallHookProc(INT HookId,
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Result = 0;
Hit = TRUE;
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
return 0;
goto Fault_Exit;
}
if (HookId == WH_CBT && Code == HCBT_CREATEWND)
/* Support write backs... SEH is in UserCallNextHookEx. */
switch (HookId)
{
if (CbtCreatewndExtra)
{
_SEH2_TRY
{ /*
The parameters could have been changed, include the coordinates
and dimensions of the window. We copy it back.
*/
CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x;
CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y;
CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx;
CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
case WH_CBT:
if (Code == HCBT_CREATEWND)
{
Result = 0;
if (CbtCreatewndExtra)
{/*
The parameters could have been changed, include the coordinates
and dimensions of the window. We copy it back.
*/
CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x;
CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y;
CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx;
CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy;
}
}
_SEH2_END;
}
break;
// "The GetMsgProc hook procedure can examine or modify the message."
case WH_GETMESSAGE:
if (lParam)
{
RtlCopyMemory((PVOID) lParam, Extra, sizeof(MSG));
}
break;
}
Fault_Exit:
if (Hit)
{
DPRINT1("Exception CallHookProc HookId %d Code %d\n",HookId,Code);
}
if (Argument) IntCbFreeMemory(Argument);
return Result;

View file

@ -30,10 +30,13 @@ static
BOOL FASTCALL
co_IntHideCaret(PTHRDCARETINFO CaretInfo)
{
PWND pWnd;
if(CaretInfo->hWnd && CaretInfo->Visible && CaretInfo->Showing)
{
pWnd = UserGetWindowObject(CaretInfo->hWnd);
co_IntSendMessage(CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
CaretInfo->Showing = 0;
IntNotifyWinEvent(EVENT_OBJECT_HIDE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
return TRUE;
}
return FALSE;
@ -43,17 +46,20 @@ BOOL FASTCALL
co_IntDestroyCaret(PTHREADINFO Win32Thread)
{
PUSER_MESSAGE_QUEUE ThreadQueue;
PWND pWnd;
ThreadQueue = (PUSER_MESSAGE_QUEUE)Win32Thread->MessageQueue;
if(!ThreadQueue || !ThreadQueue->CaretInfo)
return FALSE;
pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
co_IntHideCaret(ThreadQueue->CaretInfo);
ThreadQueue->CaretInfo->Bitmap = (HBITMAP)0;
ThreadQueue->CaretInfo->hWnd = (HWND)0;
ThreadQueue->CaretInfo->Size.cx = ThreadQueue->CaretInfo->Size.cy = 0;
ThreadQueue->CaretInfo->Showing = 0;
ThreadQueue->CaretInfo->Visible = 0;
IntNotifyWinEvent(EVENT_OBJECT_DESTROY, pWnd, OBJID_CARET, CHILDID_SELF, 0);
return TRUE;
}
@ -176,6 +182,7 @@ BOOL FASTCALL
co_IntSetCaretPos(int X, int Y)
{
PTHREADINFO pti;
PWND pWnd;
PUSER_MESSAGE_QUEUE ThreadQueue;
pti = PsGetCurrentThreadWin32Thread();
@ -183,6 +190,7 @@ co_IntSetCaretPos(int X, int Y)
if(ThreadQueue->CaretInfo->hWnd)
{
pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
if(ThreadQueue->CaretInfo->Pos.x != X || ThreadQueue->CaretInfo->Pos.y != Y)
{
co_IntHideCaret(ThreadQueue->CaretInfo);
@ -191,6 +199,7 @@ co_IntSetCaretPos(int X, int Y)
ThreadQueue->CaretInfo->Pos.y = Y;
co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM);
IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
}
return TRUE;
}
@ -277,6 +286,7 @@ BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
{
PTHREADINFO pti;
PWND pWnd;
PUSER_MESSAGE_QUEUE ThreadQueue;
if (Window) ASSERT_REFS_CO(Window);
@ -301,11 +311,12 @@ BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
ThreadQueue->CaretInfo->Visible = 1;
if(!ThreadQueue->CaretInfo->Showing)
{
pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
}
IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM);
}
return TRUE;
}
@ -370,7 +381,7 @@ NtUserCreateCaret(
}
ThreadQueue->CaretInfo->Visible = 0;
ThreadQueue->CaretInfo->Showing = 0;
IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
RETURN(TRUE);
CLEANUP:

View file

@ -884,6 +884,7 @@ NtUserCreateDesktop(
LARGE_STRING WindowName;
PWND pWnd = NULL;
CREATESTRUCTW Cs;
INT i;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
@ -1026,6 +1027,11 @@ NtUserCreateDesktop(
/* Initialize some local (to win32k) desktop state. */
InitializeListHead(&DesktopObject->PtiList);
DesktopObject->ActiveMessageQueue = NULL;
/* Setup Global Hooks. */
for (i = 0; i < NB_HOOKS; i++)
{
InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]);
}
ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING);
if (! NT_SUCCESS(Status))

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Window event handlers
* FILE: subsystem/win32/win32k/ntuser/event.c
* FILE: subsystems/win32/win32k/ntuser/event.c
* PROGRAMER: James Tabor (james.tabor@rectos.org)
*/
@ -103,12 +103,15 @@ IntCallLowLevelEvent( PEVENTHOOK pEH,
LONG idChild)
{
NTSTATUS Status;
ULONG_PTR uResult;
EVENTPACK EP;
PEVENTPACK pEP;
ULONG_PTR uResult = 0;
EP.pEH = pEH;
EP.idObject = idObject;
EP.idChild = idChild;
pEP = ExAllocatePoolWithTag(NonPagedPool, sizeof(EVENTPACK), TAG_HOOK);
if (!pEP) return 0;
pEP->pEH = pEH;
pEP->idObject = idObject;
pEP->idChild = idChild;
/* FIXME should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
@ -116,16 +119,18 @@ IntCallLowLevelEvent( PEVENTHOOK pEH,
hwnd,
event,
0,
(LPARAM)&EP,
(LPARAM)pEP,
5000,
TRUE,
MSQ_ISEVENT,
&uResult);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(pEP, TAG_HOOK);
}
return NT_SUCCESS(Status) ? uResult : 0;
}
static
BOOL
FASTCALL
@ -145,14 +150,49 @@ IntRemoveEvent(PEVENTHOOK pEH)
return FALSE;
}
VOID
FASTCALL
EVENT_DestroyThreadEvents(PETHREAD Thread)
{
PTHREADINFO pti;
PEVENTHOOK pEH;
PLIST_ENTRY pLE;
pti = Thread->Tcb.Win32Thread;
if (!pti) return;
if (!GlobalEvents || !GlobalEvents->Counts) return;
pLE = GlobalEvents->Events.Flink;
if (IsListEmpty(pLE)) return;
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
do
{
if (IsListEmpty(pLE)) break;
if (!pEH) break;
pLE = pEH->Chain.Flink;
if (pEH->head.pti == pti)
{
IntRemoveEvent(pEH);
}
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
} while (pLE != &GlobalEvents->Events);
return;
}
/* FUNCTIONS *****************************************************************/
//
// Dispatch MsgQueue Event Call processor!
//
LRESULT
FASTCALL
co_EVENT_CallEvents( DWORD event,
HWND hwnd,
UINT_PTR idObject,
LONG_PTR idChild)
HWND hwnd,
UINT_PTR idObject,
LONG_PTR idChild)
{
PEVENTHOOK pEH;
LRESULT Result;
@ -165,9 +205,11 @@ co_EVENT_CallEvents( DWORD event,
hwnd,
pEP->idObject,
pEP->idChild,
(DWORD_PTR)(NtCurrentTeb()->ClientId).UniqueThread,
PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
(DWORD)EngGetTickCount(),
pEH->Proc);
ExFreePoolWithTag(pEP, TAG_HOOK);
return Result;
}
@ -177,55 +219,66 @@ IntNotifyWinEvent(
DWORD Event,
PWND pWnd,
LONG idObject,
LONG idChild)
LONG idChild,
DWORD flags)
{
PEVENTHOOK pEH;
PLIST_ENTRY pLE;
PTHREADINFO pti, ptiCurrent;
DPRINT("IntNotifyWinEvent GlobalEvents = 0x%x pWnd 0x%x\n",GlobalEvents, pWnd);
if (!pWnd) return;
if (!GlobalEvents || !GlobalEvents->Counts) return;
if (pWnd && pWnd->state & WNDS_DESTROYED) return;
if (!GlobalEvents || !GlobalEvents->Counts) return;
ptiCurrent = PsGetCurrentThreadWin32Thread();
if (pWnd && flags & WEF_SETBYWNDPTI)
pti = pWnd->head.pti;
else
pti = ptiCurrent;
pLE = GlobalEvents->Events.Flink;
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
do
{
{
if (!pEH) break;
UserReferenceObject(pEH);
// Must be inside the event window.
if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event))
{
if (pEH->head.pti->pEThread != PsGetCurrentThread())
{ // if all process || all thread || other thread same process
if (!(pEH->idProcess) || !(pEH->idThread) ||
(NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess))
// if all process || all thread || other thread same process
// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
if ( (!pEH->idProcess || pEH->idProcess == PtrToUint(pti->pEThread->Cid.UniqueProcess)) &&
(!(pEH->Flags & WINEVENT_SKIPOWNPROCESS) || pEH->head.pti->ppi != pti->ppi) &&
(!pEH->idThread || pEH->idThread == PtrToUint(pti->pEThread->Cid.UniqueThread)) &&
(!(pEH->Flags & WINEVENT_SKIPOWNTHREAD) || pEH->head.pti != pti) &&
pEH->head.pti->rpdesk == ptiCurrent->rpdesk ) // Same as hooks.
{
// Send message to the thread if pEH is not current.
if (pEH->head.pti != ptiCurrent)
{
DPRINT1("Global Event 0x%x, idObject %d\n", Event, idObject);
IntCallLowLevelEvent( pEH,
Event,
UserHMGetHandle(pWnd),
idObject,
idChild);
}
}// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
else if ( !(pEH->Flags & WINEVENT_SKIPOWNTHREAD) &&
( ((pEH->idProcess &&
NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess) &&
!(pEH->Flags & WINEVENT_SKIPOWNPROCESS)) ||
!pEH->idProcess ) )
{
// What in the deuce is this right-aligned formatting?
co_IntCallEventProc( UserHMGetHandle(pEH),
Event,
UserHMGetHandle(pWnd),
idObject,
idChild,
PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
(DWORD)EngGetTickCount(),
pEH->Proc);
}
else
{
DPRINT1("Local Event 0x%x, idObject %d\n", Event, idObject);
co_IntCallEventProc( UserHMGetHandle(pEH),
Event,
UserHMGetHandle(pWnd),
idObject,
idChild,
PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
(DWORD)EngGetTickCount(),
pEH->Proc);
}
}
}
UserDereferenceObject(pEH);
pLE = pEH->Chain.Flink;
@ -255,7 +308,7 @@ NtUserNotifyWinEvent(
if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(Event))
{
UserRefObjectCo(Window, &Ref);
IntNotifyWinEvent( Event, Window, idObject, idChild);
IntNotifyWinEvent( Event, Window, idObject, idChild, WEF_SETBYWNDPTI);
UserDerefObjectCo(Window);
}
UserLeave();
@ -322,7 +375,7 @@ NtUserSetWinEventHook(
goto SetEventExit;
}
}
// Creator, pti is set here.
pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK));
if (pEH)
{
@ -330,16 +383,18 @@ NtUserSetWinEventHook(
GlobalEvents->Counts++;
UserHMGetHandle(pEH) = Handle;
if (Thread)
pEH->head.pti = Thread->Tcb.Win32Thread;
else
pEH->head.pti = GetW32ThreadInfo();
pEH->eventMin = eventMin;
pEH->eventMax = eventMax;
pEH->idProcess = idProcess;
pEH->idThread = idThread;
pEH->idProcess = idProcess; // These are cmp'ed
pEH->idThread = idThread; // "
pEH->Flags = dwflags;
/*
If WINEVENT_INCONTEXT, set offset from hmod and proc. Save ihmod from
the atom index table where the hmod data is saved to be recalled later
if fSync set by WINEVENT_INCONTEXT.
If WINEVENT_OUTOFCONTEXT just use proc..
Do this instead....
*/
if (NULL != hmodWinEventProc)
{
pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc);

View file

@ -165,6 +165,7 @@ co_IntSendKillFocusMessages(HWND hWndPrev, HWND hWnd)
{
if (hWndPrev)
{
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(hWndPrev, WM_KILLFOCUS, (WPARAM)hWnd, 0);
}
}
@ -174,6 +175,8 @@ co_IntSendSetFocusMessages(HWND hWndPrev, HWND hWnd)
{
if (hWnd)
{
PWND pWnd = UserGetWindowObject(hWnd);
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(hWnd, WM_SETFOCUS, (WPARAM)hWndPrev, 0);
}
}
@ -356,8 +359,10 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL)
cbt.fMouse = FALSE;
cbt.hWndActive = hWndPrev;
if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
{
DPRINT1("SetActiveWindow WH_CBT Call Hook return!\n");
return 0;
}
ThreadQueue->ActiveWindow = hWnd;
co_IntSendDeactivateMessages(hWndPrev, hWnd);
@ -392,9 +397,11 @@ co_IntSetFocusWindow(PWND Window OPTIONAL)
return hWndPrev;
}
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
return 0;
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
{
DPRINT1("SetFocusWindow 1 WH_CBT Call Hook return!\n");
return 0;
}
ThreadQueue->FocusWindow = Window->head.h;
co_IntSendKillFocusMessages(hWndPrev, Window->head.h);
@ -403,9 +410,11 @@ co_IntSetFocusWindow(PWND Window OPTIONAL)
else
{
ThreadQueue->FocusWindow = 0;
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
return 0;
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
{
DPRINT1("SetFocusWindow 2 WH_CBT Call Hook return!\n");
return 0;
}
co_IntSendKillFocusMessages(hWndPrev, 0);
}
@ -533,7 +542,7 @@ NtUserSetCapture(HWND hWnd)
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
PWND Window;
PWND Window, pWnd;
HWND hWndPrev;
DECLARE_RETURN(HWND);
@ -553,13 +562,23 @@ NtUserSetCapture(HWND hWnd)
hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd);
if (hWndPrev)
{
pWnd = UserGetWindowObject(hWndPrev);
if (pWnd)
IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
}
/* also remove other windows if not capturing anymore */
if(hWnd == NULL)
if (hWnd == NULL)
{
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL);
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL);
}
if (Window)
IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
ThreadQueue->CaptureWindow = hWnd;

File diff suppressed because it is too large Load diff

View file

@ -368,9 +368,10 @@ IntDispatchMessage(PMSG pMsg)
{
LARGE_INTEGER TickCount;
LONG Time;
LRESULT retval;
LRESULT retval = 0;
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
PTHREADINFO pti;
LPARAM lParamPacked;
PWND Window = NULL;
@ -380,25 +381,29 @@ IntDispatchMessage(PMSG pMsg)
if (!Window) return 0;
}
pti = PsGetCurrentThreadWin32Thread();
if (((pMsg->message == WM_SYSTIMER) ||
(pMsg->message == WM_TIMER)) &&
(pMsg->lParam) )
{
if (pMsg->message == WM_TIMER)
{
if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),pMsg->lParam))
ObReferenceObject(pti->pEThread);
if (ValidateTimerCallback(pti,pMsg->lParam))
{
KeQueryTickCount(&TickCount);
Time = MsqCalculateMessageTime(&TickCount);
return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
TRUE,
pMsg->hwnd,
WM_TIMER,
pMsg->wParam,
(LPARAM)Time,
sizeof(LPARAM));
retval = co_IntCallWindowProc((WNDPROC)pMsg->lParam,
TRUE,
pMsg->hwnd,
WM_TIMER,
pMsg->wParam,
(LPARAM)Time,
sizeof(LPARAM));
}
return 0;
ObDereferenceObject(pti->pEThread);
return retval;
}
else
{
@ -431,7 +436,7 @@ IntDispatchMessage(PMSG pMsg)
DPRINT1("Failed to pack message parameters\n");
return 0;
}
ObReferenceObject(pti->pEThread);
retval = co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
pMsg->hwnd,
@ -452,6 +457,7 @@ IntDispatchMessage(PMSG pMsg)
co_UserGetUpdateRgn( Window, hrgn, TRUE );
REGION_FreeRgnByHandle( hrgn );
}
ObDereferenceObject(pti->pEThread);
return retval;
}
@ -784,6 +790,7 @@ BOOL ProcessMouseMessage(MSG* Msg, BOOLEAN RemoveMessages)
HCBT_CLICKSKIPPED,
Msg->message,
(LPARAM)&MHook);
DPRINT1("MouseMessage WH_CBT Call Hook return!\n");
return FALSE;
}
@ -812,6 +819,7 @@ BOOL ProcessKeyboardMessage(MSG* Msg, BOOLEAN RemoveMessages)
HCBT_KEYSKIPPED,
LOWORD(Msg->wParam),
Msg->lParam );
DPRINT1("KeyboardMessage WH_CBT Call Hook return!\n");
return FALSE;
}
return TRUE;
@ -1322,13 +1330,13 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
UINT uTimeout,
ULONG_PTR *uResult )
{
ULONG_PTR Result;
NTSTATUS Status;
PWND Window = NULL;
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
LPARAM lParamPacked;
PTHREADINFO Win32Thread;
ULONG_PTR Result = 0;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
@ -1369,6 +1377,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
RETURN( FALSE);
}
ObReferenceObject(Win32Thread->pEThread);
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
hWnd,
@ -1381,6 +1390,8 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
*uResult = Result;
}
ObDereferenceObject(Win32Thread->pEThread);
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
@ -1408,14 +1419,14 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
do
{
Status = co_MsqSendMessage( Window->head.pti->MessageQueue,
hWnd,
Msg,
wParam,
lParam,
uTimeout,
(uFlags & SMTO_BLOCK),
MSQ_NORMAL,
uResult );
hWnd,
Msg,
wParam,
lParam,
uTimeout,
(uFlags & SMTO_BLOCK),
MSQ_NORMAL,
uResult );
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
@ -1575,7 +1586,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
/* If this is not a callback and it can be sent now, then send it. */
if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
{
ObReferenceObject(Win32Thread->pEThread);
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
hWnd,
@ -1587,6 +1598,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
{
*uResult = Result;
}
ObDereferenceObject(Win32Thread->pEThread);
}
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
@ -2553,12 +2565,13 @@ NtUserMessageCall(
2000,
&RetVal);
}
Ret = RetVal;
}
else if (parm.flags & BSF_POSTMESSAGE)
{
Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
else if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
else //Everything else,,,, if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
{
Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
@ -2584,21 +2597,31 @@ NtUserMessageCall(
case FNID_CALLWNDPROC:
case FNID_CALLWNDPROCRET:
{
PCLIENTINFO ClientInfo = GetWin32ClientInfo();
PHOOK NextObj, Hook = ClientInfo->phkCurrent;
PTHREADINFO pti;
PCLIENTINFO ClientInfo;
PHOOK NextObj, Hook;
if (!ClientInfo || !Hook) break;
pti = GetW32ThreadInfo();
UserReferenceObject(Hook);
Hook = pti->sphkCurrent;
if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
if (!Hook) break;
NextObj = Hook->phkNext;
ClientInfo = pti->pClientInfo;
_SEH2_TRY
{
UserDereferenceObject(Hook);
break;
ClientInfo->phkCurrent = NextObj;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ClientInfo = NULL;
}
_SEH2_END;
NextObj = IntGetNextHook(Hook);
ClientInfo->phkCurrent = NextObj;
if (!ClientInfo || !NextObj) break;
NextObj->phkNext = IntGetNextHook(NextObj);
if ( Hook->HookId == WH_CALLWNDPROC)
{
@ -2634,8 +2657,6 @@ NtUserMessageCall(
Hook->Ansi,
&Hook->ModuleName);
}
UserDereferenceObject(Hook);
lResult = (LRESULT) NextObj;
}
break;
}

View file

@ -948,26 +948,25 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
&Message->ListEntry);
if (Message->HookMessage == MSQ_ISHOOK)
{
Result = co_HOOK_CallHooks(Message->Msg.message,
(INT)(INT_PTR)Message->Msg.hwnd,
Message->Msg.wParam,
Message->Msg.lParam);
{ // Direct Hook Call processor
Result = co_CallHook( Message->Msg.message, // HookId
(INT)(INT_PTR)Message->Msg.hwnd, // Code
Message->Msg.wParam,
Message->Msg.lParam);
}
else if (Message->HookMessage == MSQ_ISEVENT)
{
{ // Direct Event Call processor
Result = co_EVENT_CallEvents( Message->Msg.message,
Message->Msg.hwnd,
Message->Msg.wParam,
Message->Msg.lParam);
}
else
{
/* Call the window procedure. */
Result = co_IntSendMessage(Message->Msg.hwnd,
Message->Msg.message,
Message->Msg.wParam,
Message->Msg.lParam);
{ /* Call the window procedure. */
Result = co_IntSendMessage( Message->Msg.hwnd,
Message->Msg.message,
Message->Msg.wParam,
Message->Msg.lParam);
}
/* remove the message from the local dispatching list, because it doesn't need
@ -1004,7 +1003,9 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
}
/* Call the callback if the message was sent with SendMessageCallback */
/* Call the callback if the message wa
s sent with SendMessageCallback */
if (Message->CompletionCallback != NULL)
{
co_IntCallSentMessageCallback(Message->CompletionCallback,
@ -1133,10 +1134,10 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
NTSTATUS WaitStatus;
LRESULT Result;
PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout;
PLIST_ENTRY Entry;
LRESULT Result = 0; //// Result could be trashed. ////
if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
{
@ -1154,7 +1155,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
/* FIXME - increase reference counter of sender's message queue here */
Result = 0;
Message->Msg.hwnd = Wnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
@ -1164,6 +1164,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
Message->SenderQueue = ThreadQueue;
IntReferenceMessageQueue(ThreadQueue);
Message->CompletionCallback = NULL;
Message->CompletionCallbackContext = 0;
Message->HookMessage = HookMessage;
Message->HasPackedLParam = FALSE;
@ -1632,18 +1633,6 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
IntDereferenceMessageQueue(MessageQueue);
}
PHOOKTABLE FASTCALL
MsqGetHooks(PUSER_MESSAGE_QUEUE Queue)
{
return Queue->Hooks;
}
VOID FASTCALL
MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks)
{
Queue->Hooks = Hooks;
}
LPARAM FASTCALL
MsqSetMessageExtraInfo(LPARAM lParam)
{

View file

@ -330,8 +330,8 @@ UserCreateObject( PUSER_HANDLE_TABLE ht,
{
case otWindow:
// case otMenu:
// case otHook:
// case otCallProc:
case otHook:
case otCallProc:
case otInputContext:
Object = DesktopHeapAlloc(rpdesk, size);
dt = TRUE;
@ -420,8 +420,8 @@ UserDereferenceObject(PVOID object)
{
case otWindow:
// case otMenu:
// case otHook:
// case otCallProc:
case otHook:
case otCallProc:
case otInputContext:
return DesktopHeapFree(((PTHRDESKHEAD)object)->rpdesk, object);

View file

@ -228,21 +228,6 @@ NtUserCallOneParam(
RETURN (ret);
}
case ONEPARAM_ROUTINE_ISWINDOWINDESTROY:
{
PWND Window;
DWORD_PTR Result;
if(!(Window = UserGetWindowObject((HWND)Param)))
{
RETURN( FALSE);
}
Result = (DWORD_PTR)IntIsWindowInDestroy(Window);
RETURN( Result);
}
case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
{
BOOL Enable;
@ -473,6 +458,8 @@ NtUserCallTwoParam(
case TWOPARAM_ROUTINE_SETCURSORPOS:
RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE));
case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK:
RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2));
}
DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
Routine, Param1, Param2);
@ -713,6 +700,21 @@ NtUserCallHwndParam(
UserLeave();
return 0;
}
case HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT:
{
PWND pWnd;
PNOTIFYEVENT pne;
UserEnterExclusive();
pne = (PNOTIFYEVENT)Param;
if (hWnd)
pWnd = UserGetWindowObject(hWnd);
else
pWnd = NULL;
IntNotifyWinEvent(pne->event, pWnd, pne->idObject, pne->idChild, pne->flags);
UserLeave();
return 0;
}
}
UNIMPLEMENTED;

View file

@ -163,7 +163,6 @@ IntIsWindow(HWND hWnd)
}
PWND FASTCALL
IntGetParent(PWND Wnd)
{
@ -179,7 +178,6 @@ IntGetParent(PWND Wnd)
return NULL;
}
/*
* IntWinListChildren
*
@ -348,7 +346,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
Window->state2 |= WNDS2_INDESTROY;
Window->style &= ~WS_VISIBLE;
IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, 0);
IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
/* remove the window already at this point from the thread window list so we
don't get into trouble when destroying the thread windows while we're still
@ -399,7 +397,9 @@ static LRESULT co_UserFreeWindow(PWND Window,
if(BelongsToThreadData)
co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0);
}
DestroyTimersForWindow(ThreadData, Window);
HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
/* flush the message queue */
@ -1168,6 +1168,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
}
IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
/*
* SetParent additionally needs to make hwnd the top window
* in the z-order and send the expected WM_WINDOWPOSCHANGING and
@ -1227,13 +1228,6 @@ IntUnlinkWindow(PWND Wnd)
Wnd->spwndPrev = Wnd->spwndNext = NULL;
}
BOOL FASTCALL
IntIsWindowInDestroy(PWND Window)
{
return ((Window->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY);
}
BOOL
FASTCALL
IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
@ -1635,6 +1629,33 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
pti = PsGetCurrentThreadWin32Thread();
if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
{
if (ParentWindow)
{
if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
!(ParentWindow->ExStyle & WS_EX_NOINHERITLAYOUT) )
Cs->dwExStyle |= WS_EX_LAYOUTRTL;
}
else
{/*
Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx :
Dialog boxes and message boxes do not inherit layout, so you must
set the layout explicitly.
*/
if ( Class && Class->fnid != FNID_DIALOG)
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
if (ppi->dwLayout & LAYOUT_RTL)
{
Cs->dwExStyle |= WS_EX_LAYOUTRTL;
}
}
}
}
/* Automatically add WS_EX_WINDOWEDGE */
if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
((!(Cs->dwExStyle & WS_EX_STATICEDGE)) &&
@ -1877,17 +1898,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
PLARGE_STRING WindowName)
{
PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
HWND hWnd, hWndParent, hWndOwner;
HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
DWORD dwStyle;
PWINSTATION_OBJECT WinSta;
PCLS Class = NULL;
SIZE Size;
POINT MaxPos;
CBT_CREATEWNDW CbtCreate;
CBT_CREATEWNDW * pCbtCreate;
LRESULT Result;
USER_REFERENCE_ENTRY ParentRef, Ref;
PTHREADINFO pti;
ANSI_STRING asClassName;
DWORD dwShowMode = SW_SHOW;
CREATESTRUCTW *pCsw;
DECLARE_RETURN(PWND);
/* Get the current window station and reference it */
@ -1900,6 +1923,10 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
WinSta = pti->rpdesk->rpwinstaParent;
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
pCsw = NULL;
pCbtCreate = NULL;
RtlInitAnsiString(&asClassName, NULL);
/* Get the class and reference it*/
Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
if(!Class)
@ -1956,22 +1983,57 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
RETURN(0);
}
hWnd = Window->head.h;
hWnd = UserHMGetHandle(Window);
UserRefObjectCo(Window, &Ref);
ObDereferenceObject(WinSta);
/* Call the WH_CBT hook */
dwStyle = Cs->style;
Cs->style = Window->style; /* HCBT_CREATEWND needs the real window style */
CbtCreate.lpcs = Cs;
CbtCreate.hwndInsertAfter = HWND_TOP;
//// Call the WH_CBT hook ////
if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
// Allocate the calling structures Justin Case this goes Global.
pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK);
pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK);
/* Fill the new CREATESTRUCTW */
pCsw->lpCreateParams = Cs->lpCreateParams;
pCsw->hInstance = Cs->hInstance;
pCsw->hMenu = Cs->hMenu;
pCsw->hwndParent = Cs->hwndParent;
pCsw->cx = Cs->cx;
pCsw->cy = Cs->cy;
pCsw->x = Cs->x;
pCsw->y = Cs->y;
pCsw->dwExStyle = Cs->dwExStyle;
dwStyle = Cs->style; // Save it anyway.
pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */
pCsw->lpszName = (LPCWSTR) WindowName->Buffer;
pCsw->lpszClass = (LPCWSTR) ClassName->Buffer;
if (Window->state & WNDS_ANSICREATOR)
{
DPRINT1("HCBT_CREATEWND hook failed!\n");
if (!IS_ATOM(ClassName->Buffer))
{
RtlUnicodeStringToAnsiString(&asClassName, ClassName, TRUE);
pCsw->lpszClass = (LPCWSTR) asClassName.Buffer;
}
}
pCbtCreate->lpcs = pCsw;
pCbtCreate->hwndInsertAfter = HWND_TOP;
Result = co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) pCbtCreate);
if (Result != 0)
{
DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result);
RETURN( (PWND) NULL);
}
// Write back changes.
Cs->cx = pCsw->cx;
Cs->cy = pCsw->cy;
Cs->x = pCsw->x;
Cs->y = pCsw->y;
hwndInsertAfter = pCbtCreate->hwndInsertAfter;
Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/
@ -2014,7 +2076,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
}
/* Send the NCCREATE message */
Result = co_IntSendMessage(Window->head.h, WM_NCCREATE, 0, (LPARAM) Cs);
Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
if (!Result)
{
DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n");
@ -2032,7 +2094,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
/* Send the WM_CREATE message. */
Result = co_IntSendMessage(Window->head.h, WM_CREATE, 0, (LPARAM) Cs);
Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs);
if (Result == (LRESULT)-1)
{
DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n");
@ -2040,7 +2102,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
}
/* Send the EVENT_OBJECT_CREATE event*/
IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, 0);
IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, CHILDID_SELF, 0);
/* By setting the flag below it can be examined to determine if the window
was created successfully and a valid pwnd was passed back to caller since
@ -2102,7 +2164,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
if (Window->ExStyle & WS_EX_MDICHILD)
{
co_IntSendMessage(ParentWindow->head.h, WM_MDIREFRESHMENU, 0, 0);
co_IntSendMessage(UserHMGetHandle(ParentWindow), WM_MDIREFRESHMENU, 0, 0);
/* ShowWindow won't activate child windows */
co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}
@ -2121,6 +2183,10 @@ CLEANUP:
IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
}
if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK);
if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK);
RtlFreeAnsiString(&asClassName);
if (Window)
{
UserDerefObjectCo(Window);
@ -2280,7 +2346,7 @@ NtUserCreateWindowEx(
/* Call the internal function */
pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName);
if(!pwnd)
if(!pwnd)
{
DPRINT1("co_UserCreateWindowEx failed!\n");
}
@ -2343,7 +2409,11 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
/* If window was created successfully and it is hooked */
if ((Window->state2 & WNDS2_WMCREATEMSGPROCESSED))
{
if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE;
if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0))
{
DPRINT1("Destroy Window WH_CBT Call Hook return!\n");
return FALSE;
}
}
/* Inform the parent */

View file

@ -299,8 +299,10 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow);
if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Wnd->head.h, ShowFlag))
{
DPRINT1("WinPosMinMaximize WH_CBT Call Hook return!\n");
return SWP_NOSIZE | SWP_NOMOVE;
}
if (Wnd->style & WS_MINIMIZE)
{
if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
@ -385,7 +387,6 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
}
}
}
return(SwpFlags);
}
@ -1358,6 +1359,14 @@ co_WinPosSetWindowPos(
co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
}
if ( WinPos.flags & SWP_FRAMECHANGED || WinPos.flags & SWP_STATECHANGED ||
!(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) )
{
PWND pWnd = UserGetWindowObject(WinPos.hwnd);
if (pWnd)
IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
}
return TRUE;
}