Acquire always the apc lock if we are modifying the apc queue.
Modified: trunk/reactos/ntoskrnl/ke/apc.c
Modified: trunk/reactos/ntoskrnl/ke/process.c

Modified: trunk/reactos/ntoskrnl/ke/apc.c
--- trunk/reactos/ntoskrnl/ke/apc.c	2005-07-26 19:15:08 UTC (rev 16753)
+++ trunk/reactos/ntoskrnl/ke/apc.c	2005-07-26 19:21:27 UTC (rev 16754)
@@ -245,7 +245,7 @@
  *     The APC will execute at APC_LEVEL for the KernelRoutine registered, and
  *     at PASSIVE_LEVEL for the NormalRoutine registered.
  *
- *     Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
+ *     Callers of this routine must have locked the dipatcher database.
  *
  *--*/
 BOOLEAN
@@ -257,9 +257,12 @@
     PLIST_ENTRY ApcListEntry;
     PKAPC QueuedApc;
 
+    KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
+
     /* Don't do anything if the APC is already inserted */
     if (Apc->Inserted) {
-
+    
+        KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
         return FALSE;
     }
 
@@ -301,6 +304,8 @@
     /* Confirm Insertion */
     Apc->Inserted = TRUE;
 
+    KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
+
     /*
      * Three possibilites here again:
      *  1) Kernel APC, The thread is Running: Request an Interrupt
@@ -318,13 +323,11 @@
 #ifdef CONFIG_SMP
             PKPRCB Prcb, CurrentPrcb;
             LONG i;
-            KIRQL oldIrql;
 #endif
 
             DPRINT ("Requesting APC Interrupt for Running Thread \n");
 
 #ifdef CONFIG_SMP
-            oldIrql = KeRaiseIrqlToDpcLevel();
             CurrentPrcb = KeGetCurrentPrcb();
             if (CurrentPrcb->CurrentThread == Thread)
             {
@@ -344,7 +347,6 @@
                }
                ASSERT (i < KeNumberProcessors);
             }
-            KeLowerIrql(oldIrql);
 #else
             HalRequestSoftwareInterrupt(APC_LEVEL);
 #endif

Modified: trunk/reactos/ntoskrnl/ke/process.c
--- trunk/reactos/ntoskrnl/ke/process.c	2005-07-26 19:15:08 UTC (rev 16753)
+++ trunk/reactos/ntoskrnl/ke/process.c	2005-07-26 19:21:27 UTC (rev 16754)
@@ -89,6 +89,7 @@
 
     /* Initialize the Thread List */
     InitializeListHead(&Process->ThreadListHead);
+    KeInitializeSpinLock(&Process->ProcessLock);
     DPRINT("The Process has now been initalized with the Kernel\n");
 }
 
@@ -138,6 +139,7 @@
 
     /* Lock Dispatcher */
     OldIrql = KeAcquireDispatcherDatabaseLock();
+    KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
 
     /* Crash system if DPC is being executed! */
     if (KeIsExecutingDpc()) {
@@ -150,6 +152,7 @@
     if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
 
         DPRINT("Process already Attached. Exitting\n");
+        KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
         KeReleaseDispatcherDatabaseLock(OldIrql);
     } else {
 
@@ -191,6 +194,7 @@
     KiSwapProcess(Process, SavedApcState->Process);
 
     /* Return to old IRQL*/
+    KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
     KeReleaseDispatcherDatabaseLock(ApcLock);
 
     DPRINT("KiAttachProcess Completed Sucesfully\n");
@@ -232,6 +236,7 @@
     UpdatePageDirs(Thread, Process);
 
     OldIrql = KeAcquireDispatcherDatabaseLock();
+    KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
 
     /* Crash system if DPC is being executed! */
     if (KeIsExecutingDpc()) {
@@ -273,6 +278,7 @@
     /* Get Current Thread and Lock */
     Thread = KeGetCurrentThread();
     OldIrql = KeAcquireDispatcherDatabaseLock();
+    KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
 
     /* Check if it's attached */
     DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
@@ -297,6 +303,7 @@
     KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
 
     /* Unlock Dispatcher */
+    KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
     KeReleaseDispatcherDatabaseLock(OldIrql);
 }
 
@@ -320,6 +327,7 @@
 
     Thread = KeGetCurrentThread();
     OldIrql = KeAcquireDispatcherDatabaseLock();
+    KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
 
     /* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
     if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
@@ -347,6 +355,7 @@
     KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
 
     /* Return to old IRQL*/
+    KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
     KeReleaseDispatcherDatabaseLock(OldIrql);
 }