* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Window hooks
- * FILE: subsystems/win32/win32k/ntuser/hook.c
+ * FILE: win32ss/user/ntuser/hook.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* James Tabor (james.tabor@rectos.org)
* Rafal Harabien (rafalh@reactos.org)
PLIST_ENTRY ListEntry;
PPROCESSINFO ppiCsr;
- ERR("IntHookModuleUnloaded: iHookID=%d\n", iHookID);
+ TRACE("IntHookModuleUnloaded: iHookID=%d\n", iHookID);
ppiCsr = PsGetProcessWin32Process(gpepCSRSS);
/* FIXME: Do some more security checks here */
- /* FIXME: The first check is a reactos specific hack for system threads */
+ /* FIXME: HACK: The first check is a reactos specific hack for system threads */
if(!PsIsSystemProcess(ptiCurrent->ppi->peProcess) &&
ptiCurrent->ppi != ppiCsr)
{
return FALSE;
}
- ERR("UserUnregisterUserApiHook. Server PID: %p\n", PsGetProcessId(pti->ppi->peProcess));
+ TRACE("UserUnregisterUserApiHook. Server PID: %p\n", PsGetProcessId(pti->ppi->peProcess));
/* Unregister the api hook */
gpsi->dwSRVIFlags &= ~SRVINFO_APIHOOK;
// Dispatch MsgQueue Hook Call processor!
//
LRESULT
-FASTCALL
+APIENTRY
co_CallHook( INT HookId,
INT Code,
WPARAM wParam,
LPARAM lParam)
{
- LRESULT Result;
+ LRESULT Result = 0;
PHOOK phk;
PHOOKPACK pHP = (PHOOKPACK)lParam;
{
case WH_JOURNALPLAYBACK:
case WH_JOURNALRECORD:
- case WH_KEYBOARD:
case WH_KEYBOARD_LL:
case WH_MOUSE_LL:
case WH_MOUSE:
lParam = (LPARAM)pHP->pHookStructs;
+ case WH_KEYBOARD:
break;
}
+ if (!UserObjectInDestroy(UserHMGetHandle(phk))) //// Fix CORE-10549.
+ {
/* The odds are high for this to be a Global call. */
Result = co_IntCallHookProc( HookId,
Code,
phk->offPfn,
phk->Ansi,
&phk->ModuleName);
-
+ }
/* The odds so high, no one is waiting for the results. */
if (pHP->pHookStructs) ExFreePoolWithTag(pHP->pHookStructs, TAG_HOOK);
ExFreePoolWithTag(pHP, TAG_HOOK);
static
LRESULT
-FASTCALL
+APIENTRY
co_HOOK_CallHookNext( PHOOK Hook,
INT Code,
WPARAM wParam,
static
LRESULT
-FASTCALL
+APIENTRY
co_UserCallNextHookEx(PHOOK Hook,
int Code,
WPARAM wParam,
if (!IS_ATOM(pcbtcww->lpcs->lpszClass))
{
- ProbeForRead( pcbtcww->lpcs->lpszClass,
+ _Analysis_assume_(pcbtcww->lpcs->lpszClass != NULL);
+ ProbeForRead(pcbtcww->lpcs->lpszClass,
sizeof(CHAR),
1);
}
if (!IS_ATOM(pcbtcww->lpcs->lpszClass))
{
- ProbeForRead( pcbtcww->lpcs->lpszClass,
+ _Analysis_assume_(pcbtcww->lpcs->lpszClass != NULL);
+ ProbeForRead(pcbtcww->lpcs->lpszClass,
sizeof(WCHAR),
1);
}
++cHooks;
pList = ExAllocatePoolWithTag(PagedPool, (cHooks + 1) * sizeof(HHOOK), TAG_HOOK);
- if(!pList)
+ if (!pList)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
-}
+ }
for (pElem = pLastHead->Flink; pElem != pLastHead; pElem = pElem->Flink)
-{
+ {
pHook = CONTAINING_RECORD(pElem, HOOK, Chain);
+ NT_ASSERT(i < cHooks);
pList[i++] = pHook->head.h;
}
pList[i] = NULL;
IntRemoveHook(PVOID Object)
{
INT HookId;
- PTHREADINFO pti;
+ PTHREADINFO ptiHook, pti;
PDESKTOP pdo;
PHOOK Hook = Object;
+ NT_ASSERT(UserIsEnteredExclusive());
+
HookId = Hook->HookId;
+ pti = PsGetCurrentThreadWin32Thread();
if (Hook->ptiHooked) // Local
{
- pti = Hook->ptiHooked;
+ ptiHook = Hook->ptiHooked;
- IntFreeHook( Hook);
+ IntFreeHook(Hook);
- if ( IsListEmpty(&pti->aphkStart[HOOKID_TO_INDEX(HookId)]) )
- {
- pti->fsHooks &= ~HOOKID_TO_FLAG(HookId);
- _SEH2_TRY
- {
- pti->pClientInfo->fsHooks = pti->fsHooks;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Do nothing */
- (void)0;
- }
- _SEH2_END;
+ if (IsListEmpty(&ptiHook->aphkStart[HOOKID_TO_INDEX(HookId)]))
+ {
+ BOOL bOtherProcess;
+ KAPC_STATE ApcState;
+
+ ptiHook->fsHooks &= ~HOOKID_TO_FLAG(HookId);
+ bOtherProcess = (ptiHook->ppi != pti->ppi);
+
+ if (bOtherProcess)
+ KeStackAttachProcess(&ptiHook->ppi->peProcess->Pcb, &ApcState);
+
+ _SEH2_TRY
+ {
+ ptiHook->pClientInfo->fsHooks = ptiHook->fsHooks;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Do nothing */
+ (void)0;
+ }
+ _SEH2_END;
+
+ if (bOtherProcess)
+ KeUnstackDetachProcess(&ApcState);
}
}
else // Global
{
- IntFreeHook( Hook);
+ IntFreeHook(Hook);
- pdo = IntGetActiveDesktop();
+ pdo = IntGetActiveDesktop();
- if ( pdo &&
- pdo->pDeskInfo &&
- IsListEmpty(&pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) )
- {
- pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
- }
+ if (pdo &&
+ pdo->pDeskInfo &&
+ IsListEmpty(&pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]))
+ {
+ pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
+ }
}
return TRUE;
Win32k Kernel Space Hook Caller.
*/
LRESULT
-FASTCALL
+APIENTRY
co_HOOK_CallHooks( INT HookId,
INT Code,
WPARAM wParam,
}
Hook = CONTAINING_RECORD(pLastHead->Flink, HOOK, Chain);
+ ObReferenceObject(pti->pEThread);
+ IntReferenceThreadInfo(pti);
UserRefObjectCo(Hook, &Ref);
ClientInfo = pti->pClientInfo;
wParam,
lParam,
Hook->Proc,
- Hook->ihmod,
+ Hook->ihmod,
Hook->offPfn,
Hook->Ansi,
&Hook->ModuleName);
pti->sphkCurrent = SaveHook;
Hook->phkNext = NULL;
UserDerefObjectCo(Hook);
+ IntDereferenceThreadInfo(pti);
+ ObDereferenceObject(pti->pEThread);
}
if ( Global )
ERR("Invalid hook!\n");
continue;
}
- UserRefObjectCo(Hook, &Ref);
/* Hook->Thread is null, we hax around this with Hook->head.pti. */
ptiHook = Hook->head.pti;
TRACE("Next Hook %p, %p\n", ptiHook->rpdesk, pdo);
continue;
}
+ UserRefObjectCo(Hook, &Ref);
if (ptiHook != pti )
{
TRACE("\nGlobal Hook posting to another Thread! %d\n",HookId );
Result = co_IntCallLowLevelHook(Hook, Code, wParam, lParam);
}
+ else if (ptiHook->ppi == pti->ppi)
+ {
+ TRACE("\nGlobal Hook calling to another Thread! %d\n",HookId );
+ ObReferenceObject(ptiHook->pEThread);
+ IntReferenceThreadInfo(ptiHook);
+ Result = co_IntCallHookProc( HookId,
+ Code,
+ wParam,
+ lParam,
+ Hook->Proc,
+ Hook->ihmod,
+ Hook->offPfn,
+ Hook->Ansi,
+ &Hook->ModuleName);
+ IntDereferenceThreadInfo(ptiHook);
+ ObDereferenceObject(ptiHook->pEThread);
+ }
}
else
{ /* Make the direct call. */
- TRACE("Local Hook calling to Thread! %d\n",HookId );
+ TRACE("Global going Local Hook calling to Thread! %d\n",HookId );
+ ObReferenceObject(pti->pEThread);
+ IntReferenceThreadInfo(pti);
Result = co_IntCallHookProc( HookId,
Code,
wParam,
lParam,
Hook->Proc,
- Hook->ihmod,
+ Hook->ihmod,
Hook->offPfn,
Hook->Ansi,
&Hook->ModuleName);
+ IntDereferenceThreadInfo(pti);
+ ObDereferenceObject(pti->pEThread);
}
UserDerefObjectCo(Hook);
}
HookId == WH_MOUSE_LL ||
HookId == WH_SYSMSGFILTER)
{
- ERR("Local hook installing Global HookId: %d\n",HookId);
+ TRACE("Local hook installing Global HookId: %d\n",HookId);
/* these can only be global */
EngSetLastError(ERROR_GLOBAL_ONLY_HOOK);
RETURN( NULL);
}
- if ( !(ptiHook = IntTID2PTI( (HANDLE)ThreadId )))
+ if ( !(ptiHook = IntTID2PTI( UlongToHandle(ThreadId) )))
{
ERR("Invalid thread id 0x%x\n", ThreadId);
EngSetLastError(ERROR_INVALID_PARAMETER);
}
Status = IntValidateWindowStationHandle( PsGetCurrentProcess()->Win32WindowStation,
- KernelMode,
+ UserMode,
0,
- &WinStaObj);
+ &WinStaObj,
+ 0);
if (!NT_SUCCESS(Status))
{
RETURN( NULL);
}
- Hook->ihmod = (INT)Mod; // Module Index from atom table, Do this for now.
+ Hook->ihmod = (INT_PTR)Mod; // Module Index from atom table, Do this for now.
Hook->HookId = HookId;
Hook->rpdesk = ptiHook->rpdesk;
Hook->phkNext = NULL; /* Dont use as a chain! Use link lists for chaining. */
}
else
{
- KeAttachProcess(&ptiHook->ppi->peProcess->Pcb);
+ KAPC_STATE ApcState;
+
+ KeStackAttachProcess(&ptiHook->ppi->peProcess->Pcb, &ApcState);
_SEH2_TRY
{
ptiHook->pClientInfo->fsHooks = ptiHook->fsHooks;
ERR("Problem writing to Remote ClientInfo!\n");
}
_SEH2_END;
- KeDetachProcess();
+ KeUnstackDetachProcess(&ApcState);
}
}
}