* 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
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;
}
/* Confirm Insertion */
Apc->Inserted = TRUE;
+ KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
+
/*
* Three possibilites here again:
* 1) Kernel APC, The thread is Running: Request an Interrupt
#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)
{
}
ASSERT (i < KeNumberProcessors);
}
- KeLowerIrql(oldIrql);
#else
HalRequestSoftwareInterrupt(APC_LEVEL);
#endif
/* Initialize the Thread List */
InitializeListHead(&Process->ThreadListHead);
+ KeInitializeSpinLock(&Process->ProcessLock);
DPRINT("The Process has now been initalized with the Kernel\n");
}
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
+ KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
DPRINT("Process already Attached. Exitting\n");
+ KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql);
} else {
KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/
+ KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(ApcLock);
DPRINT("KiAttachProcess Completed Sucesfully\n");
UpdatePageDirs(Thread, Process);
OldIrql = KeAcquireDispatcherDatabaseLock();
+ KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
/* Get Current Thread and Lock */
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
+ KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Check if it's attached */
DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Unlock Dispatcher */
+ KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql);
}
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)) {
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Return to old IRQL*/
+ KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql);
}