菜鸟之驱动开发2

上一篇文章里我们写了第一个驱动程序-HelloWorld, 今天我们来完善它,主要完成两个功能:添加一个驱动设备与给驱动添加默认派遣(IRP)。

首先我们来完成第一个功能:添加一个驱动设备。

代码如下:

NTSTATUS CreateTheDevice(IN PDRIVER_OBJECT pDeviceObject) { NTSTATUS status; PDEVICE_OBJECT pDevObj; UNICODE_STRING devName; UNICODE_STRING symLinkName; RtlInitUnicodeString(&devName, L"\\Device\\first_Device"); //create device status = IoCreateDevice(pDeviceObject,\ 0,\ &devName,\ FILE_DEVICE_UNKNOWN,\ 0,\ TRUE,\ &pDevObj\ ); if (!NT_SUCCESS(status)) { if (STATUS_INSUFFICIENT_RESOURCES == status) { KdPrint(("资源不足")); } if (STATUS_OBJECT_NAME_EXISTS == status) { KdPrint(("指定对象名存在")); } if (STATUS_OBJECT_NAME_COLLISION == status) { KdPrint(("//对象名有冲突")); } KdPrint(("设备创建失败")); return status; } KdPrint(("创建设备成功")); pDevObj->Flags |= DO_BUFFERED_IO; //创建符号链接 RtlInitUnicodeString(&symLinkName,L"\\??\\firstSymDevice"); status = IoCreateSymbolicLink( &symLinkName,&devName ); if (!NT_SUCCESS(status)) /*status等于0*/ { IoDeleteDevice( pDevObj ); return status; } return STATUS_SUCCESS; }


这样就可以给我们的驱动加入一个设备,驱动开发是unicode的方式,所以不能直接用用户态的API去处理字符串,必须用Rtl开头的内核函数,如上面RtlInitUnicodeString就是给第一个参数初始化。

第二个功能是关于IRP的,什么叫IRP(I/O Request Package).用户模式下所有对驱动的I/O请求,全部由操作系统转化为一个叫着IRP的数据结构,不同的IRP请求会被“派遣”到不同的派遣函数中。

有五种常用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.在驱动入口外注册IRP处理发函数

3.实现IRP处理函数

有两种方式注册IRP派遣函数,第一种是只有一个派遣函数,在该派遣函数内分别对根据IRP类型做不同的处理,这种方式代码如下:

//注册派遗函数 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; }


第二种是对每一种类型的IRP注册一个派遣函数,代码如下:

//注册派遗函数 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; //返回成功 }


到此代码介绍完毕, 记得在卸载驱动的时候,要卸载设备,不然下次加载驱动的时候,因为设备没有卸载而不能成功创建设备。请参看完整的源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值