驱动与应用层简单消息通信总结
驱动与应用层简单消息通信 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静态模版,做底层涉及到的知识是很深的,如果可以,很愿意一直从事下去,看到这篇博客的朋友想必都是新手,要是有需要帮助的随时留言,希望可以和大家一起成长,加油!