#pragma once // ke_dpc.h - deferred procedure calls // // DPCs are the kernel's bottom-half mechanism. Hardware ISRs can queue a DPC // after acknowledging/capturing device state; the DPC then runs later at // DISPATCH_LEVEL from the common interrupt-exit path. DPC routines must not // wait, block, or call PASSIVE_LEVEL-only code. #include #include #include #include typedef struct KDPC KDPC; typedef void (*KDEFERRED_ROUTINE)(KDPC* dpc, void* context, void* systemArgument1, void* systemArgument2); struct KDPC { LIST_ENTRY Link; KDEFERRED_ROUTINE Routine; void* Context; void* SystemArgument1; void* SystemArgument2; volatile long Inserted; }; // Called during kernel bring-up before interrupts are enabled. void KeInitializeDpcSystem(void); __declspec(dllexport) void KeInitializeDpc(KDPC* dpc, KDEFERRED_ROUTINE routine, void* context); // Queue a DPC if it is not already queued. Returns false if the DPC was // already pending or the arguments are invalid. __declspec(dllexport) bool KeInsertQueueDpc(KDPC* dpc, void* systemArgument1, void* systemArgument2); // Internal: drain queued DPCs at DISPATCH_LEVEL. Called from interrupt exit. void KiDrainDpcQueue(void);