mark一下,以后需要。
驱动程序如何通知应用程序读取数据?这是一个很多人都关心的问题。
在此之前,我一直是采用的应用程序主动查询的方式,即,应用程序定时发送IRP来读取驱动程 序的数据。为此,必须考虑一个问题——如果应用程序没有运行,而驱动程序的缓冲区满了,如何处理?此外,应用程序需要不停地发送IRP,但是,每次发送后要Sleep一下,否则,CPU占有率会过高的。
但主动查询终究不是正道,效率低下。所以,现在要解决的是,如何通知应用程序读取驱动程序的数据。我想,大部分在应用层用于进程间通讯的方法都是可以在驱动层中使用的。
应用层中,进程间通讯的方法大概十几种,简单的就是WM_COPYDATA,它是消息通知的一种。那么,消息通知是否可行呢?我查了一下,找到了一个函数,SHELL_PostMessage(),但是它是工作在Vxd中的,所以不能使用了。
1. 事件通知方式
参看:
内核驱动程序和用户应用程序的消息通讯机制http://bbs.driverdevelop.com/simple/index.php?t102724.html
2. 信号量通知方式
参看:
驱动与应用程序通信的问题 http://topic.csdn.net/u/20080603/13/15b0a109-1a1b-4b29-9a02-cee0f269ffae.html?79847127
“Semaphore也是可以有名字的,可以调用未公开的函数ZwCreateSemaphore来创建。
其实不用把内核对象传给应用程序,可以自己定义一个DeviceControl的控制码,在驱动程序中访问内核对象,应用程序通过DeviceIoControl来代替Wait函数。”
3. 回调函数方式
中断产生后,如何向应用程序发送消息提示中断到来?http://www.funplay.cn/forum/read.php?tid=5733
代码:
在应用程序中:
typedef DWORD (CALLBACKFUNC)(void);
typedef CALLBACKFUNC *PCALLBACKFUNC;
CALLBACKFUNC CallBackFunc ;
extern PCALLBACKFUNC v_pCallBackPtr = NULL;
DWORD CallBackFunc()
{
return 0;
}
自己定义一个IOCTL_CAM_SET_CALLBACK,用DeviceIoControl()把 v_pCallBackPtr 传到驱动程序中:
v_pCallBackFunc = CallBackFunc;
if(DeviceIoControl( m_hDevice, IOCTL_CAM_SET_CALLBACK, v_pCallBackFunc ,sizeof(DWORD),
NULL,
0,
NULL,
NULL) == FALSE)
在驱动程序中,同样定义:
typedef DWORD (CALLBACKFUNC)(void);
typedef CALLBACKFUNC *PCALLBACKFUNC;
CALLBACKFUNC CallBackFunc ;
extern PCALLBACKFUNC v_pCallBackPtr = NULL; :
在DeviceIoControl()对应的:
XXX_IOControl()
{
switch (dwCode)
{
......
case IOCTL_CAM_SET_CALLBACK:
v_pCallBackPtr = (PCALLBACKFUNC)MapPtrToProcess(pBufIn,GetCallerProcess());
......
}
}
这样,就可以调用v_pCallBackPtr();了。
4. I/O重叠方式
设备驱动程序通知应用程序的几种方法
个人觉得,回调函数的方法实现起来最简单。事件通知方式运用最广泛。——还是使用事件通知方式吧。