reactos/ntoskrnl/ke/apc.c

991 lines
30 KiB
C
Raw Permalink Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/apc.c
* PURPOSE: Implements the Asynchronous Procedure Call mechanism
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name KiCheckForKernelApcDelivery
* @implemented NT 5.2
*
* The KiCheckForKernelApcDelivery routine is called whenever APCs have
* just been re-enabled in Kernel Mode, such as after leaving a Critical or
* Guarded Region. It delivers APCs if the environment is right.
*
* @param None.
*
* @return None.
*
* @remarks This routine allows KeLeave/EnterCritical/GuardedRegion to be used
* as macros from inside WIN32K or other Drivers, which will then only
* have to do an Import API call in the case where APCs are enabled again.
*
*--*/
VOID
NTAPI
KiCheckForKernelApcDelivery(VOID)
{
KIRQL OldIrql;
/* We should only deliver at passive */
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
{
/* Raise to APC and Deliver APCs, then lower back to Passive */
KeRaiseIrql(APC_LEVEL, &OldIrql);
KiDeliverApc(KernelMode, 0, 0);
KeLowerIrql(PASSIVE_LEVEL);
}
else
{
/*
* If we're not at passive level it means someone raised IRQL
* to APC level before the critical or guarded section was entered
* (e.g) by a fast mutex). This implies that the APCs shouldn't
* be delivered now, but after the IRQL is lowered to passive
* level again.
*/
KeGetCurrentThread()->ApcState.KernelApcPending = TRUE;
HalRequestSoftwareInterrupt(APC_LEVEL);
}
}
/*++
* @name KiInsertQueueApc
*
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
* The KiInsertQueueApc routine queues a APC for execution when the right
* scheduler environment exists.
*
* @param Apc
* Pointer to an initialized control object of type APC for which the
* caller provides the storage.
*
* @param PriorityBoost
* Priority Boost to apply to the Thread.
*
* @return None
*
* @remarks The APC will execute at APC_LEVEL for the KernelRoutine registered,
* and at PASSIVE_LEVEL for the NormalRoutine registered.
*
* Callers of this routine must have locked the dipatcher database.
*
*--*/
VOID
FASTCALL
KiInsertQueueApc(IN PKAPC Apc,
IN KPRIORITY PriorityBoost)
{
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
PKTHREAD Thread = Apc->Thread;
PKAPC_STATE ApcState;
KPROCESSOR_MODE ApcMode;
PLIST_ENTRY ListHead, NextEntry;
PKAPC QueuedApc;
PKGATE Gate;
NTSTATUS Status;
BOOLEAN RequestInterrupt = FALSE;
/*
* Check if the caller wanted this APC to use the thread's environment at
* insertion time.
*/
if (Apc->ApcStateIndex == InsertApcEnvironment)
{
/* Copy it over */
Apc->ApcStateIndex = Thread->ApcStateIndex;
}
/* Get the APC State for this Index, and the mode too */
ApcState = Thread->ApcStatePointer[(UCHAR)Apc->ApcStateIndex];
ApcMode = Apc->ApcMode;
/* The APC must be "inserted" already */
ASSERT(Apc->Inserted == TRUE);
/* Three scenarios:
* 1) Kernel APC with Normal Routine or User APC = Put it at the end of the List
* 2) User APC which is PsExitSpecialApc = Put it at the front of the List
* 3) Kernel APC without Normal Routine = Put it at the end of the No-Normal Routine Kernel APC list
*/
if (Apc->NormalRoutine)
{
/* Normal APC; is it the Thread Termination APC? */
if ((ApcMode != KernelMode) &&
(Apc->KernelRoutine == PsExitSpecialApc))
{
/* Set User APC pending to true */
Thread->ApcState.UserApcPending = TRUE;
/* Insert it at the top of the list */
InsertHeadList(&ApcState->ApcListHead[ApcMode],
&Apc->ApcListEntry);
}
else
{
/* Regular user or kernel Normal APC */
InsertTailList(&ApcState->ApcListHead[ApcMode],
&Apc->ApcListEntry);
}
}
else
{
/* Special APC, find the last one in the list */
ListHead = &ApcState->ApcListHead[ApcMode];
NextEntry = ListHead->Blink;
while (NextEntry != ListHead)
{
/* Get the APC */
QueuedApc = CONTAINING_RECORD(NextEntry, KAPC, ApcListEntry);
/* Is this a No-Normal APC? If so, break */
if (!QueuedApc->NormalRoutine) break;
/* Move to the previous APC in the Queue */
NextEntry = NextEntry->Blink;
}
/* Insert us here */
InsertHeadList(NextEntry, &Apc->ApcListEntry);
}
/* Now check if the Apc State Indexes match */
if (Thread->ApcStateIndex == Apc->ApcStateIndex)
{
/* Check that the thread matches */
if (Thread == KeGetCurrentThread())
{
/* Sanity check */
ASSERT(Thread->State == Running);
/* Check if this is kernel mode */
if (ApcMode == KernelMode)
{
/* All valid, a Kernel APC is pending now */
Thread->ApcState.KernelApcPending = TRUE;
/* Check if Special APCs are disabled */
if (!Thread->SpecialApcDisable)
{
/* They're not, so request the interrupt */
HalRequestSoftwareInterrupt(APC_LEVEL);
}
}
}
else
{
/* Acquire the dispatcher lock */
KiAcquireDispatcherLock();
/* Check if this is a kernel-mode APC */
if (ApcMode == KernelMode)
{
/* Kernel-mode APC, set us pending */
Thread->ApcState.KernelApcPending = TRUE;
/* Are we currently running? */
if (Thread->State == Running)
{
/* The thread is running, so remember to send a request */
RequestInterrupt = TRUE;
}
else if ((Thread->State == Waiting) &&
(Thread->WaitIrql == PASSIVE_LEVEL) &&
!(Thread->SpecialApcDisable) &&
(!(Apc->NormalRoutine) ||
(!(Thread->KernelApcDisable) &&
!(Thread->ApcState.KernelApcInProgress))))
{
/* We'll unwait with this status */
Status = STATUS_KERNEL_APC;
/* Wake up the thread */
KiUnwaitThread(Thread, Status, PriorityBoost);
}
else if (Thread->State == GateWait)
{
/* Lock the thread */
KiAcquireThreadLock(Thread);
/* Essentially do the same check as above */
if ((Thread->State == GateWait) &&
(Thread->WaitIrql == PASSIVE_LEVEL) &&
!(Thread->SpecialApcDisable) &&
(!(Apc->NormalRoutine) ||
(!(Thread->KernelApcDisable) &&
!(Thread->ApcState.KernelApcInProgress))))
{
/* We were in a gate wait. Handle this. */
DPRINT1("A thread was in a gate wait\n");
/* Get the gate */
Gate = Thread->GateObject;
/* Lock the gate */
KiAcquireDispatcherObject(&Gate->Header);
/* Remove it from the waiters list */
RemoveEntryList(&Thread->WaitBlock[0].WaitListEntry);
/* Unlock the gate */
KiReleaseDispatcherObject(&Gate->Header);
/* Increase the queue counter if needed */
if (Thread->Queue) Thread->Queue->CurrentCount++;
/* Put into deferred ready list with this status */
Thread->WaitStatus = STATUS_KERNEL_APC;
KiInsertDeferredReadyList(Thread);
}
/* Release the thread lock */
KiReleaseThreadLock(Thread);
}
}
else if ((Thread->State == Waiting) &&
(Thread->WaitMode == UserMode) &&
((Thread->Alertable) ||
(Thread->ApcState.UserApcPending)))
{
/* Set user-mode APC pending */
Thread->ApcState.UserApcPending = TRUE;
Status = STATUS_USER_APC;
/* Wake up the thread */
KiUnwaitThread(Thread, Status, PriorityBoost);
}
/* Release dispatcher lock */
KiReleaseDispatcherLockFromSynchLevel();
/* Check if an interrupt was requested */
KiRequestApcInterrupt(RequestInterrupt, Thread->NextProcessor);
}
}
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
}
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
/*++
* @name KiDeliverApc
* @implemented @NT4
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
*
* The KiDeliverApc routine is called from IRQL switching code if the
* thread is returning from an IRQL >= APC_LEVEL and Kernel-Mode APCs are
* pending.
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
*
* @param DeliveryMode
* Specifies the current processor mode.
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
*
* @param ExceptionFrame
* Pointer to the Exception Frame on non-i386 builds.
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
*
* @param TrapFrame
* Pointer to the Trap Frame.
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
*
* @return None.
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
*
* @remarks First, Special APCs are delivered, followed by Kernel-Mode APCs and
* User-Mode APCs. Note that the TrapFrame is only valid if the
* delivery mode is User-Mode.
* Upon entry, this routine executes at APC_LEVEL.
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
*
*--*/
VOID
NTAPI
KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PKTRAP_FRAME TrapFrame)
Thread/Process Termination/Repeaing Rewrite + Fixes --------------------------------------------------- - ps/cid.c: * Moved CID Lookup functions here - ps/security.c: * Moved all security related functions here. Makes other files neater and security functions easier to locate. - ps/thread.c: * Moved most of the Thread Scheduling/Dispatching code that belongs in the Kernel to /ke and renamed functions from Ps to Ki. * Implemented PsIsSystemThread. * Removed Reaper Thread Init (now obsolete). * Renamed PiDeleteThread to PspDeleteThread. * Moved Thread State functions from tinfo.c to here. - ps/process.c: * Removed Query/Set Process functions and moved to ps/query.c * Renamed PiDeletePRocess to PspDeleteProcess * Removed obsoleted Process Termination functions, moved persistent one to kill.c - ps/create.c: * Moved the security APIs to security.c * Correctly implemented PsCreateSystemThread to actually create system threads. - ps/suspend.c * Rewrote Nt Executive functions to use Kernel functions. * Moved Ps* Routines into ke/kthread.c and fixed them. The implementation was wrong in some aspects, especially the issue of the APC looping around the KeWaitXxx call and the fact that the routines excluded/ignored the FreezeCount. - ps/debug.c * Fixed completely broken implementation of Get/SetThreadContext. The old version crashed when called and did not work at all. Suspend Regression test now works. * Moved Context<->TrapFrame functions to ke/i386/ * Combined Set/GetThreadContext APCs into a single one, and used special context structure. - ps/query.c: * Moved Thread/Process Query/Set Routines here. - ps/tinfo.c: * Removed. - ps/kill.c * Removed complicated Process Termination semantics and useless Attach/Detach in favor for a much more lightweight function which performs the same tasks as before and actually works. TaskManager can now terminate foreign processes. * Rewrote Thread Reaping to use the HyperCritical Work Queue instead of manually controlled thread. This results in much less code as well as an increase in speed and less micro management. The reaper is PspReapRoutine. Closing CMD.EXE now works properly without requiring masks that were added as hacks to allow it. * Renamed PiTerminateProcessThreads to PspTerminateProcessThreads. Fixed it to work with new termination code. * Added PspDeleteProcess to handle Process Object deletion. Kills the CID Handle here as done by Hartmut. * Added PspDeletethread here. * Renamed and rewrote PsTerminateCurrentThread to PspExitThread. Used NT Implementation out- lined in Windows Internals, Chapter 13. Uses less locks, a more concise order of actions, actually parses the Termination Ports, handles Dbgk notification. Timers are now rundown, and Mutex rundown is in a dedicated Kernel function. Final termination handled by KeTerminate Thread as documented. * Renamed PsTerminateOtherThread to PspTerminateThreadByPointer and modified implementation to be compatible with the changes above. * Renamed and regrouped Process Termination into PspExitProcess. Also implemented as described above, and moved each subsystem specific termination helper into its own subsytem. * Improved NtTerminateProcess and added more debugging messages. * Improved NtTerminateThread and added check against System Thread and made it compatible with new implementation. * Corrected PsTerminateSystemThread now that we support System Threads. * Corrected NtRegisterThreadTerminatePort to use same structure name as on windows for the port, and added tag to pool allocation (documented in pooltag.txt) include/internal/*.h: * Defined Scheduler Functions and misc new functions or renamed functions. ke/apc.c: * Fixed critical bug where APCs were not delivered at all if the thread wastion and cancels any timers that are associated to a thread, as well as their APCs and DPCs. REGRESSIONS FOUND: NONE BUGS/REGRESSIOSN FIXED: * Thread/Get Set Context now works. * Suspend Regression test now works. * Task manager can now kill foreign processes, even hung ones (like it should). * ExitProcess/closing cmd.exe with the 'x' button now works correctly without hacks. KNOWN ISSUES: I left a bit of a mess in the headers and some stuff still needs to be moved into the right places. I just wanted to have this first part ready first, so that it won't get too big. svn path=/trunk/; revision=14174
2005-03-18 05:53:04 +00:00
{
PKTHREAD Thread = KeGetCurrentThread();
PKPROCESS Process = Thread->ApcState.Process;
PKTRAP_FRAME OldTrapFrame;
PLIST_ENTRY ApcListEntry;
PKAPC Apc;
KLOCK_QUEUE_HANDLE ApcLock;
PKKERNEL_ROUTINE KernelRoutine;
PVOID NormalContext;
PKNORMAL_ROUTINE NormalRoutine;
PVOID SystemArgument1;
PVOID SystemArgument2;
ASSERT_IRQL_EQUAL(APC_LEVEL);
/* Save the old trap frame and set current one */
OldTrapFrame = Thread->TrapFrame;
Thread->TrapFrame = TrapFrame;
/* Clear Kernel APC Pending */
Thread->ApcState.KernelApcPending = FALSE;
/* Check if Special APCs are disabled */
if (Thread->SpecialApcDisable) goto Quickie;
/* Do the Kernel APCs first */
while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
{
/* Lock the APC Queue */
KiAcquireApcLockRaiseToDpc(Thread, &ApcLock);
/* Check if the list became empty now */
if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
{
/* It is, release the lock and break out */
KiReleaseApcLock(&ApcLock);
break;
}
/* Kernel APC is not pending anymore */
Thread->ApcState.KernelApcPending = FALSE;
/* Get the next Entry */
ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
/* Save Parameters so that it's safe to free the Object in the Kernel Routine*/
NormalRoutine = Apc->NormalRoutine;
KernelRoutine = Apc->KernelRoutine;
NormalContext = Apc->NormalContext;
SystemArgument1 = Apc->SystemArgument1;
SystemArgument2 = Apc->SystemArgument2;
/* Special APC */
if (!NormalRoutine)
{
/* Remove the APC from the list */
RemoveEntryList(ApcListEntry);
Apc->Inserted = FALSE;
/* Release the APC lock */
KiReleaseApcLock(&ApcLock);
/* Call the Special APC */
KernelRoutine(Apc,
&NormalRoutine,
&NormalContext,
&SystemArgument1,
&SystemArgument2);
/* Make sure it returned correctly */
if (KeGetCurrentIrql() != ApcLock.OldIrql)
{
KeBugCheckEx(IRQL_UNEXPECTED_VALUE,
(KeGetCurrentIrql() << 16) |
(ApcLock.OldIrql << 8),
(ULONG_PTR)KernelRoutine,
(ULONG_PTR)Apc,
(ULONG_PTR)NormalRoutine);
}
}
else
{
/* Normal Kernel APC, make sure it's safe to deliver */
if ((Thread->ApcState.KernelApcInProgress) ||
(Thread->KernelApcDisable))
{
/* Release lock and return */
KiReleaseApcLock(&ApcLock);
goto Quickie;
}
/* Dequeue the APC */
RemoveEntryList(ApcListEntry);
Apc->Inserted = FALSE;
/* Go back to APC_LEVEL */
KiReleaseApcLock(&ApcLock);
/* Call the Kernel APC */
KernelRoutine(Apc,
&NormalRoutine,
&NormalContext,
&SystemArgument1,
&SystemArgument2);
/* Make sure it returned correctly */
if (KeGetCurrentIrql() != ApcLock.OldIrql)
{
KeBugCheckEx(IRQL_UNEXPECTED_VALUE,
(KeGetCurrentIrql() << 16) |
(ApcLock.OldIrql << 8),
(ULONG_PTR)KernelRoutine,
(ULONG_PTR)Apc,
(ULONG_PTR)NormalRoutine);
}
/* Check if there still is a Normal Routine */
if (NormalRoutine)
{
/* At Passive Level, an APC can be prempted by a Special APC */
Thread->ApcState.KernelApcInProgress = TRUE;
KeLowerIrql(PASSIVE_LEVEL);
/* Call and Raise IRQL back to APC_LEVEL */
NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
KeRaiseIrql(APC_LEVEL, &ApcLock.OldIrql);
}
/* Set Kernel APC in progress to false and loop again */
Thread->ApcState.KernelApcInProgress = FALSE;
}
}
/* Now we do the User APCs */
if ((DeliveryMode == UserMode) &&
!(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
(Thread->ApcState.UserApcPending))
{
/* Lock the APC Queue */
KiAcquireApcLockRaiseToDpc(Thread, &ApcLock);
/* It's not pending anymore */
Thread->ApcState.UserApcPending = FALSE;
/* Check if the list became empty now */
if (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))
{
/* It is, release the lock and break out */
KiReleaseApcLock(&ApcLock);
goto Quickie;
}
/* Get the actual APC object */
ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink;
Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
/* Save Parameters so that it's safe to free the Object in the Kernel Routine*/
NormalRoutine = Apc->NormalRoutine;
KernelRoutine = Apc->KernelRoutine;
NormalContext = Apc->NormalContext;
SystemArgument1 = Apc->SystemArgument1;
SystemArgument2 = Apc->SystemArgument2;
/* Remove the APC from Queue, and release the lock */
RemoveEntryList(ApcListEntry);
Apc->Inserted = FALSE;
KiReleaseApcLock(&ApcLock);
/* Call the kernel routine */
KernelRoutine(Apc,
&NormalRoutine,
&NormalContext,
&SystemArgument1,
&SystemArgument2);
/* Check if there's no normal routine */
if (!NormalRoutine)
{
/* Check if more User APCs are Pending */
KeTestAlertThread(UserMode);
}
else
{
/* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */
KiInitializeUserApc(ExceptionFrame,
TrapFrame,
NormalRoutine,
NormalContext,
SystemArgument1,
SystemArgument2);
}
}
Quickie:
/* Make sure we're still in the same process */
if (Process != Thread->ApcState.Process)
{
/* Erm, we got attached or something! BAD! */
KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
(ULONG_PTR)Process,
(ULONG_PTR)Thread->ApcState.Process,
Thread->ApcStateIndex,
KeGetCurrentPrcb()->DpcRoutineActive);
}
/* Restore the trap frame */
Thread->TrapFrame = OldTrapFrame;
}
FORCEINLINE
VOID
RepairList(IN PLIST_ENTRY Original,
IN PLIST_ENTRY Copy,
IN KPROCESSOR_MODE Mode)
{
/* Check if the list for this mode is empty */
if (IsListEmpty(&Original[Mode]))
{
/* It is, all we need to do is initialize it */
InitializeListHead(&Copy[Mode]);
}
else
{
/* Copy the lists */
Copy[Mode].Flink = Original[Mode].Flink;
Copy[Mode].Blink = Original[Mode].Blink;
Original[Mode].Flink->Blink = &Copy[Mode];
Original[Mode].Blink->Flink = &Copy[Mode];
}
}
VOID
NTAPI
KiMoveApcState(PKAPC_STATE OldState,
PKAPC_STATE NewState)
{
/* Restore backup of Original Environment */
RtlCopyMemory(NewState, OldState, KAPC_STATE_ACTUAL_LENGTH);
/* Repair Lists */
RepairList(OldState->ApcListHead, NewState->ApcListHead, KernelMode);
RepairList(OldState->ApcListHead, NewState->ApcListHead, UserMode);
}
/* PUBLIC FUNCTIONS **********************************************************/
/*++
* @name KeEnterCriticalRegion
* @implemented NT4
*
* The KeEnterCriticalRegion routine temporarily disables the delivery of
* normal kernel APCs; special kernel-mode APCs are still delivered.
*
* @param None.
*
* @return None.
*
* @remarks Highest-level drivers can call this routine while running in the
* context of the thread that requested the current I/O operation.
* Any caller of this routine should call KeLeaveCriticalRegion as
* quickly as possible.
*
* Callers of KeEnterCriticalRegion must be running at IRQL <=
* APC_LEVEL.
*
*--*/
VOID
NTAPI
_KeEnterCriticalRegion(VOID)
{
/* Use inlined function */
KeEnterCriticalRegion();
}
/*++
* KeLeaveCriticalRegion
* @implemented NT4
*
* The KeLeaveCriticalRegion routine reenables the delivery of normal
* kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion.
*
* @param None.
*
* @return None.
*
* @remarks Highest-level drivers can call this routine while running in the
* context of the thread that requested the current I/O operation.
*
* Callers of KeLeaveCriticalRegion must be running at IRQL <=
* DISPATCH_LEVEL.
*
*--*/
VOID
NTAPI
_KeLeaveCriticalRegion(VOID)
{
/* Use inlined version */
KeLeaveCriticalRegion();
}
/*++
* KeInitializeApc
* @implemented NT4
*
* The KeInitializeApc routine initializes an APC object, and registers
* the Kernel, Rundown and Normal routines for that object.
*
* @param Apc
* Pointer to a KAPC structure that represents the APC object to
* initialize. The caller must allocate storage for the structure
* from resident memory.
*
* @param Thread
* Thread to which to deliver the APC.
*
* @param TargetEnvironment
* APC Environment to be used.
*
* @param KernelRoutine
* Points to the KernelRoutine to associate with the APC.
* This routine is executed for all APCs.
*
* @param RundownRoutine
* Points to the RundownRoutine to associate with the APC.
* This routine is executed when the Thread exits during APC execution.
*
* @param NormalRoutine
* Points to the NormalRoutine to associate with the APC.
* This routine is executed at PASSIVE_LEVEL. If this is not specifed,
* the APC becomes a Special APC and the Mode and Context parameters are
* ignored.
*
* @param Mode
* Specifies the processor mode at which to run the Normal Routine.
*
* @param Context
* Specifices the value to pass as Context parameter to the registered
* routines.
*
* @return None.
*
* @remarks The caller can queue an initialized APC with KeInsertQueueApc.
*
*--*/
VOID
NTAPI
KeInitializeApc(IN PKAPC Apc,
IN PKTHREAD Thread,
IN KAPC_ENVIRONMENT TargetEnvironment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine,
IN KPROCESSOR_MODE Mode,
IN PVOID Context)
{
/* Sanity check */
ASSERT(TargetEnvironment <= InsertApcEnvironment);
/* Set up the basic APC Structure Data */
Apc->Type = ApcObject;
Apc->Size = sizeof(KAPC);
/* Set the Environment */
if (TargetEnvironment == CurrentApcEnvironment)
{
/* Use the current one for the thread */
Apc->ApcStateIndex = Thread->ApcStateIndex;
}
else
{
/* Sanity check */
ASSERT((TargetEnvironment <= Thread->ApcStateIndex) ||
(TargetEnvironment == InsertApcEnvironment));
/* Use the one that was given */
Apc->ApcStateIndex = TargetEnvironment;
}
/* Set the Thread and Routines */
Apc->Thread = Thread;
Apc->KernelRoutine = KernelRoutine;
Apc->RundownRoutine = RundownRoutine;
Apc->NormalRoutine = NormalRoutine;
/* Check if this is a special APC */
if (NormalRoutine)
{
/* It's a normal one. Set the context and mode */
Apc->ApcMode = Mode;
Apc->NormalContext = Context;
}
else
{
/* It's a special APC, which can only be kernel mode */
Apc->ApcMode = KernelMode;
Apc->NormalContext = NULL;
}
/* The APC is not inserted */
Apc->Inserted = FALSE;
}
/*++
* @name KeInsertQueueApc
* @implemented NT4
*
* The KeInsertQueueApc routine queues a APC for execution when the right
* scheduler environment exists.
*
* @param Apc
* Pointer to an initialized control object of type APC for which the
* caller provides the storage.
*
* @param SystemArgument[1,2]
* Pointer to a set of two parameters that contain untyped data.
*
* @param PriorityBoost
* Priority Boost to apply to the Thread.
*
* @return If the APC is already inserted or APC queueing is disabled, FALSE.
* Otherwise, TRUE.
*
* @remarks 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 <= DISPATCH_LEVEL.
*
*--*/
BOOLEAN
NTAPI
KeInsertQueueApc(IN PKAPC Apc,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2,
IN KPRIORITY PriorityBoost)
{
PKTHREAD Thread = Apc->Thread;
KLOCK_QUEUE_HANDLE ApcLock;
BOOLEAN State = TRUE;
ASSERT_APC(Apc);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Get the APC lock */
KiAcquireApcLockRaiseToSynch(Thread, &ApcLock);
/* Make sure we can Queue APCs and that this one isn't already inserted */
if (!(Thread->ApcQueueable) || (Apc->Inserted))
{
/* Fail */
State = FALSE;
}
else
{
/* Set the System Arguments and set it as inserted */
Apc->SystemArgument1 = SystemArgument1;
Apc->SystemArgument2 = SystemArgument2;
Apc->Inserted = TRUE;
/* Call the Internal Function */
KiInsertQueueApc(Apc, PriorityBoost);
}
/* Release the APC lock and return success */
KiReleaseApcLockFromSynchLevel(&ApcLock);
KiExitDispatcher(ApcLock.OldIrql);
return State;
}
/*++
* @name KeFlushQueueApc
* @implemented NT4
*
* The KeFlushQueueApc routine flushes all APCs of the given processor mode
* from the specified Thread's APC queue.
*
* @param Thread
* Pointer to the thread whose APC queue will be flushed.
*
* @param PreviousMode
* Specifies which APC Queue to flush.
*
* @return A pointer to the first entry in the flushed APC queue.
*
* @remarks If the routine returns NULL, it means that no APCs were flushed.
* Callers of this routine must be running at DISPATCH_LEVEL or lower.
*
*--*/
PLIST_ENTRY
NTAPI
KeFlushQueueApc(IN PKTHREAD Thread,
IN KPROCESSOR_MODE PreviousMode)
{
PKAPC Apc;
PLIST_ENTRY FirstEntry, CurrentEntry;
KLOCK_QUEUE_HANDLE ApcLock;
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Check if this was user mode */
if (PreviousMode == UserMode)
{
/* Get the APC lock */
KiAcquireApcLockRaiseToSynch(Thread, &ApcLock);
/* Select user list and check if it's empty */
if (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))
{
/* Don't return anything */
FirstEntry = NULL;
goto FlushDone;
}
}
else
{
/* Select kernel list and check if it's empty */
if (IsListEmpty( &Thread->ApcState.ApcListHead[KernelMode]))
{
/* Don't return anything */
return NULL;
}
/* Otherwise, acquire the APC lock */
KiAcquireApcLockRaiseToSynch(Thread, &ApcLock);
}
/* Get the first entry and check if the list is empty now */
FirstEntry = Thread->ApcState.ApcListHead[PreviousMode].Flink;
if (FirstEntry == &Thread->ApcState.ApcListHead[PreviousMode])
{
/* It is, clear the returned entry */
FirstEntry = NULL;
}
else
{
/* It's not, remove the first entry */
RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]);
/* Loop all the entries */
CurrentEntry = FirstEntry;
do
{
/* Get the APC and make it un-inserted */
Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
Apc->Inserted = FALSE;
/* Get the next entry */
CurrentEntry = CurrentEntry->Flink;
} while (CurrentEntry != FirstEntry);
/* Re-initialize the list */
InitializeListHead(&Thread->ApcState.ApcListHead[PreviousMode]);
}
/* Release the lock */
FlushDone:
KiReleaseApcLock(&ApcLock);
/* Return the first entry */
return FirstEntry;
}
/*++
* @name KeRemoveQueueApc
* @implemented NT4
*
* The KeRemoveQueueApc routine removes a given APC object from the system
* APC queue.
*
* @param Apc
* Pointer to an initialized APC object that was queued by calling
* KeInsertQueueApc.
*
* @return TRUE if the APC Object is in the APC Queue. Otherwise, no operation
* is performed and FALSE is returned.
*
* @remarks If the given APC Object is currently queued, it is removed from the
* queue and any calls to the registered routines are cancelled.
*
* Callers of this routine must be running at IRQL <= DISPATCH_LEVEL.
*
*--*/
BOOLEAN
NTAPI
KeRemoveQueueApc(IN PKAPC Apc)
{
PKTHREAD Thread = Apc->Thread;
PKAPC_STATE ApcState;
BOOLEAN Inserted;
KLOCK_QUEUE_HANDLE ApcLock;
ASSERT_APC(Apc);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Get the APC lock (this raises IRQL to SYNCH_LEVEL) */
KiAcquireApcLockRaiseToSynch(Thread, &ApcLock);
/* Check if it's inserted */
Inserted = Apc->Inserted;
if (Inserted)
{
/* Set it as non-inserted and get the APC state */
Apc->Inserted = FALSE;
ApcState = Thread->ApcStatePointer[(UCHAR)Apc->ApcStateIndex];
/* Acquire the dispatcher lock and remove it from the list */
KiAcquireDispatcherLockAtSynchLevel();
if (RemoveEntryList(&Apc->ApcListEntry))
{
/* Set the correct state based on the APC Mode */
if (Apc->ApcMode == KernelMode)
{
/* No more pending kernel APCs */
ApcState->KernelApcPending = FALSE;
}
else
{
/* No more pending user APCs */
ApcState->UserApcPending = FALSE;
}
}
/* Release dispatcher lock */
KiReleaseDispatcherLockFromSynchLevel();
}
/* Release the lock and return */
KiReleaseApcLock(&ApcLock);
return Inserted;
}
/*++
* @name KeAreApcsDisabled
* @implemented NT4
*
* The KeAreApcsDisabled routine returns whether kernel APC delivery is
* disabled for the current thread.
*
* @param None.
*
* @return KeAreApcsDisabled returns TRUE if the thread is within a critical
* region or a guarded region, and FALSE otherwise.
*
* @remarks A thread running at IRQL = PASSIVE_LEVEL can use KeAreApcsDisabled
* to determine if normal kernel APCs are disabled.
*
* A thread that is inside critical region has both user APCs and
* normal kernel APCs disabled, but not special kernel APCs.
*
* A thread that is inside a guarded region has all APCs disabled,
* including special kernel APCs.
*
* Callers of this routine must be running at IRQL <= DISPATCH_LEVEL.
*
*--*/
BOOLEAN
NTAPI
KeAreApcsDisabled(VOID)
{
/* Return the Kernel APC State */
return KeGetCurrentThread()->CombinedApcDisable ? TRUE : FALSE;
}
/*++
* @name KeAreAllApcsDisabled
* @implemented NT5.1
*
* The KeAreAllApcsDisabled routine returns whether the calling thread is
* inside a guarded region or running at IRQL >= APC_LEVEL, which disables
* all APC delivery.
*
* @param None.
*
* @return KeAreAllApcsDisabled returns TRUE if the thread is within a guarded
* guarded region or running at IRQL >= APC_LEVEL, and FALSE otherwise.
*
* @remarks A thread running at IRQL = PASSIVE_LEVEL can use this routine to
* determine if all APC delivery is disabled.
*
* Callers of this routine must be running at IRQL <= DISPATCH_LEVEL.
*
*--*/
BOOLEAN
NTAPI
KeAreAllApcsDisabled(VOID)
{
/* Return the Special APC State */
return ((KeGetCurrentThread()->SpecialApcDisable) ||
(KeGetCurrentIrql() >= APC_LEVEL)) ? TRUE : FALSE;
}