驱动与应用层简单消息通信总结

驱动与应用层简单消息通信总结

参考:

驱动与应用层简单消息通信  http://www.cnblogs.com/einyboy/archive/2012/06/13/2548030.html

GetLastError    http://www.cnblogs.com/carekee/articles/2196518.html

DeviceIoControl的使用说明     http://hi.baidu.com/dylan_li/item/90b061dcb3d9a1df251f4097

由于从来没接触过驱动编程,想要入门理解驱动与应用程序间的通信,刚开始确实很头疼,我的理解总是与真正的原理不一致,我的理解是:像我们自己写的函数那样,知道函数地址,传过去各种形参,返回来的是运算结果,但是驱动与应用程序间的通信,却有那么一些的不一样,经过两天的努力入门总结一下:


001:首先编写自己的驱动程序,使用默认的模版就行,之后在入口函数DriverEntry中增加注册回调函数:

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceIoControl;

002:创建设备的时候,给扩展区设置最高允许传过来的缓存大小,这个地方如果设置为0会导致程序无法运行,因为没有空间存放应用程序传参,例如:

ntStatus = IoCreateDevice(DriverObject,         //生成设备的驱动对象  
                              10,                    //设备扩展区内存大小  
                              &DeviceName,          //设备名,/Device/Aliwy  
                              FILE_DEVICE_UNKNOWN,  //设备类型  
                              0,                    //填写0即可  
                              FALSE,                //必须为FALSE  
                              &Device);             //设备对象指针返回到DeviceObject中  

003:MyDeviceIoControl:

inBuf = Irp->AssociatedIrp.SystemBuffer;  //输入缓冲区  
outBuf = Irp->AssociatedIrp.SystemBuffer; //输出缓冲区  

这里是困扰我好久的地方,SystemBuffer是PVOID类型的,我们想要获得缓冲区的地址给inBuf,我的inBuf是PCHAR类型的,首先得强制转换一下:

inBuf = (PCHAR)Irp->AssociatedIrp.SystemBuffer;  //输入缓冲区  
outBuf = (PCHAR)Irp->AssociatedIrp.SystemBuffer; //输出缓冲区 

之后用KdPrint(("inBuf : %s\n",inBuf))打印inBuf居然始终是空,很头疼,结果使用WinDbg调试,用dc 0xf9d4d140  (0xf9d4d140是inBuf的内存地址)查看inBuf 的物理内容,发现数值是存在并且正确的,看来肯定是取字符串出问题了,给inBuf结果增加一个'\0',就正确了。

004:Irp返回结果设置:

错误的设置:

Irp->IoStatus.Information = 0; 
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

正确的设置:

Irp->IoStatus.Information = outDataLen; 
Irp->IoStatus.Status = STATUS_SUCCESS; 

由于这里之前忘记修改,使用的是错误的设置,直接导致内核缓存中的数据是争取的,而用户缓存始终没有数据,就是这里的问题,Status不是正确的,那么I/O管理器就不会把系统分配的缓存中的结果复制到应用缓存中。

005:应用程序:

/*打开设备,用我们自定的符号链接,响应驱动IRP_MJ_CREATE*/ 
    HANDLE hDevice = CreateFile(".//IamAliwy", 
                                GENERIC_READ | GENERIC_WRITE, 
                                FILE_SHARE_READ,  //修改成这样
                                NULL, 
                                CREATE_ALWAYS, 
                                FILE_ATTRIBUTE_NORMAL, 
                                NULL); 

/*控制设备,响应驱动IRP_MJ_DEVICE_CONTROL*/ 
    BOOL ret = DeviceIoControl(hDevice, 
                               MY_DVC_BUFFERED_CODE, //我们自定义的功能号  
                               inBuf,               //传入驱动的内容  
                               strlen(inBuf) + 1,    //传入内容长度  
                               outBuf,              //驱动输出的缓冲区  
                               sizeof(outBuf),       //驱动输出缓冲区大小  
                               &bytesReturned,       //返回的长度  
                               NULL); 

新手刚开始学确实听累的,因为以前是编写上层应用程序,而现在却是编写底层,不过,虽然仅仅编写了6天底层,却感觉这个方向很好,不用费尽心思去找个毫无技术锻炼的属性调节ASP.NET的图像显示样式,也不用编写很枯燥的html静态模版,做底层涉及到的知识是很深的,如果可以,很愿意一直从事下去,看到这篇博客的朋友想必都是新手,要是有需要帮助的随时留言,希望可以和大家一起成长,加油!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值