Windows Driver Model >> C/C++
Asynchronous Procedure Call(APC)
參考資訊:
1. Source Code
2. inside-nts-asynchronous-procedure-call
此部份屬於Undocument範疇,可能因系統或者環境而異,Asynchronous Procedure Call(APC)介紹的相關資料甚少,一般都只知道是用於Windows系統上,用來做Context Switch的排程,優先級別屬於APC_LEVEL,介於PASSIVE_LEVEL和DISPATCH_LEVEL之間,因此,司徒將它當作是一般排程使用。
main.c
#include <wdm.h> #define DEV_NAME L"\\Device\\MyDriver" #define SYM_NAME L"\\DosDevices\\MyDriver" KAPC stAPC={0}; PDEVICE_OBJECT pNextDevice=NULL; typedef enum _KAPC_ENVIRONMENT { OriginalApcEnvironment, AttachedApcEnvironment, CurrentApcEnvironment, InsertApcEnvironment } KAPC_ENVIRONMENT; NTSYSAPI BOOLEAN _stdcall KeInsertQueueApc(PRKAPC, PVOID, PVOID, KPRIORITY); void KeInitializeApc(PKAPC, PETHREAD, KAPC_ENVIRONMENT, PKKERNEL_ROUTINE, PKRUNDOWN_ROUTINE, PKNORMAL_ROUTINE, KPROCESSOR_MODE, PVOID); void APC_Handler(PRKAPC Apc, PKNORMAL_ROUTINE *NormalRoutine, PVOID *NormalContext, PVOID *SystemArgument1, PVOID *SystemArgument2) { DbgPrint("APC_Handler\n"); } NTSTATUS AddDevice(PDRIVER_OBJECT pOurDriver, PDEVICE_OBJECT pPhyDevice) { PDEVICE_OBJECT pOurDevice=NULL; UNICODE_STRING usDeviceName; UNICODE_STRING usSymboName; RtlInitUnicodeString(&usDeviceName, DEV_NAME); IoCreateDevice(pOurDriver, 0, &usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pOurDevice); RtlInitUnicodeString(&usSymboName, SYM_NAME); IoCreateSymbolicLink(&usSymboName, &usDeviceName); pNextDevice = IoAttachDeviceToDeviceStack(pOurDevice, pPhyDevice); pOurDevice->Flags&= ~DO_DEVICE_INITIALIZING; pOurDevice->Flags|= DO_BUFFERED_IO; KeInitializeApc(&stAPC, PsGetCurrentThread(), 0, APC_Handler, 0, NULL, KernelMode, NULL); return STATUS_SUCCESS; } void Unload(PDRIVER_OBJECT pOurDriver) { pOurDriver = pOurDriver; } NTSTATUS IrpPnp(PDEVICE_OBJECT pOurDevice, PIRP pIrp) { PIO_STACK_LOCATION psk = IoGetCurrentIrpStackLocation(pIrp); UNICODE_STRING usSymboName; if(psk->MinorFunction == IRP_MN_START_DEVICE){ KeInsertQueueApc (&stAPC, NULL, NULL, 0); } else if(psk->MinorFunction == IRP_MN_REMOVE_DEVICE){ RtlInitUnicodeString(&usSymboName, SYM_NAME); IoDeleteSymbolicLink(&usSymboName); IoDetachDevice(pNextDevice); IoDeleteDevice(pOurDevice); } IoSkipCurrentIrpStackLocation(pIrp); return IoCallDriver(pNextDevice, pIrp); } NTSTATUS DriverEntry(PDRIVER_OBJECT pOurDriver, PUNICODE_STRING pOurRegistry) { pOurDriver->MajorFunction[IRP_MJ_PNP] = IrpPnp; pOurDriver->DriverExtension->AddDevice = AddDevice; pOurDriver->DriverUnload = Unload; return STATUS_SUCCESS; }
IRP_MN_START_DEVICE插入一個新的APC Task
結果