mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 19:55:41 +00:00
[WIN32K]
- Fix possible thread reference leak when calling hook - Fix possible memory corruption if hook is unexpectedly removed - Cleanup hooks a bit - Fixes bug #1567 (explorer ghost in taskmgr) svn path=/trunk/; revision=53022
This commit is contained in:
parent
489942bf51
commit
12bdc5e8e3
1 changed files with 128 additions and 146 deletions
|
@ -5,6 +5,7 @@
|
||||||
* FILE: subsystems/win32/win32k/ntuser/hook.c
|
* FILE: subsystems/win32/win32k/ntuser/hook.c
|
||||||
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
* James Tabor (james.tabor@rectos.org)
|
* James Tabor (james.tabor@rectos.org)
|
||||||
|
* Rafal Harabien (rafalh@reactos.org)
|
||||||
*
|
*
|
||||||
* REVISION HISTORY:
|
* REVISION HISTORY:
|
||||||
* 06-06-2001 CSH Created
|
* 06-06-2001 CSH Created
|
||||||
|
@ -29,7 +30,7 @@ typedef struct _HOOKPACK
|
||||||
static
|
static
|
||||||
LRESULT
|
LRESULT
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntCallLowLevelHook( PHOOK Hook,
|
co_IntCallLowLevelHook(PHOOK Hook,
|
||||||
INT Code,
|
INT Code,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
|
@ -37,7 +38,7 @@ IntCallLowLevelHook( PHOOK Hook,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
PHOOKPACK pHP;
|
PHOOKPACK pHP;
|
||||||
INT Size;
|
INT Size = 0;
|
||||||
UINT uTimeout = 300;
|
UINT uTimeout = 300;
|
||||||
BOOL Block = FALSE;
|
BOOL Block = FALSE;
|
||||||
ULONG_PTR uResult = 0;
|
ULONG_PTR uResult = 0;
|
||||||
|
@ -53,7 +54,6 @@ IntCallLowLevelHook( PHOOK Hook,
|
||||||
pHP->pHk = Hook;
|
pHP->pHk = Hook;
|
||||||
pHP->lParam = lParam;
|
pHP->lParam = lParam;
|
||||||
pHP->pHookStructs = NULL;
|
pHP->pHookStructs = NULL;
|
||||||
Size = 0;
|
|
||||||
|
|
||||||
// This prevents stack corruption from the caller.
|
// This prevents stack corruption from the caller.
|
||||||
switch(Hook->HookId)
|
switch(Hook->HookId)
|
||||||
|
@ -170,9 +170,10 @@ co_HOOK_CallHookNext( PHOOK Hook,
|
||||||
&Hook->ModuleName);
|
&Hook->ModuleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
LRESULT
|
LRESULT
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntCallDebugHook( PHOOK Hook,
|
co_IntCallDebugHook(PHOOK Hook,
|
||||||
int Code,
|
int Code,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam,
|
LPARAM lParam,
|
||||||
|
@ -302,9 +303,10 @@ IntCallDebugHook( PHOOK Hook,
|
||||||
return lResult;
|
return lResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
LRESULT
|
LRESULT
|
||||||
FASTCALL
|
FASTCALL
|
||||||
UserCallNextHookEx( PHOOK Hook,
|
co_UserCallNextHookEx(PHOOK Hook,
|
||||||
int Code,
|
int Code,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam,
|
LPARAM lParam,
|
||||||
|
@ -697,7 +699,7 @@ UserCallNextHookEx( PHOOK Hook,
|
||||||
}
|
}
|
||||||
|
|
||||||
case WH_DEBUG:
|
case WH_DEBUG:
|
||||||
lResult = IntCallDebugHook(Hook, Code, wParam, lParam, Ansi);
|
lResult = co_IntCallDebugHook(Hook, Code, wParam, lParam, Ansi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -740,31 +742,35 @@ IntGetHookObject(HHOOK hHook)
|
||||||
return Hook;
|
return Hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the first hook in the chain */
|
|
||||||
static
|
static
|
||||||
PHOOK
|
HHOOK*
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntGetFirstHook(PLIST_ENTRY Table)
|
IntGetGlobalHookHandles(PDESKTOP pdo, int HookId)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY Elem = Table->Flink;
|
PLIST_ENTRY pLastHead, pElem;
|
||||||
|
unsigned i, cHooks;
|
||||||
|
HHOOK *pList;
|
||||||
|
PHOOK pHook;
|
||||||
|
|
||||||
if (IsListEmpty(Table)) return NULL;
|
pLastHead = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
|
||||||
|
for (pElem = pLastHead->Flink; pElem != pLastHead; pElem = pElem->Flink)
|
||||||
|
++cHooks;
|
||||||
|
|
||||||
return Elem == Table ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain);
|
pList = ExAllocatePoolWithTag(PagedPool, (cHooks + 1) * sizeof(HHOOK), TAG_HOOK);
|
||||||
|
if(!pList)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
for (pElem = pLastHead->Flink; pElem != pLastHead; pElem = pElem->Flink)
|
||||||
PHOOK
|
|
||||||
FASTCALL
|
|
||||||
IntGetNextGlobalHook(PHOOK Hook, PDESKTOP pdo)
|
|
||||||
{
|
{
|
||||||
int HookId = Hook->HookId;
|
pHook = CONTAINING_RECORD(pElem, HOOK, Chain);
|
||||||
PLIST_ENTRY Elem;
|
pList[i++] = pHook->head.h;
|
||||||
|
}
|
||||||
|
pList[i] = NULL;
|
||||||
|
|
||||||
Elem = Hook->Chain.Flink;
|
return pList;
|
||||||
if (Elem != &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)])
|
|
||||||
return CONTAINING_RECORD(Elem, HOOK, Chain);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the next hook in the chain */
|
/* find the next hook in the chain */
|
||||||
|
@ -773,22 +779,23 @@ FASTCALL
|
||||||
IntGetNextHook(PHOOK Hook)
|
IntGetNextHook(PHOOK Hook)
|
||||||
{
|
{
|
||||||
int HookId = Hook->HookId;
|
int HookId = Hook->HookId;
|
||||||
PLIST_ENTRY Elem;
|
PLIST_ENTRY pLastHead, pElem;
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
|
|
||||||
if (Hook->Thread)
|
if (Hook->Thread)
|
||||||
{
|
{
|
||||||
pti = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread);
|
pti = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread);
|
||||||
|
pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
|
||||||
Elem = Hook->Chain.Flink;
|
|
||||||
if (Elem != &pti->aphkStart[HOOKID_TO_INDEX(HookId)])
|
|
||||||
return CONTAINING_RECORD(Elem, HOOK, Chain);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pti = PsGetCurrentThreadWin32Thread();
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
return IntGetNextGlobalHook(Hook, pti->rpdesk);
|
pLastHead = &pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pElem = Hook->Chain.Flink;
|
||||||
|
if (pElem != pLastHead)
|
||||||
|
return CONTAINING_RECORD(pElem, HOOK, Chain);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,7 +817,7 @@ IntFreeHook(PHOOK Hook)
|
||||||
|
|
||||||
/* remove a hook, freeing it from the chain */
|
/* remove a hook, freeing it from the chain */
|
||||||
static
|
static
|
||||||
BOOL
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntRemoveHook(PHOOK Hook)
|
IntRemoveHook(PHOOK Hook)
|
||||||
{
|
{
|
||||||
|
@ -837,7 +844,6 @@ IntRemoveHook(PHOOK Hook)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Global
|
else // Global
|
||||||
|
@ -851,10 +857,8 @@ IntRemoveHook(PHOOK Hook)
|
||||||
IsListEmpty(&pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) )
|
IsListEmpty(&pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) )
|
||||||
{
|
{
|
||||||
pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
|
pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -875,27 +879,21 @@ HOOK_DestroyThreadHooks(PETHREAD Thread)
|
||||||
DPRINT1("Kill Thread Hooks pti 0x%x pdo 0x%x\n",pti,pdo);
|
DPRINT1("Kill Thread Hooks pti 0x%x pdo 0x%x\n",pti,pdo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ObReferenceObject(Thread);
|
|
||||||
|
|
||||||
// Local Thread cleanup.
|
// Local Thread cleanup.
|
||||||
if (pti->fsHooks)
|
if (pti->fsHooks)
|
||||||
{
|
{
|
||||||
for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++)
|
for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
|
PLIST_ENTRY pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
|
||||||
|
|
||||||
if (IsListEmpty(pLLE)) continue;
|
pElem = pLastHead->Flink;
|
||||||
|
while (pElem != pLastHead)
|
||||||
pElem = pLLE->Flink;
|
|
||||||
HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (!HookObj) break;
|
|
||||||
if (IntRemoveHook(HookObj)) break;
|
|
||||||
pElem = HookObj->Chain.Flink;
|
|
||||||
HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
|
HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
|
||||||
|
pElem = HookObj->Chain.Flink; // get next element before hook is destroyed
|
||||||
|
IntRemoveHook(HookObj);
|
||||||
}
|
}
|
||||||
while (pElem != pLLE);
|
|
||||||
}
|
}
|
||||||
pti->fsHooks = 0;
|
pti->fsHooks = 0;
|
||||||
}
|
}
|
||||||
|
@ -906,24 +904,18 @@ HOOK_DestroyThreadHooks(PETHREAD Thread)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pGLE = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
|
PLIST_ENTRY pGLE = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
|
||||||
|
|
||||||
if (IsListEmpty(pGLE)) continue;
|
|
||||||
|
|
||||||
pElem = pGLE->Flink;
|
pElem = pGLE->Flink;
|
||||||
HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
|
while (pElem != pGLE)
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (!HookObj) break;
|
HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
|
||||||
|
pElem = HookObj->Chain.Flink; // get next element before hook is destroyed
|
||||||
if (HookObj->head.pti == pti)
|
if (HookObj->head.pti == pti)
|
||||||
{
|
{
|
||||||
if (IntRemoveHook(HookObj)) break;
|
IntRemoveHook(HookObj);
|
||||||
}
|
}
|
||||||
pElem = HookObj->Chain.Flink;
|
}
|
||||||
HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
|
|
||||||
}
|
|
||||||
while (pElem != pGLE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,10 +932,11 @@ co_HOOK_CallHooks( INT HookId,
|
||||||
PHOOK Hook, SaveHook;
|
PHOOK Hook, SaveHook;
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
PCLIENTINFO ClientInfo;
|
PCLIENTINFO ClientInfo;
|
||||||
PLIST_ENTRY pLLE, pGLE;
|
PLIST_ENTRY pLastHead;
|
||||||
PDESKTOP pdo;
|
PDESKTOP pdo;
|
||||||
BOOL Local = FALSE, Global = FALSE;
|
BOOL Local = FALSE, Global = FALSE;
|
||||||
LRESULT Result = 0;
|
LRESULT Result = 0;
|
||||||
|
USER_REFERENCE_ENTRY Ref;
|
||||||
|
|
||||||
ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
|
ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
|
||||||
|
|
||||||
|
@ -992,14 +985,15 @@ co_HOOK_CallHooks( INT HookId,
|
||||||
*/
|
*/
|
||||||
if ( Local )
|
if ( Local )
|
||||||
{
|
{
|
||||||
pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
|
pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
|
||||||
Hook = IntGetFirstHook(pLLE);
|
if (IsListEmpty(pLastHead))
|
||||||
if (!Hook)
|
|
||||||
{
|
{
|
||||||
DPRINT1("No Local Hook Found!\n");
|
DPRINT1("No Local Hook Found!\n");
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
ObReferenceObject(Hook->Thread);
|
|
||||||
|
Hook = CONTAINING_RECORD(pLastHead->Flink, HOOK, Chain);
|
||||||
|
UserRefObjectCo(Hook, &Ref);
|
||||||
|
|
||||||
ClientInfo = pti->pClientInfo;
|
ClientInfo = pti->pClientInfo;
|
||||||
SaveHook = pti->sphkCurrent;
|
SaveHook = pti->sphkCurrent;
|
||||||
|
@ -1043,44 +1037,46 @@ co_HOOK_CallHooks( INT HookId,
|
||||||
}
|
}
|
||||||
pti->sphkCurrent = SaveHook;
|
pti->sphkCurrent = SaveHook;
|
||||||
Hook->phkNext = NULL;
|
Hook->phkNext = NULL;
|
||||||
ObDereferenceObject(Hook->Thread);
|
UserDerefObjectCo(Hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Global )
|
if ( Global )
|
||||||
{
|
{
|
||||||
PTHREADINFO ptiHook;
|
PTHREADINFO ptiHook;
|
||||||
|
HHOOK *pHookHandles;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
pGLE = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
|
/* Keep hooks in array because hooks can be destroyed in user world */
|
||||||
Hook = IntGetFirstHook(pGLE);
|
pHookHandles = IntGetGlobalHookHandles(pdo, HookId);
|
||||||
if (!Hook)
|
if(!pHookHandles)
|
||||||
{
|
|
||||||
DPRINT1("No Global Hook Found!\n");
|
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
|
||||||
/* Performance goes down the drain. If more hooks are associated to this
|
/* Performance goes down the drain. If more hooks are associated to this
|
||||||
* hook ID, this will have to post to each of the thread message queues
|
* hook ID, this will have to post to each of the thread message queues
|
||||||
* or make a direct call.
|
* or make a direct call.
|
||||||
*/
|
*/
|
||||||
do
|
for(i = 0; pHookHandles[i]; ++i)
|
||||||
{
|
{
|
||||||
|
Hook = (PHOOK)UserGetObject(gHandleTable, pHookHandles[i], otHook);
|
||||||
|
if(!Hook)
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid hook!\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
UserRefObjectCo(Hook, &Ref);
|
||||||
|
|
||||||
/* Hook->Thread is null, we hax around this with Hook->head.pti. */
|
/* Hook->Thread is null, we hax around this with Hook->head.pti. */
|
||||||
ptiHook = Hook->head.pti;
|
ptiHook = Hook->head.pti;
|
||||||
|
|
||||||
/* "Global hook monitors messages for all threads in the same desktop
|
if ( (pti->TIF_flags & TIF_DISABLEHOOKS) || (ptiHook->TIF_flags & TIF_INCLEANUP))
|
||||||
* as the calling thread."
|
|
||||||
*/
|
|
||||||
if ( ptiHook->TIF_flags & (TIF_INCLEANUP|TIF_DISABLEHOOKS) ||
|
|
||||||
ptiHook->rpdesk != pdo)
|
|
||||||
{
|
{
|
||||||
DPRINT("Next Hook 0x%x, 0x%x\n", ptiHook->rpdesk, pdo);
|
DPRINT("Next Hook 0x%x, 0x%x\n", ptiHook->rpdesk, pdo);
|
||||||
Hook = IntGetNextGlobalHook(Hook, pdo);
|
|
||||||
if (!Hook) break;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Lockup the thread while this links through user world.
|
|
||||||
ObReferenceObject(ptiHook->pEThread);
|
|
||||||
if (ptiHook != pti )
|
if (ptiHook != pti )
|
||||||
{ // Block | TimeOut
|
{
|
||||||
|
// Block | TimeOut
|
||||||
if ( HookId == WH_JOURNALPLAYBACK || // 1 | 0
|
if ( HookId == WH_JOURNALPLAYBACK || // 1 | 0
|
||||||
HookId == WH_JOURNALRECORD || // 1 | 0
|
HookId == WH_JOURNALRECORD || // 1 | 0
|
||||||
HookId == WH_KEYBOARD || // 1 | 200
|
HookId == WH_KEYBOARD || // 1 | 200
|
||||||
|
@ -1089,12 +1085,11 @@ co_HOOK_CallHooks( INT HookId,
|
||||||
HookId == WH_MOUSE_LL ) // 0 | 300
|
HookId == WH_MOUSE_LL ) // 0 | 300
|
||||||
{
|
{
|
||||||
DPRINT("\nGlobal Hook posting to another Thread! %d\n", HookId);
|
DPRINT("\nGlobal Hook posting to another Thread! %d\n", HookId);
|
||||||
Result = IntCallLowLevelHook(Hook, Code, wParam, lParam);
|
Result = co_IntCallLowLevelHook(Hook, Code, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* Make the direct call. */
|
{ /* Make the direct call. */
|
||||||
DPRINT("\nLocal Hook calling to Thread! %d\n",HookId );
|
|
||||||
Result = co_IntCallHookProc( HookId,
|
Result = co_IntCallHookProc( HookId,
|
||||||
Code,
|
Code,
|
||||||
wParam,
|
wParam,
|
||||||
|
@ -1103,10 +1098,9 @@ co_HOOK_CallHooks( INT HookId,
|
||||||
Hook->Ansi,
|
Hook->Ansi,
|
||||||
&Hook->ModuleName);
|
&Hook->ModuleName);
|
||||||
}
|
}
|
||||||
ObDereferenceObject(ptiHook->pEThread);
|
UserDerefObjectCo(Hook);
|
||||||
Hook = IntGetNextGlobalHook(Hook, pdo);
|
|
||||||
}
|
}
|
||||||
while ( Hook );
|
ExFreePoolWithTag(pHookHandles, TAG_HOOK);
|
||||||
DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId, Result);
|
DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId, Result);
|
||||||
}
|
}
|
||||||
Exit:
|
Exit:
|
||||||
|
@ -1118,7 +1112,7 @@ FASTCALL
|
||||||
IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc)
|
IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc)
|
||||||
{
|
{
|
||||||
PHOOK Hook;
|
PHOOK Hook;
|
||||||
PLIST_ENTRY pLLE, pLE;
|
PLIST_ENTRY pLastHead, pElement;
|
||||||
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
|
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
|
if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
|
||||||
|
@ -1129,15 +1123,13 @@ IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc)
|
||||||
|
|
||||||
if (pti->fsHooks)
|
if (pti->fsHooks)
|
||||||
{
|
{
|
||||||
pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
|
pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
|
||||||
|
|
||||||
if (IsListEmpty(pLLE)) return FALSE;
|
pElement = pLastHead->Flink;
|
||||||
|
while (pElement != pLastHead)
|
||||||
pLE = pLLE->Flink;
|
|
||||||
Hook = CONTAINING_RECORD(pLE, HOOK, Chain);
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (!Hook) break;
|
Hook = CONTAINING_RECORD(pElement, HOOK, Chain);
|
||||||
|
|
||||||
if (Hook->Proc == pfnFilterProc)
|
if (Hook->Proc == pfnFilterProc)
|
||||||
{
|
{
|
||||||
if (Hook->head.pti == pti)
|
if (Hook->head.pti == pti)
|
||||||
|
@ -1152,10 +1144,9 @@ IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pLE = Hook->Chain.Flink;
|
|
||||||
Hook = CONTAINING_RECORD(pLE, HOOK, Chain);
|
pElement = Hook->Chain.Flink;
|
||||||
}
|
}
|
||||||
while (pLE != pLLE);
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1207,7 +1198,7 @@ NtUserCallNextHookEx( int Code,
|
||||||
if (ClientInfo && NextObj)
|
if (ClientInfo && NextObj)
|
||||||
{
|
{
|
||||||
NextObj->phkNext = IntGetNextHook(NextObj);
|
NextObj->phkNext = IntGetNextHook(NextObj);
|
||||||
lResult = UserCallNextHookEx( NextObj, Code, wParam, lParam, NextObj->Ansi);
|
lResult = co_UserCallNextHookEx( NextObj, Code, wParam, lParam, NextObj->Ansi);
|
||||||
}
|
}
|
||||||
RETURN( lResult);
|
RETURN( lResult);
|
||||||
|
|
||||||
|
@ -1252,14 +1243,13 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HHOOK Handle;
|
HHOOK Handle;
|
||||||
PETHREAD Thread = NULL;
|
PETHREAD Thread = NULL;
|
||||||
PTHREADINFO ptiCurrent, pti = NULL;
|
PTHREADINFO pti, ptiHook = NULL;
|
||||||
BOOL Hit = FALSE;
|
|
||||||
DECLARE_RETURN(HHOOK);
|
DECLARE_RETURN(HHOOK);
|
||||||
|
|
||||||
DPRINT("Enter NtUserSetWindowsHookEx\n");
|
DPRINT("Enter NtUserSetWindowsHookEx\n");
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
ptiCurrent = PsGetCurrentThreadWin32Thread();
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
|
if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
|
||||||
{
|
{
|
||||||
|
@ -1294,11 +1284,11 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
pti = Thread->Tcb.Win32Thread;
|
ptiHook = Thread->Tcb.Win32Thread;
|
||||||
|
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
|
||||||
if ( pti->rpdesk != ptiCurrent->rpdesk) // gptiCurrent->rpdesk)
|
if ( ptiHook->rpdesk != pti->rpdesk) // gptiCurrent->rpdesk)
|
||||||
{
|
{
|
||||||
DPRINT1("Local hook wrong desktop HookId: %d\n",HookId);
|
DPRINT1("Local hook wrong desktop HookId: %d\n",HookId);
|
||||||
EngSetLastError(ERROR_ACCESS_DENIED);
|
EngSetLastError(ERROR_ACCESS_DENIED);
|
||||||
|
@ -1322,7 +1312,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (pti->TIF_flags & (TIF_CSRSSTHREAD|TIF_SYSTEMTHREAD)) &&
|
if ( (ptiHook->TIF_flags & (TIF_CSRSSTHREAD|TIF_SYSTEMTHREAD)) &&
|
||||||
(HookId == WH_GETMESSAGE ||
|
(HookId == WH_GETMESSAGE ||
|
||||||
HookId == WH_CALLWNDPROC ||
|
HookId == WH_CALLWNDPROC ||
|
||||||
HookId == WH_CBT ||
|
HookId == WH_CBT ||
|
||||||
|
@ -1339,7 +1329,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
|
||||||
}
|
}
|
||||||
else /* system-global hook */
|
else /* system-global hook */
|
||||||
{
|
{
|
||||||
pti = ptiCurrent; // gptiCurrent;
|
ptiHook = pti; // gptiCurrent;
|
||||||
if ( !Mod &&
|
if ( !Mod &&
|
||||||
(HookId == WH_GETMESSAGE ||
|
(HookId == WH_GETMESSAGE ||
|
||||||
HookId == WH_CALLWNDPROC ||
|
HookId == WH_CALLWNDPROC ||
|
||||||
|
@ -1379,68 +1369,60 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
|
||||||
Hook->ihmod = (INT)Mod; // Module Index from atom table, Do this for now.
|
Hook->ihmod = (INT)Mod; // Module Index from atom table, Do this for now.
|
||||||
Hook->Thread = Thread; /* Set Thread, Null is Global. */
|
Hook->Thread = Thread; /* Set Thread, Null is Global. */
|
||||||
Hook->HookId = HookId;
|
Hook->HookId = HookId;
|
||||||
Hook->rpdesk = pti->rpdesk;
|
Hook->rpdesk = ptiHook->rpdesk;
|
||||||
Hook->phkNext = NULL; /* Dont use as a chain! Use link lists for chaining. */
|
Hook->phkNext = NULL; /* Dont use as a chain! Use link lists for chaining. */
|
||||||
Hook->Proc = HookProc;
|
Hook->Proc = HookProc;
|
||||||
Hook->Ansi = Ansi;
|
Hook->Ansi = Ansi;
|
||||||
|
|
||||||
DPRINT("Set Hook Desk 0x%x DeskInfo 0x%x Handle Desk 0x%x\n",pti->rpdesk, pti->pDeskInfo,Hook->head.rpdesk);
|
DPRINT("Set Hook Desk 0x%x DeskInfo 0x%x Handle Desk 0x%x\n", ptiHook->rpdesk, ptiHook->pDeskInfo,Hook->head.rpdesk);
|
||||||
|
|
||||||
if (ThreadId) /* thread-local hook */
|
if (ThreadId) /* thread-local hook */
|
||||||
{
|
{
|
||||||
InsertHeadList(&pti->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
|
InsertHeadList(&ptiHook->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
|
||||||
pti->sphkCurrent = NULL;
|
ptiHook->sphkCurrent = NULL;
|
||||||
Hook->ptiHooked = pti;
|
Hook->ptiHooked = ptiHook;
|
||||||
pti->fsHooks |= HOOKID_TO_FLAG(HookId);
|
ptiHook->fsHooks |= HOOKID_TO_FLAG(HookId);
|
||||||
|
|
||||||
if (pti->pClientInfo)
|
if (ptiHook->pClientInfo)
|
||||||
{
|
{
|
||||||
if ( pti->ppi == ptiCurrent->ppi) /* gptiCurrent->ppi) */
|
if ( ptiHook->ppi == pti->ppi) /* gptiCurrent->ppi) */
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
pti->pClientInfo->fsHooks = pti->fsHooks;
|
ptiHook->pClientInfo->fsHooks = ptiHook->fsHooks;
|
||||||
pti->pClientInfo->phkCurrent = NULL;
|
ptiHook->pClientInfo->phkCurrent = NULL;
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
|
||||||
Hit = TRUE;
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
if (Hit)
|
|
||||||
{
|
{
|
||||||
DPRINT1("Problem writing to Local ClientInfo!\n");
|
DPRINT1("Problem writing to Local ClientInfo!\n");
|
||||||
}
|
}
|
||||||
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KeAttachProcess(&pti->ppi->peProcess->Pcb);
|
KeAttachProcess(&ptiHook->ppi->peProcess->Pcb);
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
pti->pClientInfo->fsHooks = pti->fsHooks;
|
ptiHook->pClientInfo->fsHooks = ptiHook->fsHooks;
|
||||||
pti->pClientInfo->phkCurrent = NULL;
|
ptiHook->pClientInfo->phkCurrent = NULL;
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
Hit = TRUE;
|
DPRINT1("Problem writing to Remote ClientInfo!\n");
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
if (Hit)
|
|
||||||
{
|
|
||||||
DPRINT1("Problem writing to Remote ClientInfo!\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InsertHeadList(&pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
|
InsertHeadList(&ptiHook->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
|
||||||
Hook->ptiHooked = NULL;
|
Hook->ptiHooked = NULL;
|
||||||
//gptiCurrent->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
|
//gptiCurrent->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
|
||||||
pti->rpdesk->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
|
ptiHook->rpdesk->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
|
||||||
pti->sphkCurrent = NULL;
|
ptiHook->sphkCurrent = NULL;
|
||||||
pti->pClientInfo->phkCurrent = NULL;
|
ptiHook->pClientInfo->phkCurrent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlInitUnicodeString(&Hook->ModuleName, NULL);
|
RtlInitUnicodeString(&Hook->ModuleName, NULL);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue