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

View file

@ -83,9 +83,6 @@
#define NtUserGetCursorPos(lpPoint) \ #define NtUserGetCursorPos(lpPoint) \
(BOOL)NtUserCallOneParam((DWORD_PTR)lpPoint, ONEPARAM_ROUTINE_GETCURSORPOSITION) (BOOL)NtUserCallOneParam((DWORD_PTR)lpPoint, ONEPARAM_ROUTINE_GETCURSORPOSITION)
#define NtUserIsWindowInDestroy(hWnd) \
(BOOL)NtUserCallOneParam((DWORD_PTR)hWnd, ONEPARAM_ROUTINE_ISWINDOWINDESTROY)
#define NtUserEnableProcessWindowGhosting(bEnable) \ #define NtUserEnableProcessWindowGhosting(bEnable) \
NtUserCallOneParam((DWORD_PTR)bEnable, ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING) 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] = static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
{ {
FALSE, /* VALIDATE_TYPE_FREE (not used) */ FALSE, /* VALIDATE_TYPE_FREE (not used) */
FALSE, /* VALIDATE_TYPE_WIN FALSE */ FALSE, /* VALIDATE_TYPE_WIN */
TRUE, /* VALIDATE_TYPE_MENU FALSE */ TRUE, /* VALIDATE_TYPE_MENU FALSE */
TRUE, /* VALIDATE_TYPE_CURSOR */ TRUE, /* VALIDATE_TYPE_CURSOR */
TRUE, /* VALIDATE_TYPE_MWPOS */ TRUE, /* VALIDATE_TYPE_MWPOS */
TRUE, /* VALIDATE_TYPE_HOOK FALSE */ FALSE, /* VALIDATE_TYPE_HOOK */
FALSE, /* (not used) */ FALSE, /* (not used) */
TRUE, /* VALIDATE_TYPE_CALLPROC FALSE */ FALSE, /* VALIDATE_TYPE_CALLPROC */
TRUE, /* VALIDATE_TYPE_ACCEL */ TRUE, /* VALIDATE_TYPE_ACCEL */
FALSE, /* (not used) */ FALSE, /* (not used) */
FALSE, /* (not used) */ FALSE, /* (not used) */

View file

@ -103,6 +103,7 @@ BOOL
FASTCALL FASTCALL
DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi) DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
{ {
BOOL Ret;
LARGE_STRING lsString; LARGE_STRING lsString;
if ( String ) if ( String )
@ -112,7 +113,12 @@ DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
else else
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0); 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 void
@ -1969,7 +1975,6 @@ RealDefWindowProcA(HWND hWnd,
{ {
DefWndNCPaint(hWnd, (HRGN)1, -1); DefWndNCPaint(hWnd, (HRGN)1, -1);
} }
Result = 1; Result = 1;
break; break;
} }

View file

@ -34,6 +34,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(user32); WINE_DEFAULT_DEBUG_CHANNEL(user32);
typedef struct _NOTIFYEVENT
{
DWORD event;
LONG idObject;
LONG idChild;
DWORD flags;
} NOTIFYEVENT, *PNOTIFYEVENT;
/* PRIVATE FUNCTIONS *********************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
static static
@ -99,6 +107,29 @@ IntSetWindowsHook(
return NtUserSetWindowsHookEx(hMod, &USModuleName, dwThreadId, idHook, lpfn, bAnsi); 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 *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -195,7 +226,7 @@ CallNextHookEx(
{ {
PCLIENTINFO ClientInfo; PCLIENTINFO ClientInfo;
DWORD Flags, Save; DWORD Flags, Save;
PHOOK pHook; PHOOK pHook, phkNext;
LRESULT lResult = 0; LRESULT lResult = 0;
GetConnected(); GetConnected();
@ -204,9 +235,14 @@ CallNextHookEx(
if (!ClientInfo->phkCurrent) return 0; 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; Save = ClientInfo->dwHookData;
Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK; Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK;
@ -215,7 +251,7 @@ CallNextHookEx(
if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK; if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK;
else 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; PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam;
@ -225,7 +261,7 @@ CallNextHookEx(
pCWP->lParam, pCWP->lParam,
(ULONG_PTR)&lResult, (ULONG_PTR)&lResult,
FNID_CALLWNDPROC, FNID_CALLWNDPROC,
pHook->Ansi); phkNext->Ansi);
} }
else else
{ {
@ -239,7 +275,7 @@ CallNextHookEx(
pCWPR->lParam, pCWPR->lParam,
(ULONG_PTR)&lResult, (ULONG_PTR)&lResult,
FNID_CALLWNDPROCRET, FNID_CALLWNDPROCRET,
pHook->Ansi); phkNext->Ansi);
} }
ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK); ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK);
ClientInfo->dwHookData = Save; ClientInfo->dwHookData = Save;
@ -252,23 +288,27 @@ CallNextHookEx(
/* /*
* @unimplemented * @implemented
*/ */
HHOOK HHOOK
WINAPI WINAPI
SetWindowsHookW(int idHook, HOOKPROC lpfn) 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 HHOOK
WINAPI WINAPI
SetWindowsHookA(int idHook, HOOKPROC lpfn) 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 HHOOK
WINAPI WINAPI
@ -392,7 +432,7 @@ SetWindowsHookExA(
/* /*
* @unimplemented * @implemented
*/ */
HHOOK HHOOK
WINAPI WINAPI
@ -417,14 +457,15 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL; PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
WPARAM wParam = 0; WPARAM wParam = 0;
LPARAM lParam = 0; LPARAM lParam = 0;
PKBDLLHOOKSTRUCT KeyboardLlData; PKBDLLHOOKSTRUCT pKeyboardLlData;
PMSLLHOOKSTRUCT MouseLlData; PMSLLHOOKSTRUCT pMouseLlData;
PMSG Msg; PMSG pMsg;
PMOUSEHOOKSTRUCT MHook; PMOUSEHOOKSTRUCT pMHook;
PCWPSTRUCT CWP; PCWPSTRUCT pCWP;
PCWPRETSTRUCT CWPR; PCWPRETSTRUCT pCWPR;
PRECTL prl; PRECTL prl;
LPCBTACTIVATESTRUCT pcbtas; LPCBTACTIVATESTRUCT pcbtas;
BOOL Hit = FALSE;
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments; Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
@ -464,8 +505,8 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
} }
break; break;
case HCBT_CLICKSKIPPED: case HCBT_CLICKSKIPPED:
MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam); pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
lParam = (LPARAM) MHook; lParam = (LPARAM) pMHook;
break; break;
case HCBT_MOVESIZE: case HCBT_MOVESIZE:
prl = (PRECTL)((PCHAR) Common + Common->lParam); prl = (PRECTL)((PCHAR) Common + Common->lParam);
@ -475,7 +516,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
pcbtas = (LPCBTACTIVATESTRUCT)((PCHAR) Common + Common->lParam); pcbtas = (LPCBTACTIVATESTRUCT)((PCHAR) Common + Common->lParam);
lParam = (LPARAM) pcbtas; lParam = (LPARAM) pcbtas;
break; break;
case HCBT_KEYSKIPPED: case HCBT_KEYSKIPPED: /* The rest SEH support */
case HCBT_MINMAX: case HCBT_MINMAX:
case HCBT_SETFOCUS: case HCBT_SETFOCUS:
case HCBT_SYSCOMMAND: case HCBT_SYSCOMMAND:
@ -490,7 +531,17 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
} }
if (Common->Proc) if (Common->Proc)
{
_SEH2_TRY
{
Result = Common->Proc(Common->Code, wParam, lParam); Result = Common->Proc(Common->Code, wParam, lParam);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
}
else else
{ {
ERR("Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc); ERR("Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc);
@ -504,41 +555,67 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
break; break;
} }
case WH_KEYBOARD_LL: case WH_KEYBOARD_LL:
KeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); pKeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) KeyboardLlData); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pKeyboardLlData);
break; break;
case WH_MOUSE_LL: case WH_MOUSE_LL:
MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); pMouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMouseLlData);
break; break;
case WH_MOUSE: case WH_MOUSE: /* SEH support */
MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam); pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MHook); _SEH2_TRY
{
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMHook);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
break; break;
case WH_CALLWNDPROC: case WH_CALLWNDPROC:
CWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam); pCWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWP); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
break; break;
case WH_CALLWNDPROCRET: case WH_CALLWNDPROCRET:
CWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam); pCWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam);
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWPR); Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
break; break;
case WH_MSGFILTER: case WH_MSGFILTER: /* All SEH support */
case WH_SYSMSGFILTER: case WH_SYSMSGFILTER:
case WH_GETMESSAGE: case WH_GETMESSAGE:
Msg = (PMSG)((PCHAR) Common + Common->lParam); pMsg = (PMSG)((PCHAR) Common + Common->lParam);
// FIXME("UHOOK Memory: %x: %x\n",Common, Msg); _SEH2_TRY
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) Msg); {
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMsg);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
break; break;
case WH_FOREGROUNDIDLE: case WH_FOREGROUNDIDLE: /* <-- SEH support */
case WH_KEYBOARD: case WH_KEYBOARD:
case WH_SHELL: case WH_SHELL:
_SEH2_TRY
{
Result = Common->Proc(Common->Code, Common->wParam, Common->lParam); Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
}
_SEH2_END;
break; break;
default: default:
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED); 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); return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
} }

View file

@ -138,6 +138,7 @@ EnableWindow(HWND hWnd,
if (Update) if (Update)
{ {
IntNotifyWinEvent(EVENT_OBJECT_STATECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
SendMessageW(hWnd, WM_ENABLE, (LPARAM)bEnable, 0); SendMessageW(hWnd, WM_ENABLE, (LPARAM)bEnable, 0);
} }
// Return nonzero if it was disabled, or zero if it wasn't: // 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; top_popup_hmenu = hmenu;
} }
IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
/* Display the window */ /* Display the window */
SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0, 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) if (MenuInfo.Flags & MF_POPUP)
{ {
IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
DestroyWindow(MenuInfo.Wnd); DestroyWindow(MenuInfo.Wnd);
MenuInfo.Wnd = NULL; MenuInfo.Wnd = NULL;
@ -3519,6 +3522,10 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
MenuSetRosMenuInfo(&MenuInfo); MenuSetRosMenuInfo(&MenuInfo);
} }
IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
hWnd,
MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
CHILDID_SELF, 0);
return TRUE; return TRUE;
} }
/*********************************************************************** /***********************************************************************
@ -3528,6 +3535,7 @@ static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup)
{ {
TRACE("hwnd=%p\n", hWnd); TRACE("hwnd=%p\n", hWnd);
IntNotifyWinEvent( EVENT_SYSTEM_MENUEND, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 ); SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 );
ShowCaret(0); ShowCaret(0);
top_popup = 0; top_popup = 0;

View file

@ -2064,13 +2064,18 @@ SendMessageW(HWND Wnd,
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST)) 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 /* NOTE: We can directly send messages to the window procedure
if *all* the following conditions are met: if *all* the following conditions are met:
* Window belongs to calling thread * Window belongs to calling thread
* The calling thread is not being hooked * 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); 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 (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 /* NOTE: We can directly send messages to the window procedure
if *all* the following conditions are met: if *all* the following conditions are met:
* Window belongs to calling thread * Window belongs to calling thread
* The calling thread is not being hooked * 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); return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, TRUE);

View file

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

View file

@ -1,17 +1,10 @@
#pragma once #pragma once
#define HOOK_THREAD_REFERENCED (0x1) #define HOOK_THREAD_REFERENCED (0x1)
#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK) #define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK)
#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1)) #define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
#define ISITHOOKED(HookId) (((PTHREADINFO)PsGetCurrentThreadWin32Thread())->fsHooks & HOOKID_TO_FLAG(HookId)) #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 typedef struct tagEVENTHOOK
{ {
THROBJHEAD head; THROBJHEAD head;
@ -32,11 +25,22 @@ typedef struct tagEVENTTABLE
UINT Counts; UINT Counts;
} EVENTTABLE, *PEVENTTABLE; } 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_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, UINT_PTR, LONG_PTR); LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, UINT_PTR, LONG_PTR);
VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread); VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread);
VOID FASTCALL EVENT_DestroyThreadEvents(PETHREAD Thread);
PHOOK FASTCALL IntGetHookObject(HHOOK); PHOOK FASTCALL IntGetHookObject(HHOOK);
PHOOK FASTCALL IntGetNextHook(PHOOK Hook); PHOOK FASTCALL IntGetNextHook(PHOOK Hook);
LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi); LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi);
BOOL FASTCALL IntUnhookWindowsHook(int,HOOKPROC);
/* EOF */ /* EOF */

View file

@ -87,9 +87,6 @@ typedef struct _USER_MESSAGE_QUEUE
/* Caret information for this queue */ /* Caret information for this queue */
PTHRDCARETINFO CaretInfo; PTHRDCARETINFO CaretInfo;
/* Window hooks */
PHOOKTABLE Hooks;
/* queue state tracking */ /* queue state tracking */
WORD WakeMask; WORD WakeMask;
WORD QueueBits; WORD QueueBits;
@ -212,9 +209,6 @@ BOOL APIENTRY IntInitMessagePumpHook();
BOOL APIENTRY IntUninitMessagePumpHook(); BOOL APIENTRY IntUninitMessagePumpHook();
#define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
PHOOKTABLE FASTCALL MsqGetHooks(PUSER_MESSAGE_QUEUE Queue);
VOID FASTCALL MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks);
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam); LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam);
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID); LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */ 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; LIST_ENTRY PtiLink;
POINT ptLast; POINT ptLast;
LIST_ENTRY aphkStart[NB_HOOKS];
CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL. CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL.
/* ReactOS */ /* ReactOS */
LIST_ENTRY WindowListHead; LIST_ENTRY WindowListHead;
@ -150,6 +151,8 @@ typedef struct _W32PROCESS
LIST_ENTRY GDIBrushAttrFreeList; LIST_ENTRY GDIBrushAttrFreeList;
} W32PROCESS, *PW32PROCESS; } W32PROCESS, *PW32PROCESS;
#define CLIBS 32
typedef struct _PROCESSINFO typedef struct _PROCESSINFO
{ {
W32PROCESS; W32PROCESS;
@ -158,11 +161,15 @@ typedef struct _PROCESSINFO
struct _DESKTOP* rpdeskStartup; struct _DESKTOP* rpdeskStartup;
PCLS pclsPrivateList; PCLS pclsPrivateList;
PCLS pclsPublicList; PCLS pclsPublicList;
DWORD dwhmodLibLoadedMask;
HANDLE ahmodLibLoaded[CLIBS];
struct _WINSTATION_OBJECT *prpwinsta;
HWINSTA hwinsta;
ACCESS_MASK amwinsta;
DWORD dwHotkey;
HMONITOR hMonitor; HMONITOR hMonitor;
LUID luidSession;
USERSTARTUPINFO usi; USERSTARTUPINFO usi;
ULONG Flags;
DWORD dwLayout; DWORD dwLayout;
DWORD dwRegisteredClasses; DWORD dwRegisteredClasses;
/* ReactOS */ /* ReactOS */

View file

@ -104,7 +104,7 @@ IntShowOwnedPopups( PWND owner, BOOL fShow );
LRESULT FASTCALL LRESULT FASTCALL
IntDefWindowProc( PWND Window, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi); 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); PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRING);
WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL); WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL);

View file

@ -175,6 +175,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
{ {
struct _EPROCESS *Process; struct _EPROCESS *Process;
PTHREADINFO Win32Thread; PTHREADINFO Win32Thread;
int i;
DECLARE_RETURN(NTSTATUS); DECLARE_RETURN(NTSTATUS);
DPRINT("Enter Win32kThreadCallback\n"); DPRINT("Enter Win32kThreadCallback\n");
@ -214,6 +215,10 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
InitializeListHead(&Win32Thread->WindowListHead); InitializeListHead(&Win32Thread->WindowListHead);
InitializeListHead(&Win32Thread->W32CallbackListHead); InitializeListHead(&Win32Thread->W32CallbackListHead);
InitializeListHead(&Win32Thread->PtiLink); 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 * 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; Win32Thread->TIF_flags |= TIF_INCLEANUP;
DceFreeThreadDCE(Win32Thread); DceFreeThreadDCE(Win32Thread);
HOOK_DestroyThreadHooks(Thread); HOOK_DestroyThreadHooks(Thread);
EVENT_DestroyThreadEvents(Thread);
/* Cleanup timers */ /* Cleanup timers */
DestroyTimersForThread(Win32Thread); DestroyTimersForThread(Win32Thread);
KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);

View file

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

View file

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

View file

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

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* PURPOSE: Window event handlers * 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) * PROGRAMER: James Tabor (james.tabor@rectos.org)
*/ */
@ -103,12 +103,15 @@ IntCallLowLevelEvent( PEVENTHOOK pEH,
LONG idChild) LONG idChild)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG_PTR uResult; PEVENTPACK pEP;
EVENTPACK EP; ULONG_PTR uResult = 0;
EP.pEH = pEH; pEP = ExAllocatePoolWithTag(NonPagedPool, sizeof(EVENTPACK), TAG_HOOK);
EP.idObject = idObject; if (!pEP) return 0;
EP.idChild = idChild;
pEP->pEH = pEH;
pEP->idObject = idObject;
pEP->idChild = idChild;
/* FIXME should get timeout from /* FIXME should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
@ -116,16 +119,18 @@ IntCallLowLevelEvent( PEVENTHOOK pEH,
hwnd, hwnd,
event, event,
0, 0,
(LPARAM)&EP, (LPARAM)pEP,
5000, 5000,
TRUE, TRUE,
MSQ_ISEVENT, MSQ_ISEVENT,
&uResult); &uResult);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(pEP, TAG_HOOK);
}
return NT_SUCCESS(Status) ? uResult : 0; return NT_SUCCESS(Status) ? uResult : 0;
} }
static static
BOOL BOOL
FASTCALL FASTCALL
@ -145,8 +150,43 @@ IntRemoveEvent(PEVENTHOOK pEH)
return FALSE; 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 *****************************************************************/ /* FUNCTIONS *****************************************************************/
//
// Dispatch MsgQueue Event Call processor!
//
LRESULT LRESULT
FASTCALL FASTCALL
co_EVENT_CallEvents( DWORD event, co_EVENT_CallEvents( DWORD event,
@ -165,9 +205,11 @@ co_EVENT_CallEvents( DWORD event,
hwnd, hwnd,
pEP->idObject, pEP->idObject,
pEP->idChild, pEP->idChild,
(DWORD_PTR)(NtCurrentTeb()->ClientId).UniqueThread, PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
(DWORD)EngGetTickCount(), (DWORD)EngGetTickCount(),
pEH->Proc); pEH->Proc);
ExFreePoolWithTag(pEP, TAG_HOOK);
return Result; return Result;
} }
@ -177,46 +219,56 @@ IntNotifyWinEvent(
DWORD Event, DWORD Event,
PWND pWnd, PWND pWnd,
LONG idObject, LONG idObject,
LONG idChild) LONG idChild,
DWORD flags)
{ {
PEVENTHOOK pEH; PEVENTHOOK pEH;
PLIST_ENTRY pLE; PLIST_ENTRY pLE;
PTHREADINFO pti, ptiCurrent;
DPRINT("IntNotifyWinEvent GlobalEvents = 0x%x pWnd 0x%x\n",GlobalEvents, pWnd); 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 (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; pLE = GlobalEvents->Events.Flink;
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
do do
{ {
if (!pEH) break;
UserReferenceObject(pEH); UserReferenceObject(pEH);
// Must be inside the event window. // Must be inside the event window.
if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event)) if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event))
{ {
if (pEH->head.pti->pEThread != PsGetCurrentThread()) // if all process || all thread || other thread same process
{ // 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->idThread) || if ( (!pEH->idProcess || pEH->idProcess == PtrToUint(pti->pEThread->Cid.UniqueProcess)) &&
(NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess)) (!(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, IntCallLowLevelEvent( pEH,
Event, Event,
UserHMGetHandle(pWnd), UserHMGetHandle(pWnd),
idObject, idObject,
idChild); idChild);
} }
}// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process) else
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? DPRINT1("Local Event 0x%x, idObject %d\n", Event, idObject);
co_IntCallEventProc( UserHMGetHandle(pEH), co_IntCallEventProc( UserHMGetHandle(pEH),
Event, Event,
UserHMGetHandle(pWnd), UserHMGetHandle(pWnd),
@ -227,6 +279,7 @@ IntNotifyWinEvent(
pEH->Proc); pEH->Proc);
} }
} }
}
UserDereferenceObject(pEH); UserDereferenceObject(pEH);
pLE = pEH->Chain.Flink; pLE = pEH->Chain.Flink;
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
@ -255,7 +308,7 @@ NtUserNotifyWinEvent(
if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(Event)) if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(Event))
{ {
UserRefObjectCo(Window, &Ref); UserRefObjectCo(Window, &Ref);
IntNotifyWinEvent( Event, Window, idObject, idChild); IntNotifyWinEvent( Event, Window, idObject, idChild, WEF_SETBYWNDPTI);
UserDerefObjectCo(Window); UserDerefObjectCo(Window);
} }
UserLeave(); UserLeave();
@ -322,7 +375,7 @@ NtUserSetWinEventHook(
goto SetEventExit; goto SetEventExit;
} }
} }
// Creator, pti is set here.
pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK)); pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK));
if (pEH) if (pEH)
{ {
@ -330,16 +383,18 @@ NtUserSetWinEventHook(
GlobalEvents->Counts++; GlobalEvents->Counts++;
UserHMGetHandle(pEH) = Handle; UserHMGetHandle(pEH) = Handle;
if (Thread)
pEH->head.pti = Thread->Tcb.Win32Thread;
else
pEH->head.pti = GetW32ThreadInfo();
pEH->eventMin = eventMin; pEH->eventMin = eventMin;
pEH->eventMax = eventMax; pEH->eventMax = eventMax;
pEH->idProcess = idProcess; pEH->idProcess = idProcess; // These are cmp'ed
pEH->idThread = idThread; pEH->idThread = idThread; // "
pEH->Flags = dwflags; 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) if (NULL != hmodWinEventProc)
{ {
pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc); pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc);

View file

@ -165,6 +165,7 @@ co_IntSendKillFocusMessages(HWND hWndPrev, HWND hWnd)
{ {
if (hWndPrev) if (hWndPrev)
{ {
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(hWndPrev, WM_KILLFOCUS, (WPARAM)hWnd, 0); co_IntPostOrSendMessage(hWndPrev, WM_KILLFOCUS, (WPARAM)hWnd, 0);
} }
} }
@ -174,6 +175,8 @@ co_IntSendSetFocusMessages(HWND hWndPrev, HWND hWnd)
{ {
if (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); co_IntPostOrSendMessage(hWnd, WM_SETFOCUS, (WPARAM)hWndPrev, 0);
} }
} }
@ -356,8 +359,10 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL)
cbt.fMouse = FALSE; cbt.fMouse = FALSE;
cbt.hWndActive = hWndPrev; cbt.hWndActive = hWndPrev;
if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt)) if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
{
DPRINT1("SetActiveWindow WH_CBT Call Hook return!\n");
return 0; return 0;
}
ThreadQueue->ActiveWindow = hWnd; ThreadQueue->ActiveWindow = hWnd;
co_IntSendDeactivateMessages(hWndPrev, hWnd); co_IntSendDeactivateMessages(hWndPrev, hWnd);
@ -393,8 +398,10 @@ co_IntSetFocusWindow(PWND Window OPTIONAL)
} }
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev)) 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; return 0;
}
ThreadQueue->FocusWindow = Window->head.h; ThreadQueue->FocusWindow = Window->head.h;
co_IntSendKillFocusMessages(hWndPrev, Window->head.h); co_IntSendKillFocusMessages(hWndPrev, Window->head.h);
@ -403,9 +410,11 @@ co_IntSetFocusWindow(PWND Window OPTIONAL)
else else
{ {
ThreadQueue->FocusWindow = 0; ThreadQueue->FocusWindow = 0;
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev)) if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
{
DPRINT1("SetFocusWindow 2 WH_CBT Call Hook return!\n");
return 0; return 0;
}
co_IntSendKillFocusMessages(hWndPrev, 0); co_IntSendKillFocusMessages(hWndPrev, 0);
} }
@ -533,7 +542,7 @@ NtUserSetCapture(HWND hWnd)
{ {
PTHREADINFO pti; PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue; PUSER_MESSAGE_QUEUE ThreadQueue;
PWND Window; PWND Window, pWnd;
HWND hWndPrev; HWND hWndPrev;
DECLARE_RETURN(HWND); DECLARE_RETURN(HWND);
@ -553,6 +562,13 @@ NtUserSetCapture(HWND hWnd)
hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, 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 */ /* also remove other windows if not capturing anymore */
if (hWnd == NULL) if (hWnd == NULL)
{ {
@ -560,6 +576,9 @@ NtUserSetCapture(HWND hWnd)
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, 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); co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
ThreadQueue->CaptureWindow = 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; LARGE_INTEGER TickCount;
LONG Time; LONG Time;
LRESULT retval; LRESULT retval = 0;
PMSGMEMORY MsgMemoryEntry; PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize; INT lParamBufferSize;
PTHREADINFO pti;
LPARAM lParamPacked; LPARAM lParamPacked;
PWND Window = NULL; PWND Window = NULL;
@ -380,17 +381,20 @@ IntDispatchMessage(PMSG pMsg)
if (!Window) return 0; if (!Window) return 0;
} }
pti = PsGetCurrentThreadWin32Thread();
if (((pMsg->message == WM_SYSTIMER) || if (((pMsg->message == WM_SYSTIMER) ||
(pMsg->message == WM_TIMER)) && (pMsg->message == WM_TIMER)) &&
(pMsg->lParam) ) (pMsg->lParam) )
{ {
if (pMsg->message == WM_TIMER) if (pMsg->message == WM_TIMER)
{ {
if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),pMsg->lParam)) ObReferenceObject(pti->pEThread);
if (ValidateTimerCallback(pti,pMsg->lParam))
{ {
KeQueryTickCount(&TickCount); KeQueryTickCount(&TickCount);
Time = MsqCalculateMessageTime(&TickCount); Time = MsqCalculateMessageTime(&TickCount);
return co_IntCallWindowProc((WNDPROC)pMsg->lParam, retval = co_IntCallWindowProc((WNDPROC)pMsg->lParam,
TRUE, TRUE,
pMsg->hwnd, pMsg->hwnd,
WM_TIMER, WM_TIMER,
@ -398,7 +402,8 @@ IntDispatchMessage(PMSG pMsg)
(LPARAM)Time, (LPARAM)Time,
sizeof(LPARAM)); sizeof(LPARAM));
} }
return 0; ObDereferenceObject(pti->pEThread);
return retval;
} }
else else
{ {
@ -431,7 +436,7 @@ IntDispatchMessage(PMSG pMsg)
DPRINT1("Failed to pack message parameters\n"); DPRINT1("Failed to pack message parameters\n");
return 0; return 0;
} }
ObReferenceObject(pti->pEThread);
retval = co_IntCallWindowProc( Window->lpfnWndProc, retval = co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode, !Window->Unicode,
pMsg->hwnd, pMsg->hwnd,
@ -452,6 +457,7 @@ IntDispatchMessage(PMSG pMsg)
co_UserGetUpdateRgn( Window, hrgn, TRUE ); co_UserGetUpdateRgn( Window, hrgn, TRUE );
REGION_FreeRgnByHandle( hrgn ); REGION_FreeRgnByHandle( hrgn );
} }
ObDereferenceObject(pti->pEThread);
return retval; return retval;
} }
@ -784,6 +790,7 @@ BOOL ProcessMouseMessage(MSG* Msg, BOOLEAN RemoveMessages)
HCBT_CLICKSKIPPED, HCBT_CLICKSKIPPED,
Msg->message, Msg->message,
(LPARAM)&MHook); (LPARAM)&MHook);
DPRINT1("MouseMessage WH_CBT Call Hook return!\n");
return FALSE; return FALSE;
} }
@ -812,6 +819,7 @@ BOOL ProcessKeyboardMessage(MSG* Msg, BOOLEAN RemoveMessages)
HCBT_KEYSKIPPED, HCBT_KEYSKIPPED,
LOWORD(Msg->wParam), LOWORD(Msg->wParam),
Msg->lParam ); Msg->lParam );
DPRINT1("KeyboardMessage WH_CBT Call Hook return!\n");
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@ -1322,13 +1330,13 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
UINT uTimeout, UINT uTimeout,
ULONG_PTR *uResult ) ULONG_PTR *uResult )
{ {
ULONG_PTR Result;
NTSTATUS Status; NTSTATUS Status;
PWND Window = NULL; PWND Window = NULL;
PMSGMEMORY MsgMemoryEntry; PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize; INT lParamBufferSize;
LPARAM lParamPacked; LPARAM lParamPacked;
PTHREADINFO Win32Thread; PTHREADINFO Win32Thread;
ULONG_PTR Result = 0;
DECLARE_RETURN(LRESULT); DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
@ -1369,6 +1377,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
RETURN( FALSE); RETURN( FALSE);
} }
ObReferenceObject(Win32Thread->pEThread);
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc, Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode, !Window->Unicode,
hWnd, hWnd,
@ -1381,6 +1390,8 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
*uResult = Result; *uResult = Result;
} }
ObDereferenceObject(Win32Thread->pEThread);
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
@ -1575,7 +1586,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
/* If this is not a callback and it can be sent now, then send it. */ /* If this is not a callback and it can be sent now, then send it. */
if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
{ {
ObReferenceObject(Win32Thread->pEThread);
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc, Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode, !Window->Unicode,
hWnd, hWnd,
@ -1587,6 +1598,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
{ {
*uResult = Result; *uResult = Result;
} }
ObDereferenceObject(Win32Thread->pEThread);
} }
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
@ -2553,12 +2565,13 @@ NtUserMessageCall(
2000, 2000,
&RetVal); &RetVal);
} }
Ret = RetVal;
} }
else if (parm.flags & BSF_POSTMESSAGE) else if (parm.flags & BSF_POSTMESSAGE)
{ {
Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam); 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); Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
} }
@ -2584,21 +2597,31 @@ NtUserMessageCall(
case FNID_CALLWNDPROC: case FNID_CALLWNDPROC:
case FNID_CALLWNDPROCRET: case FNID_CALLWNDPROCRET:
{ {
PCLIENTINFO ClientInfo = GetWin32ClientInfo(); PTHREADINFO pti;
PHOOK NextObj, Hook = ClientInfo->phkCurrent; 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;
}
NextObj = IntGetNextHook(Hook);
ClientInfo->phkCurrent = NextObj; ClientInfo->phkCurrent = NextObj;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ClientInfo = NULL;
}
_SEH2_END;
if (!ClientInfo || !NextObj) break;
NextObj->phkNext = IntGetNextHook(NextObj);
if ( Hook->HookId == WH_CALLWNDPROC) if ( Hook->HookId == WH_CALLWNDPROC)
{ {
@ -2634,8 +2657,6 @@ NtUserMessageCall(
Hook->Ansi, Hook->Ansi,
&Hook->ModuleName); &Hook->ModuleName);
} }
UserDereferenceObject(Hook);
lResult = (LRESULT) NextObj;
} }
break; break;
} }

View file

@ -948,22 +948,21 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
&Message->ListEntry); &Message->ListEntry);
if (Message->HookMessage == MSQ_ISHOOK) if (Message->HookMessage == MSQ_ISHOOK)
{ { // Direct Hook Call processor
Result = co_HOOK_CallHooks(Message->Msg.message, Result = co_CallHook( Message->Msg.message, // HookId
(INT)(INT_PTR)Message->Msg.hwnd, (INT)(INT_PTR)Message->Msg.hwnd, // Code
Message->Msg.wParam, Message->Msg.wParam,
Message->Msg.lParam); Message->Msg.lParam);
} }
else if (Message->HookMessage == MSQ_ISEVENT) else if (Message->HookMessage == MSQ_ISEVENT)
{ { // Direct Event Call processor
Result = co_EVENT_CallEvents( Message->Msg.message, Result = co_EVENT_CallEvents( Message->Msg.message,
Message->Msg.hwnd, Message->Msg.hwnd,
Message->Msg.wParam, Message->Msg.wParam,
Message->Msg.lParam); Message->Msg.lParam);
} }
else else
{ { /* Call the window procedure. */
/* Call the window procedure. */
Result = co_IntSendMessage( Message->Msg.hwnd, Result = co_IntSendMessage( Message->Msg.hwnd,
Message->Msg.message, Message->Msg.message,
Message->Msg.wParam, Message->Msg.wParam,
@ -1004,7 +1003,9 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); 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) if (Message->CompletionCallback != NULL)
{ {
co_IntCallSentMessageCallback(Message->CompletionCallback, co_IntCallSentMessageCallback(Message->CompletionCallback,
@ -1133,10 +1134,10 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_SENT_MESSAGE Message; PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent; KEVENT CompletionEvent;
NTSTATUS WaitStatus; NTSTATUS WaitStatus;
LRESULT Result;
PUSER_MESSAGE_QUEUE ThreadQueue; PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout; LARGE_INTEGER Timeout;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
LRESULT Result = 0; //// Result could be trashed. ////
if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG))) 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 */ /* FIXME - increase reference counter of sender's message queue here */
Result = 0;
Message->Msg.hwnd = Wnd; Message->Msg.hwnd = Wnd;
Message->Msg.message = Msg; Message->Msg.message = Msg;
Message->Msg.wParam = wParam; Message->Msg.wParam = wParam;
@ -1164,6 +1164,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
Message->SenderQueue = ThreadQueue; Message->SenderQueue = ThreadQueue;
IntReferenceMessageQueue(ThreadQueue); IntReferenceMessageQueue(ThreadQueue);
Message->CompletionCallback = NULL; Message->CompletionCallback = NULL;
Message->CompletionCallbackContext = 0;
Message->HookMessage = HookMessage; Message->HookMessage = HookMessage;
Message->HasPackedLParam = FALSE; Message->HasPackedLParam = FALSE;
@ -1632,18 +1633,6 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
IntDereferenceMessageQueue(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 LPARAM FASTCALL
MsqSetMessageExtraInfo(LPARAM lParam) MsqSetMessageExtraInfo(LPARAM lParam)
{ {

View file

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

View file

@ -228,21 +228,6 @@ NtUserCallOneParam(
RETURN (ret); 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: case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
{ {
BOOL Enable; BOOL Enable;
@ -473,6 +458,8 @@ NtUserCallTwoParam(
case TWOPARAM_ROUTINE_SETCURSORPOS: case TWOPARAM_ROUTINE_SETCURSORPOS:
RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE)); 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", DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
Routine, Param1, Param2); Routine, Param1, Param2);
@ -713,6 +700,21 @@ NtUserCallHwndParam(
UserLeave(); UserLeave();
return 0; 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; UNIMPLEMENTED;

View file

@ -163,7 +163,6 @@ IntIsWindow(HWND hWnd)
} }
PWND FASTCALL PWND FASTCALL
IntGetParent(PWND Wnd) IntGetParent(PWND Wnd)
{ {
@ -179,7 +178,6 @@ IntGetParent(PWND Wnd)
return NULL; return NULL;
} }
/* /*
* IntWinListChildren * IntWinListChildren
* *
@ -348,7 +346,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
Window->state2 |= WNDS2_INDESTROY; Window->state2 |= WNDS2_INDESTROY;
Window->style &= ~WS_VISIBLE; 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 /* 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 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) if(BelongsToThreadData)
co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0); co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0);
} }
DestroyTimersForWindow(ThreadData, Window); DestroyTimersForWindow(ThreadData, Window);
HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too! HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
/* flush the message queue */ /* 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 * SetParent additionally needs to make hwnd the top window
* in the z-order and send the expected WM_WINDOWPOSCHANGING and * in the z-order and send the expected WM_WINDOWPOSCHANGING and
@ -1227,13 +1228,6 @@ IntUnlinkWindow(PWND Wnd)
Wnd->spwndPrev = Wnd->spwndNext = NULL; Wnd->spwndPrev = Wnd->spwndNext = NULL;
} }
BOOL FASTCALL
IntIsWindowInDestroy(PWND Window)
{
return ((Window->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY);
}
BOOL BOOL
FASTCALL FASTCALL
IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl) IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
@ -1635,6 +1629,33 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
pti = PsGetCurrentThreadWin32Thread(); 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 */ /* Automatically add WS_EX_WINDOWEDGE */
if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) || if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
((!(Cs->dwExStyle & WS_EX_STATICEDGE)) && ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) &&
@ -1877,17 +1898,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
PLARGE_STRING WindowName) PLARGE_STRING WindowName)
{ {
PWND Window = NULL, ParentWindow = NULL, OwnerWindow; PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
HWND hWnd, hWndParent, hWndOwner; HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
DWORD dwStyle; DWORD dwStyle;
PWINSTATION_OBJECT WinSta; PWINSTATION_OBJECT WinSta;
PCLS Class = NULL; PCLS Class = NULL;
SIZE Size; SIZE Size;
POINT MaxPos; POINT MaxPos;
CBT_CREATEWNDW CbtCreate; CBT_CREATEWNDW * pCbtCreate;
LRESULT Result; LRESULT Result;
USER_REFERENCE_ENTRY ParentRef, Ref; USER_REFERENCE_ENTRY ParentRef, Ref;
PTHREADINFO pti; PTHREADINFO pti;
ANSI_STRING asClassName;
DWORD dwShowMode = SW_SHOW; DWORD dwShowMode = SW_SHOW;
CREATESTRUCTW *pCsw;
DECLARE_RETURN(PWND); DECLARE_RETURN(PWND);
/* Get the current window station and reference it */ /* Get the current window station and reference it */
@ -1900,6 +1923,10 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
WinSta = pti->rpdesk->rpwinstaParent; WinSta = pti->rpdesk->rpwinstaParent;
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0); ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
pCsw = NULL;
pCbtCreate = NULL;
RtlInitAnsiString(&asClassName, NULL);
/* Get the class and reference it*/ /* Get the class and reference it*/
Class = IntGetAndReferenceClass(ClassName, Cs->hInstance); Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
if(!Class) if(!Class)
@ -1956,22 +1983,57 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
RETURN(0); RETURN(0);
} }
hWnd = Window->head.h; hWnd = UserHMGetHandle(Window);
UserRefObjectCo(Window, &Ref); UserRefObjectCo(Window, &Ref);
ObDereferenceObject(WinSta); ObDereferenceObject(WinSta);
/* Call the WH_CBT hook */ //// 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;
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); 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*/ Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/
@ -2014,7 +2076,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
} }
/* Send the NCCREATE message */ /* 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) if (!Result)
{ {
DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n"); DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n");
@ -2032,7 +2094,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
/* Send the WM_CREATE message. */ /* 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) if (Result == (LRESULT)-1)
{ {
DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n"); DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n");
@ -2040,7 +2102,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
} }
/* Send the EVENT_OBJECT_CREATE event*/ /* 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 /* 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 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) 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 */ /* ShowWindow won't activate child windows */
co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); 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); IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
} }
if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK);
if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK);
RtlFreeAnsiString(&asClassName);
if (Window) if (Window)
{ {
UserDerefObjectCo(Window); UserDerefObjectCo(Window);
@ -2343,7 +2409,11 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
/* If window was created successfully and it is hooked */ /* If window was created successfully and it is hooked */
if ((Window->state2 & WNDS2_WMCREATEMSGPROCESSED)) 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 */ /* Inform the parent */

View file

@ -299,8 +299,10 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow); WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow);
if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Wnd->head.h, ShowFlag)) 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; return SWP_NOSIZE | SWP_NOMOVE;
}
if (Wnd->style & WS_MINIMIZE) if (Wnd->style & WS_MINIMIZE)
{ {
if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0)) if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
@ -385,7 +387,6 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
} }
} }
} }
return(SwpFlags); return(SwpFlags);
} }
@ -1358,6 +1359,14 @@ co_WinPosSetWindowPos(
co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos); 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; return TRUE;
} }