从一个IRP指针获取主功能号
//irpsp是irp的栈空间,IoGetCurrentIrpStackLocation获取当前栈空间
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
if(irpsp->MajorFunction == IRP_MJ_WRITE)
{
//如果是写请求....
}
else if ((irpsp->MajorFunction == IRP_MJ_READ)
{
//如果是读请求
}
串口过滤的分发函数
NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp)
{
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
NTSTATUS status;
ULONG i,j;
for(i=0;i<=CCP_MAX_COM_ID;i++)
{
if(s_fltobj[i] == device)
{
//所有的电源操作直接放行
if(irpsp->MjorFunction == IRP_MJ_POWER)
{
//直接发送,然后返回说已经处理了
PoStartNextPowerIrp(irp);
IoSkipCurrentIrpStackLocation(irp);
return PoCallDriver(s_nextobj[i],irp);
}
//获取写请求的缓冲区及其长度然后打印
if{irpsp->MjorFunction == IRP_MJ_WRITE}
{
//如果是写请求先获取长度
ULONG len = irpsp->paramaters.Write.Length;
//然后获取缓冲区
PUCHAR buf = NULL;
if(irp->MdlAddress != NULL)
buf = (PUCHAR)MmGetSystemAddressForMalSafe(irp->MdlAddress.NormalPagePriority);
else
buf = (PUCHAR)irp->UserBuffer
if(buf == NULL)
buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;
//打印内容
for(j=0,j<len;++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",buf[j]);
}
}
//其他请求直接下发执行即可,我们并不禁止或者改变他
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(s_naxtobj[i],irp);
}
}
//如果不在绑定的设备中,那么返回参数错误
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
如何动态的卸载
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
void ccpUnload(PDRIVER_OBJECT drv)
{
ULONG i;
LARGE_INTEGER interval;
//首先解除锁定
for(i=0;i<=CCP_MAX_COM_ID;i++)
{
if(s_nextobj[i] != NULL)
IoDetachDevice(s_nextobj[i]);
}
//睡眠5秒,等待所有的IRP处理结束
interval.QuadPart = (5*1000*DELAY_ONE_MILLISECOND);
KeDelayExecutionThread(KernelMode,FALSE,&interval);
for(i=0;i<=CCP_MAX_COM_ID;i++)
{
if(s_fltobj[i] != NULL)
IoDetachDevice(s_fltobj[i]);
}
}