diff --git a/xtoskrnl/includes/ke/apc.hh b/xtoskrnl/includes/ke/apc.hh index fc6c0cc..c324289 100644 --- a/xtoskrnl/includes/ke/apc.hh +++ b/xtoskrnl/includes/ke/apc.hh @@ -18,6 +18,10 @@ namespace KE class Apc { public: + STATIC XTAPI VOID CheckApcDelivery(VOID); + STATIC XTAPI VOID DeliverApc(IN KPROCESSOR_MODE ProcessorMode, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame); STATIC XTAPI VOID InitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT Environment, diff --git a/xtoskrnl/ke/apc.cc b/xtoskrnl/ke/apc.cc index 1969d5c..574cf68 100644 --- a/xtoskrnl/ke/apc.cc +++ b/xtoskrnl/ke/apc.cc @@ -4,11 +4,78 @@ * FILE: xtoskrnl/ke/apc.cc * DESCRIPTION: Kernel APC objects support * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ #include +/** + * Checks if a kernel APC can be delivered and initiates the delivery process. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::Apc::CheckApcDelivery(VOID) +{ + PKTHREAD Thread; + + /* Check if system is running at PASSIVE level */ + if(KE::RunLevel::GetCurrentRunLevel() == PASSIVE_LEVEL) + { + /* Raise runlevel to APC level */ + KE::RaiseRunLevel RunLevel(APC_LEVEL); + + /* Deliver the APC */ + DeliverApc(KernelMode, NULLPTR, NULLPTR); + } + else + { + /* Mark the current thread as having a pending kernel APC */ + Thread = KE::Processor::GetCurrentThread(); + Thread->ApcState.KernelApcPending = TRUE; + + /* Request an APC software interrupt */ + HL::Irq::SendSoftwareInterrupt(APC_LEVEL); + } +} + +/** + * Delivers pending Asynchronous Procedure Calls (APCs) to the current executing thread. + * + * @param ProcessorMode + * Supplies the processor execution mode at the time the APC delivery was requested. + * + * @param ExceptionFrame + * Supplies an optional pointer to the exception frame if the APC is being delivered following an exception. + * + * @param TrapFrame + * Supplies an optional pointer to the trap frame if the APC is being delivered following an interrupt. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::Apc::DeliverApc(IN KPROCESSOR_MODE ProcessorMode, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame) +{ + PKTHREAD Thread; + + UNIMPLEMENTED; + + /* Get the current thread */ + Thread = KE::Processor::GetCurrentThread(); + + /* Clear the pending kernel APC flag */ + Thread->ApcState.KernelApcPending = FALSE; +} + /** * Initializes an APC object. *