关于这个问题高手略过吧。 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 CODE : HANDLE m_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); // 创建事件 // 发事件给ring 0 if (0 == DeviceIoControl(hFile, / // 获得ring 0 的共享内存 unsigned int add = 0; 当Ring0有事件产生时,Ring3的线程就可处理m_pShareMen了。 UINT WorkThread(PVOID param) { ............... while(!bExit) { WaitForSingleObject(g_hEvent,INFINITE); ...................... // 可以处理分析m_pShareMen 了 } } Ring0 CODE : PVOID g_pSysAdd = NULL; NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString) } // I/O控制派遣例程 { PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); switch(uIoControlCode)
} .............. } RtlCopyMemory(g_pSysAdd,pSource,dwLen) // 将写数据到共享内存, KeSetEvent((PKEVENT)g_pEvent,0,false); // 此刻Ring3就可以接受数据了。 最后一步记得释放内存。 void DriverUnload(PDRIVER_OBJECT pDriverObj) 以上就是整个处理过程。 |
应用层与驱动层同步事件处理方法
应用层与驱动层同步事件处理方法
2007-09-03 17:00