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

結果


返回上一頁