向Windows内核驱动传递用户层定义的事件Event,并响应内核层的通知
完整的程序在下载:http://download.csdn.net/detail/dijkstar/7913249
用户层创建的事件Event是一个Handle句柄,和内核中的创建的内核模式下的KEVENT是一个东西。因此,在应用层创建的事件,可以在内核层获得并使用。这一部分的原理,见张帆编著的《Windows驱动技术详解》章节8.5.4,P237页;
程序是来自于《Windows驱动技术详解》章节8.5.4(驱动程序和应用程序交互事件对象)和章节10.2.1(DPC定时器)。
首先,在应用层创建一个等待事件Event,创建监控这个等待事件的线程,并把等待事件Event传递给内核:
- //
- // 1. 创建用户层的等待事件,传入内核
- // 2. 创建线程,用于监测内核事件的到来
- //
- HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, Thread1, &hEvent, 0, NULL);
- //先将用户层的等待Event传入内核
- DeviceIoControl(hDevice, IOCTL_SET_EVENT, &hEvent, sizeof(hEvent), NULL, 0, &dwOutput, NULL);
监控线程的内容:(里面用了查询指令周期数,可以测试每次等待WaitFor××的时间)
- UINT WINAPI Thread1(LPVOID para)
- {
- HANDLE *phEvent = (HANDLE *)para;
- while(1)
- {
- //获得初始值
- QueryPerformanceCounter(&litmp);
- qt1=litmp.QuadPart;
- //等待
- WaitForSingleObject(*phEvent, INFINITE);
- //获得终止值
- QueryPerformanceCounter(&litmp);
- qt2=litmp.QuadPart;
- //获得对应的时间值,转到毫秒单位上
- dfm=(double)(qt2-qt1);
- dft=dfm/dff;
- printf("本次等待用时: %.3f 毫秒\n", dft*1000.0);
- }
- }
用户层还通知驱动内核启动一个DPC定时器,用于每次来触发应用层的等待事件Event:
- DWORD dwMircoSeconds = 1000 * 50; //单位微秒
- DeviceIoControl(hDevice, IOCTL_START_TIMER, &dwMircoSeconds, sizeof(DWORD), NULL, 0, &dwOutput, NULL);
在驱动程序中,首先取出来应用层传递进来的事件,并把它转化为内核对象:
- case IOCTL_SET_EVENT:
- {
- //把传递进来的用户层等待事件取出来
- HANDLE hUserEvent = *(HANDLE *)pIrp->AssociatedIrp.SystemBuffer;
- //将用户层事件转化为内核等待对象
- status = ObReferenceObjectByHandle(hUserEvent, EVENT_MODIFY_STATE,
- *ExEventObjectType, KernelMode, (PVOID*)&pDevExt->pEvent, NULL);
- KdPrint(("status = %d\n", status));//status应该为0才对
- ObDereferenceObject(pDevExt->pEvent);
- break;
- }
在内核的每次定时器到来时,激活等待事件,等于触发激活应用层的WaitFor××函数向下继续执行:
- #pragma LOCKEDCODE
- VOID PollingTimerDpc( IN PKDPC pDpc,
- IN PVOID pContext,
- IN PVOID SysArg1,
- IN PVOID SysArg2 )
- {
- PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)pContext;
- PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
- KeSetTimer(
- &pdx->pollingTimer,
- pdx->pollingInterval,
- &pdx->pollingDPC );
- KdPrint(("PollingTimerDpc\n"));
- //定时器到来,通知用户层
- if(pdx->pEvent)
- KeSetEvent(pdx->pEvent, IO_NO_INCREMENT, FALSE);
- /*
- //检验是运行在任意线程上下文
- PEPROCESS pEProcess = IoGetCurrentProcess();
- PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);
- KdPrint(("%s\n",ProcessName));
- */
- }
程序中其他部分见源码解释,这个程序还有两个问题,一是应用层必须正常退出,否则驱动内核层因不能正常关闭DPC定时器,而继续执行已经找不到的等待事件,引起蓝屏崩溃;二是虽然在内核里,DPC定时器的触发精度为1个100ns级别,但当触发周期设置为20ms以下时,在应用层监控WaitFor,都是十几个毫秒的分辨精度,再向下设置已经没有意义。
jpg 改 rar 
向Windows内核驱动传递用户层定义的事件Event,并响应内核层的通知的更多相关文章
- go语言学习--内核态和用户态(协程)
go中的一个特点就是引入了相比于线程更加轻量级的协程(用户态的线程),那么什么是用户态和内核态呢? 一.什么是用户态和内核态 当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核 ...
- 【windows 操作系统】【CPU】用户模式和内核模式(用户层和内核层)
所有的现代操作系统中,CPU是在两种不同的模式下运行的: 注意以下内容来自微软: windows用户模式和内核模式 运行 Windows 的计算机中的处理器有两个不同模式:用户模式 和内核模式 . 用 ...
- Windows网络驱动、NDIS驱动(微端口驱动、中间层驱动、协议驱动)、TDI驱动(网络传输层过滤)、WFP(Windows Filtering Platform)
catalog . 引言 . Windows 2000网络结构和OSI模型 . NDIS驱动 . NDIS微端口驱动编程实例 . NDIS中间层驱动编程实例 . NDIS协议层驱动编程实例 . TDI ...
- 理解Windows内核模式与用户模式
1.基础 执行 Windows 的计算机中的处理器有两个不同模式:"用户模式"和"内核模式". 依据处理器上执行的代码的类型,处理器在两个模式之间切换.应 ...
- Windows内核驱动中操作文件
本页主题:如何在windows内核驱动中对文件操作,实现对文件的拷贝.粘贴.删除.查询信息等,这是很常用也是很简单的方法. 部分内容参考:http://www.cppblog.com/aurain/a ...
- 用户空间与内核驱动的交互过程 — ioctl
在Linux内核模块的开发过程中,经常涉及到运行在用户空间上的应用程序与内核模块进行交互,ioctl系统调用是常用的一种方式.本文并不涉及vlan的具体原理,仅通过vconfig与vlan内核模块进行 ...
- Windows系统的四个重要概念——进程、线程、虚拟内存、内核模式和用户模式
引言 本来在写一篇Windows内存管理的文章,写着写着就发现好多基础的概念都要先讲.更可怕的是,这些基础的概念我却不能完全讲清楚.只好再把这本<深入解析Windows操作系统>翻到第一章 ...
- Windows内核驱动开发入门学习资料
声明:本文所描述的所有资料和源码均搜集自互联网,版权归原始作者所有,所以在引用资料时我尽量注明原始作者和出处:本文所搜集资料也仅供同学们学习之用,由于用作其他用途引起的责任纠纷,本人不负任何责任.(本 ...
- Windows内核驱动开发:HelloWorld
测试信息 Dev Machine: Windows Version: 2004 (19041.264) WDK Version: 10.0.19041.1 SDK Version: 10.0.1904 ...
随机推荐
- Lua------------------unity关于lua的使用
关于Lua在Unity 中的使用 对于手机游戏,如果可以在线更新以实现bug修复.新功能添加等等,其好处自不必多说. 通过C#的反射机制,也可以实现某种程度上的脚本级更新,具体可以参考 http: ...
- svn -- svn配置自动启动
配置自动启动服务 1.添加到系统服务 sc create SVNService binpath= “D:\subversion\bin\svnserve.exe --service -r D:/sv ...
- nodejs基础 -- 常用工具util
util是nodejs的核心模块,提供常用函数的集合,用户弥补核心javascript的功能过于精简的不足 util.inherits 是一个实现对象间原型继承的函数 javascript的面向对象特 ...
- C# 获取文件夹下的所有文件的文件名
String path = @"X:\xxx\xxx"; //第一种方法 var files = Directory.GetFiles(path, "*.txt" ...
- Opengl的gl_NormalMatrix
原文地址:http://blog.csdn.net/ichild1964/article/details/9728357 参考:http://www.gamedev.net/topic/598985- ...
- spring + springMVC + spring Data + jpa + maven 项目框架搭建
首先看一下项目结构: 所用到的jar(pom.xml): <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:x ...
- hql Hibernate.gethibernatetemplate()
1. find(String hql); //普通查询 示例:this.gethibernateTemplate().find("from User"); 2. find(Str ...
- SharePoint PowerShell使用Backup-SPSite指令来备份网站集
备份网站集: Backup-SPSite -Identity http://win2012sp2013:1000/ -Path "C:\KenmuTemp\Test File\Temp\si ...
- DEFINE_PER_CPU,如何实现“数组”
引述自:http://www.unixresources.net/linux/clf/linuxK/archive/00/00/47/91/479165.html Kevin.Liu 的<调度器 ...
- [转载]Android 生成keystore,两种方式
Refer : http://blog.csdn.net/ms03001620/article/details/8490314 一.eclipse 中生成android keystore 建立任意一个 ...