应用层与驱动层同步事件处理方法
2014-03-01 14:34
369 查看
源地址:http://hi.baidu.com/zkriymfvqfbaglq/item/90207f0785d2b713cd34ea53
(不保证一定是最初的博文地址)
关于这个问题高手略过吧。
Ring3与Ring0同步是很有用的手段,在此做一个简要的整理,希望对开发这方面程序的朋友有帮助,好了,开始吧。
1 同步的策略
初写驱动的朋友都知道,通过DeviceIoControl这个API函数, 可以将Ring3的数据及控制请求发送给Ring0.但这是单向的,由Ring3主动发起,Ring0被动接受。可以说这是单向轮询的。
询问(CTL_CODE)
Ring3 ---------------------------------------------------------------- > Ring0
回答(通过OUT参数)
Ring3 <---------------------------------------------------------------- Ring0
这种方式用于主动获取Ring0数据,又不要求效率,和具有实时性的开发情况。
但做监控类软件却与此相反,是Ring0先监控到事件,具有主动权,发起询问通知Ring3。
监控到事件(通知)
Ring0(监控)----------------------------------------------------------------> Ring3
在实时性要求不高的情况下可以采用Ring3定时询问Ring0,当然Ring0保存了事件的状态。
这里介绍的就是高实时性,大数据传输的同步解决办法。
原理:通过Ring3创建事件,并将该事件传递给Ring0,同时Ring3创建监控线程,等待Ring0发起事件,此为应用层驱动层共享事件。同时Ring0在内核分配非分页内存,通过DeviceIoControl 传递给Ring3,此为应用层驱动层共享内存。因在DeviceIoControl 中传送Buffer,涉及到内核数据拷贝,大数据量下使用效率很低,故用共享内存的方法。
2 具体实现
Ring3:
Ring0:
以上就是整个处理过程。
(不保证一定是最初的博文地址)
关于这个问题高手略过吧。
Ring3与Ring0同步是很有用的手段,在此做一个简要的整理,希望对开发这方面程序的朋友有帮助,好了,开始吧。
1 同步的策略
初写驱动的朋友都知道,通过DeviceIoControl这个API函数, 可以将Ring3的数据及控制请求发送给Ring0.但这是单向的,由Ring3主动发起,Ring0被动接受。可以说这是单向轮询的。
询问(CTL_CODE)
Ring3 ---------------------------------------------------------------- > Ring0
回答(通过OUT参数)
Ring3 <---------------------------------------------------------------- Ring0
这种方式用于主动获取Ring0数据,又不要求效率,和具有实时性的开发情况。
但做监控类软件却与此相反,是Ring0先监控到事件,具有主动权,发起询问通知Ring3。
监控到事件(通知)
Ring0(监控)----------------------------------------------------------------> Ring3
在实时性要求不高的情况下可以采用Ring3定时询问Ring0,当然Ring0保存了事件的状态。
这里介绍的就是高实时性,大数据传输的同步解决办法。
原理:通过Ring3创建事件,并将该事件传递给Ring0,同时Ring3创建监控线程,等待Ring0发起事件,此为应用层驱动层共享事件。同时Ring0在内核分配非分页内存,通过DeviceIoControl 传递给Ring3,此为应用层驱动层共享内存。因在DeviceIoControl 中传送Buffer,涉及到内核数据拷贝,大数据量下使用效率很低,故用共享内存的方法。
2 具体实现
Ring3:
// 创建事件 HANDLE m_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); // 发事件给ring 0 if (0 == DeviceIoControl( hFile, \ SET_EVENT, \ &m_hEvent, \ sizeof(HANDLE), \ NULL, \ 0,\ &uRetBytes, NULL)) { CloseHandle(hFile); CloseHandle(m_hEvent); return ; } // 获得ring 0 的共享内存 unsigned int add = 0; if (0 == DeviceIoControl( hFile, \ GET_SHARE_ADD, \ NULL, \ 0, \ &add, \ sizeof (unsigned int),\ &uRetBytes, NULL)) { CloseHandle(hFile); CloseHandle(m_hEvent); return ; } m_pShareMem =(PVOID)add; //映射的共享内存 //当Ring0有事件产生时,Ring3的线程就可处理m_pShareMen了。 UINT WorkThread(PVOID param) { ............... while(!bExit) { WaitForSingleObject(g_hEvent,INFINITE); ...................... // 可以处理分析m_pShareMen 了 } }
Ring0:
PVOID g_pSysAdd = NULL; PMDL g_pMdl = NULL; // 与ring 3 的共享内存描述 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString) { ...... g_pSysAdd = ExAllocatePool(NonPagedPool, SHARE_MLEN + IPHEDLEN); g_pMdl = IoAllocateMdl(g_pSysAdd, SHARE_MLEN + IPHEDLEN, FALSE, FALSE, NULL); MmBuildMdlForNonPagedPool(g_pMdl); ...... } // I/O控制派遣例程 NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp) { PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); // 取得I/O控制代码 ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; switch(uIoControlCode) { case SET_EVENT: // 处理Ring3的事件 if(g_pInBuffer == NULL||g_nInBuffSize < sizeof(HANDLE)) { status = STATUS_INVALID_BUFFER_SIZE; break; } hEvent = *(HANDLE *)g_pInBuffer; status = ObReferenceObjectByHandle( hEvent, SYNCHRONIZE, *ExEventObjectType, KernelMode, (PVOID *)&g_pEvent, &objHandleInfo ); if(!NT_SUCCESS(status)) { g_pEvent = NULL; } DbgPrint("g_pEvent: %x\n",g_pEvent); // 得到了ring 3 事件句柄 break; case GET_SHARE_ADD: // 传给ring 3 内存地址 UserAddr = MmMapLockedPages(g_pMdl, UserMode); *((PVOID *)(pIrp->AssociatedIrp.SystemBuffer)) = UserAddr; status = STATUS_SUCCESS; break; } .............. } RtlCopyMemory(g_pSysAdd,pSource,dwLen) // 将写数据到共享内存, KeSetEvent((PKEVENT)g_pEvent,0,false); // 此刻Ring3就可以接受数据了。 //最后一步记得释放内存。 void DriverUnload(PDRIVER_OBJECT pDriverObj) { // 清除共享内存 IoFreeMdl(g_pMdl); ExFreePool(g_pSysAdd); // 删除设备对象 IoDeleteDevice(pDriverObj->DeviceObject); }
以上就是整个处理过程。
相关文章推荐
- myeclipse10.0激活方式
- UIImageView类实现动画效果
- 特殊回文数
- Add Binary
- javascript学习笔记一:javascript原型+对象字面量等
- Log系统的JNI方法注册
- android下消息机制简介
- vc中ifstream ofstream不能读取带有中文路径
- linux编程-守护进程编写
- Linux useradd命令详解
- Maven 镜像
- struts2单例和多例
- java内存分析+String+equals详解
- 使用PriorityQueue排序?结果可能不是你想要的
- 【LeetCode】Sort Colors
- Hashmap的Hash()
- 怎样在xcode5中使用低版本sdk,解决兼容ios7ui问题
- 无权最短路径-广度优先搜索
- sql server 查看表的行数
- highcharts图表插件