预计平均三天一课,录制过程中,大纲会实时更新(更改)
主讲:郁金香灬老师 QQ150330575
开发环境:VC6,VS2003,VS2008
教程购买地址:http://yjxsoft.taobao.com
1.3.8为DDK_HelloWorld添加默认派遣例程-16课
A、初识IRP
B、一个简单的IRP处理函数
C、IRP.IoStatus结构
D、IoCompleteRequest函数
IPR简介:
IRP全称(I/O Request Package),即输入输出请求包。他是windows驱动的重要概念,用户模式下所有对驱动程序的I/O请求,全部由操作系统转化为一个叫做IRP的数据结构,不同的IRP数据会被“派遗”到不同的派遣函数(DisPatch Function)中。
作用:
上层应用程序与底层驱动通信。EXE程序与SYS
五种常用的IRP类型:
#define IRP_MJ_CREATE 0x00 //CreateFile()
#define IRP_MJ_CLOSE 0x02 //CloseHandle()
#define IRP_MJ_READ 0x03//ReadFile
#define IRP_MJ_WRITE 0x04//WriteFile
#define IRP_MJ_DEVICE_CONTROL 0x0e//DeviceIoControl
过程:
1、创建IRP处理函数
2、在驱动入口函数里DriverEntry()注册IRP处理函数
3、细化IRP函数
相关内核API:
//获取指定IRP的栈空间地址
PIO_STACK_LOCATION IoGetCurrentIrpStackLocation( IN PIRP Irp);
VOID IoCompleteRequest(
IN PIRP Irp,//指定需要完成的IPR
IN CCHAR PriorityBoost //
);
方法1:统一注册派遗函数
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_CREATE]=ddk_DispatchRoutine;
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine;
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_READ]=ddk_DispatchRoutine;
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_WRITE]=ddk_DispatchRoutine;
//注册派遗函数
pDriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL]=ddk_DispatchRoutine;
NTSTATUS ddk_DispatchRoutine(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp )
{
PIO_STACK_LOCATION irpsp=IoGetCurrentIrpStackLocation(pIrp);
switch (irpsp->MajorFunction)
{
case IRP_MJ_CREATE:
break;
case IRP_MJ_CLOSE:
break;
case IRP_MJ_READ:
break;
case IRP_MJ_WRITE:
break;
case IRP_MJ_DEVICE_CONTROL:
break;
default:
KdPrint(("其它处理"));
//指示完成此IRP
}
//成功返回
return STATUS_SUCCESS;
}
//方法二:分开注册
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_CREATE]=ddk_DispatchRoutine_CREATE;
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine_CLOSE;
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_READ]=ddk_DispatchRoutine_READ;
//注册派遗函数
pDriverObject->MajorFunction[IRP_MJ_WRITE]=ddk_DispatchRoutine_WRITE;
//注册派遗函数
pDriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL]=ddk_DispatchRoutine_CONTROL;
NTSTATUS ddk_DispatchRoutine_CONTROL(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp )
{
//对相应的IPR进行处理
pIrp->IoStatus.Information=0;//设置操作的字节数为0,这里无实际意义
pIrp->IoStatus.Status=STATUS_SUCCESS;//返回成功
IoCompleteRequest(pIrp,IO_NO_INCREMENT);//指示完成此IRP
KdPrint(("离开派遣函数\n"));//调试信息
return STATUS_SUCCESS; //返回成功
}