- 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:
Rafal Harabien 2011-08-01 22:30:21 +00:00
parent 489942bf51
commit 12bdc5e8e3

View file

@ -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,15 +30,15 @@ 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)
{ {
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,13 +170,14 @@ 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,
BOOL Ansi) BOOL Ansi)
{ {
LRESULT lResult = 0; LRESULT lResult = 0;
ULONG Size; ULONG Size;
@ -302,13 +303,14 @@ 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,
BOOL Ansi) BOOL Ansi)
{ {
LRESULT lResult = 0; LRESULT lResult = 0;
BOOL BadChk = FALSE; BOOL BadChk = FALSE;
@ -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 pHook = CONTAINING_RECORD(pElem, HOOK, Chain);
IntGetNextGlobalHook(PHOOK Hook, PDESKTOP pdo) pList[i++] = pHook->head.h;
{ }
int HookId = Hook->HookId; pList[i] = NULL;
PLIST_ENTRY Elem;
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
@ -1088,13 +1084,12 @@ co_HOOK_CallHooks( INT HookId,
HookId == WH_KEYBOARD_LL || // 0 | 300 HookId == WH_KEYBOARD_LL || // 0 | 300
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,11 +1098,10 @@ 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:
return Result; return Result;
@ -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);