Commit in reactos/ntoskrnl/ke on MAIN
apc.c+37-91.59 -> 1.60
Fix insertion of APCs where the target thread is attached to another process

reactos/ntoskrnl/ke
apc.c 1.59 -> 1.60
diff -u -r1.59 -r1.60
--- apc.c	21 Aug 2004 21:19:06 -0000	1.59
+++ apc.c	18 Sep 2004 19:43:00 -0000	1.60
@@ -321,6 +321,10 @@
 	  "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 @@
 
    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 @@
    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 @@
    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 @@
     
     /* 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 @@
   {
     /* 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 
CVSspam 0.2.8