Files
nt-lite/code/kernel/ke_apc.h
T

103 lines
3.5 KiB
C

#pragma once
// ke_apc.h - kernel APC infrastructure
//
// Kernel APCs are per-thread callbacks that run in the target thread's
// context when that thread reaches PASSIVE_LEVEL and APC delivery is enabled.
// They are the first APC layer; user APCs will build on this once trap-frame
// return-to-user delivery exists.
#include <stdint.h>
#include <stdbool.h>
#include <ke_list.h>
#include <ke_status.h>
struct THREAD;
typedef struct THREAD THREAD;
typedef struct KTRAP_FRAME KTRAP_FRAME;
typedef struct KAPC KAPC;
typedef void (*PKKERNEL_ROUTINE)(KAPC* apc,
void** normalRoutine,
void** normalContext,
void** systemArgument1,
void** systemArgument2);
typedef void (*PKNORMAL_ROUTINE)(void* normalContext,
void* systemArgument1,
void* systemArgument2);
typedef void (*PKRUNDOWN_ROUTINE)(KAPC* apc);
typedef struct KUSER_APC KUSER_APC;
typedef struct SYS_USER_APC_FRAME_K {
uint64_t Magic;
uint64_t OriginalRip;
uint64_t OriginalRsp;
uint64_t OriginalRflags;
uint64_t OriginalRax;
uint64_t Routine;
uint64_t NormalContext;
uint64_t SystemArgument1;
uint64_t SystemArgument2;
} SYS_USER_APC_FRAME_K;
#define SYS_USER_APC_FRAME_MAGIC 0x3143504152555355ULL /* "USURAPC1" little-ish */
struct KUSER_APC {
LIST_ENTRY Link;
void* Routine;
void* NormalContext;
void* SystemArgument1;
void* SystemArgument2;
};
struct KAPC {
LIST_ENTRY Link;
THREAD* Thread;
PKKERNEL_ROUTINE KernelRoutine;
PKNORMAL_ROUTINE NormalRoutine;
PKRUNDOWN_ROUTINE RundownRoutine;
void* NormalContext;
void* SystemArgument1;
void* SystemArgument2;
volatile long Inserted;
};
void KiInitializeApcState(THREAD* thread);
__declspec(dllexport) void KeInitializeApc(KAPC* apc,
THREAD* thread,
PKKERNEL_ROUTINE kernelRoutine,
PKNORMAL_ROUTINE normalRoutine,
void* normalContext);
__declspec(dllexport) void KeSetApcRundownRoutine(KAPC* apc,
PKRUNDOWN_ROUTINE rundownRoutine);
__declspec(dllexport) bool KeInsertQueueApc(KAPC* apc,
void* systemArgument1,
void* systemArgument2);
__declspec(dllexport) void KeEnterCriticalRegion(void);
__declspec(dllexport) void KeLeaveCriticalRegion(void);
__declspec(dllexport) bool KeAreKernelApcsDisabled(void);
// Internal dispatcher hook. Called when a thread returns to PASSIVE_LEVEL,
// after context switches, and after waits complete.
void KiDeliverKernelApcs(void);
__declspec(dllexport) KSTATUS KeSetUserApcDispatcher(void* dispatcher);
__declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread,
void* routine,
void* normalContext,
void* systemArgument1,
void* systemArgument2);
__declspec(dllexport) uint64_t KeUserApcReturn(const SYS_USER_APC_FRAME_K* frame);
void KiRundownApcState(THREAD* thread);
// Called from KiExitTrapFrame before committing the editable user return state.
void KiCheckForUserApcDelivery(KTRAP_FRAME* frame);