Fix insertion of APCs where the target thread is attached to another process

svn path=/trunk/; revision=10899
This commit is contained in:
Gé van Geldorp 2004-09-18 19:43:00 +00:00
parent 767ca4f4ac
commit ac1e392aec

View file

@ -321,6 +321,10 @@ KeInsertQueueApc (PKAPC Apc,
"SystemArgument2 %x)\n",Apc,SystemArgument1,
SystemArgument2);
/* We don't support queuing APCs to the attached environment (yet),
see KiSwapApcEnvironment() */
assert(OriginalApcEnvironment == Apc->ApcStateIndex);
Apc->SystemArgument1 = SystemArgument1;
Apc->SystemArgument2 = SystemArgument2;
@ -348,15 +352,15 @@ KeInsertQueueApc (PKAPC Apc,
if (Apc->ApcMode == KernelMode)
{
InsertTailList(&TargetThread->ApcState.ApcListHead[0],
InsertTailList(&TargetThread->ApcStatePointer[(int) Apc->ApcStateIndex]->ApcListHead[0],
&Apc->ApcListEntry);
TargetThread->ApcState.KernelApcPending++;
TargetThread->ApcStatePointer[(int) Apc->ApcStateIndex]->KernelApcPending++;
}
else
{
InsertTailList(&TargetThread->ApcState.ApcListHead[1],
InsertTailList(&TargetThread->ApcStatePointer[(int) Apc->ApcStateIndex]->ApcListHead[1],
&Apc->ApcListEntry);
TargetThread->ApcState.UserApcPending++;
TargetThread->ApcStatePointer[(int) Apc->ApcStateIndex]->UserApcPending++;
}
Apc->Inserted = TRUE;
@ -445,20 +449,20 @@ KeRemoveQueueApc (PKAPC Apc)
KiAcquireSpinLock(&PiApcLock);
if (Apc->Inserted == FALSE)
{
KiReleaseSpinLock(&PiApcLock);
KeLowerIrql(oldIrql);
return(FALSE);
KiReleaseSpinLock(&PiApcLock);
KeLowerIrql(oldIrql);
return FALSE;
}
TargetThread = Apc->Thread;
RemoveEntryList(&Apc->ApcListEntry);
if (Apc->ApcMode == KernelMode)
{
TargetThread->ApcState.KernelApcPending--;
TargetThread->ApcStatePointer[(int) Apc->ApcStateIndex]->KernelApcPending--;
}
else
{
TargetThread->ApcState.UserApcPending--;
TargetThread->ApcStatePointer[(int) Apc->ApcStateIndex]->UserApcPending--;
}
Apc->Inserted = FALSE;
@ -607,6 +611,20 @@ PiInitApcManagement(VOID)
KeInitializeSpinLock(&PiApcLock);
}
static VOID FASTCALL
RepairList(PLIST_ENTRY Original, PLIST_ENTRY Copy, int Mode)
{
if (IsListEmpty(&Original[Mode]))
{
InitializeListHead(&Copy[Mode]);
}
else
{
Copy[Mode].Flink->Blink = &Copy[Mode];
Copy[Mode].Blink->Flink = &Copy[Mode];
}
}
VOID FASTCALL
KiSwapApcEnvironment(
@ -638,6 +656,11 @@ KiSwapApcEnvironment(
/* restore backup of original environment */
Thread->ApcState = Thread->SavedApcState;
/* repair lists */
RepairList(Thread->SavedApcState.ApcListHead, Thread->ApcState.ApcListHead,
KernelMode);
RepairList(Thread->SavedApcState.ApcListHead, Thread->ApcState.ApcListHead,
UserMode);
/* update environment pointers */
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
@ -650,6 +673,11 @@ KiSwapApcEnvironment(
{
/* backup original environment */
Thread->SavedApcState = Thread->ApcState;
/* repair lists */
RepairList(Thread->ApcState.ApcListHead, Thread->SavedApcState.ApcListHead,
KernelMode);
RepairList(Thread->ApcState.ApcListHead, Thread->SavedApcState.ApcListHead,
UserMode);
/*
FIXME: Is it possible to target an apc to an attached environment even if the