- 浏览: 975920 次
- 性别:
- 来自: 珠海
-
文章分类
最新评论
-
Yunjey:
Yunjey 写道这样子的话、grid中的editable如何 ...
Flex创建可编辑以及分页的DataGrid -
Yunjey:
这样子的话、grid中的editable如何设置啊?!
Flex创建可编辑以及分页的DataGrid -
di1984HIT:
写的很好~~
JCalendar组件 -
sanny81:
此文真棒!感谢一路风尘的奉献!
但我有一疑 ...
Filter发送自定义数据详解 -
umgsai:
求完整demo umgsai@126.com
Flex和Jsp创建用户登入系统
前面我们谈到了关于异步I/O的实现:关于DeviceIoControl实 现异步的笔记【1】 。可是实现起来,你会发现你的程序在DevieIoControl已经被挂起,而且返回的结果是非0。这就与真正的异步调用返回结果有出入,理论上应该返回0,且GetLastError()值为ERROR_IO_PENDING。
/** Send the packets defined by users */ BOOL FilterWrapper::SendMyOwnPacket() { BOOL result = FALSE; DWORD bytesWritten = 0; DWORD varEventResult; OVERLAPPED varOverLapped; HANDLE varObjectHandle = 0; LPVOID testBuffer = NULL; PBYTE pBuf = NULL; DWORD testBufferLength = (DWORD)sizeof("Hi Mon, I finish your request!\n"); testBuffer = new BYTE[testBufferLength]; if(testBuffer == NULL) { goto Exit; } varObjectHandle = CreateEvent(NULL,TRUE, TRUE,""); if(varObjectHandle == NULL) goto Exit; memset(&varOverLapped,0,sizeof(OVERLAPPED)); varOverLapped.hEvent = varObjectHandle; varOverLapped.Offset = 0; varOverLapped.OffsetHigh = 0; // pass a new io control to underlying driver to send packets if(!DeviceIoControl( m_hFilter, IOCTL_FILTER_SEND_MYOWN_PACKET, "Request from user mode to Send A Packet.\n", sizeof("Request from user mode to Send A Packet.\n"), testBuffer, testBufferLength, &bytesWritten, (LPOVERLAPPED)&varOverLapped)) { //printf("Can't Send Packet\n"); if(GetLastError() != ERROR_IO_PENDING) { printf("Overlapped I/O exception\n"); goto Exit; }else{ printf("Overlappedn pending....\n"); } } printf("Son, I am calling you for dinner...\n"); varEventResult = WaitForSingleObject(varObjectHandle,6000); switch(varEventResult) { case WAIT_OBJECT_0 : printf("overlapped i/0 workss\n"); pBuf = (PBYTE)testBuffer; printf("Return buffer is %s\n",pBuf); result = TRUE; break; case WAIT_TIMEOUT: varEventResult = CancelIo(m_hFilter); result = FALSE; break; default: break; } // printf("Successfully Send A packet!^_^\n"); ResetEvent(varObjectHandle); CloseHandle(varObjectHandle); Exit: delete[] testBuffer; return result; }
所以每次都不会打印Overlappedn pending....这一句,因为DeviceIoControl返回为非零。我原本愚蠢的以为,底层驱动是不需要更改就可以实现异步I/O。但是我错了,从一开始我就错了。那么亡羊补牢吧。我们进行底层驱动的处理:
由于你要求驱动做的工作不能即时完成,所以我们先返回一个PENDING状态:
case IOCTL_FILTER_SEND_MYOWN_PACKET: InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; //这里等下讲如何叫底层驱动做该做的事情 //一个疑问在这里:如果像常规的函数在这里调用,那么跟同步I/O有何差异? //如果不这样,有其他方法吗? DEBUGP(DL_TEST,("I am waiting this io dispath\n")); Status = STATUS_PENDING; IoMarkIrpPending(Irp); Irp->IoStatus.Status = Status; return Status; break;
这里返回的状态为STATUS_PENDING,所以导致GetLastError值为ERROR_IO_PENDING,而是用overlapped i/o的异步方式导致DeviceIoControl返回为0.
别以为要做好了,还有好多疑问:
- 如何叫底层驱动做我么要他做的事情呢(很明显这里不能用常规的函数,否则当前线程就会执行这个函数的功能)
- 刚才的IRP请求到底执行结束没?
- 最后以何种方式告诉User层应用程序,某个时间已经是signaled状态,然后读取最后执行结果?
带着这个三个问题,我们继续讲:
既然不能用常规的函数,我们想想有什么方法可以让这个函数独立运行,而不受当前线程控制,答案就是在创建一个线程,负责该项工作。所以在上面的代码中间添加:
Status = PsCreateSystemThread(&threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, (PKSTART_ROUTINE) printSomething, Irp ); if( !NT_SUCCESS(Status)) { DEBUGP(DL_TEST,("Fail to start a thread!\n")); return Status; }
注意这里传入当前IRP的指针。当该线程完成工作后,结束该IRP。
接下来看看线程调用printSomething这个函数:
VOID printSomething( IN PIRP pIrp ){ PUCHAR OutputBuffer = NULL; PUCHAR pTestBuf = "Hi Mon, I finish your request!\n"; ULONG bufSize = sizeof("Hi Mon, I finish your request!\n"); mySleepTimer(5); DEBUGP(DL_TEST,("Five seconds,I have finished done something,hahhaha\n")); pIrp->IoStatus.Status = NDIS_STATUS_SUCCESS; OutputBuffer = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer; NdisMoveMemory(OutputBuffer,pTestBuf,bufSize); pIrp->IoStatus.Information = bufSize; IoCompleteRequest(pIrp, IO_NO_INCREMENT); PsTerminateSystemThread(STATUS_SUCCESS); }
这里,我们等待5秒钟,然后返回。返回前设置输出缓冲区的数据,返回给user,其次设置返回的状态Success等。最后调用IoCompleteRequest()函数通知User中的Event事件,把Event设置成Signaled状态,使得WaitForSignalObject函数可以继续执行。
这样才完成异步I/O的调用,其实自己细看,使用同步时,DeviceIoControl被挂起,现在使用异步,DeviceIoControl立刻返回,但是在WaitForSignalObject中挂起等待Event的状态改变。所以要真正实现异步,估计还需要在User层使用线程,用线程负责该DeviceIoControl的调用。才能真正意义上实现异步。
----------------------------------------附上MySleepTimer()------------------------------
这个函数实现的功能是延迟5秒钟。
VOID mySleepTimer( IN ULONG time ){ LARGE_INTEGER my_interval; my_interval.QuadPart = RELATIVE(SECONDS(5)); KeDelayExecutionThread(KernelMode,FALSE,&my_interval); }
关键是在SECONDS()的宏定义,来自Osronline的牛人写的:
//Define some times #define ABSOLUTE(wait) (wait) #define RELATIVE(wait) (-(wait)) #define NANOSECONDS(nanos) \ (((signed __int64)(nanos)) / 100L) #define MICROSECONDS(micros) \ (((signed __int64)(micros)) * NANOSECONDS(1000L)) #define MILLISECONDS(milli) \ (((signed __int64)(milli)) * MICROSECONDS(1000L)) #define SECONDS(seconds) \ (((signed __int64)(seconds)) * MILLISECONDS(1000L))
所以等相对的5秒钟就是 RELATIVE(SECONDS(5)),很强大~
------------------------------------附上图片---------------------------------
执行过程中,WaitForsignalObject被挂起:
最后执行完成:
下面是Debugview信息:
0005056 261.43447876 NDISLWF:
00005057 261.43450928 The input length is 42, and inputdata is Request from user mode to Send A Packet.
00005058 261.43450928
00005059 261.43460083 NDISLWF:
00005060 261.43460083 I am waiting this io dispath
.......
00005229 266.43710327 NDISLWF:
00005230 266.43713379 Five seconds,I have finished done something,hahhaha
-------------------参考资料-----------------
- DPC定时器何时返回的问题 http://bbs.pediy.com/showthread.php?t=110344
- 内核中线程的创建与销毁 http://hi.baidu.com/sysinternal/blog/item/f2b877084535c532e92488cc.html
- 关于DeviceIoControl异步调用的笔记【1】:http://yexin218.iteye.com/blog/638445
最后感谢两个人: 南部天天以及古越魂
评论
members of OVERLAPPED structure to zero before calling DeviceIoControl.
But what are you doing in the device driver? Here is an excerpt from the
MSDN KB article Q117308 (their site seems to be down, otherwise I would
direct you to the page).
"The driver should not complete the I/O request until an event has occurred.
When the driver receives the I/O request, if an event has occurred and is
waiting to be sent to the application, the driver can complete the request
in the dispatch routine. If no event is waiting to be reported, the driver
should perform the following steps:
1. Mark the Irp pending, using IoMarkIrpPending().
2. Set up a cancel routine for the Irp, using IoSetCancelRoutine().
3. Put the Irp in a storing place (a queue for example).
4. Return STATUS_PENDING from the dispatch routine.
Later, when an event has occurred, the driver can complete the pending
request from its deferred procedure call (DPC) routine. Before the Irp can
be completed, the driver should set the cancel routine address to NULL
using IoSetCancelRoutine."
发表评论
-
Filter驱动:过滤(修改)接受数据包
2010-04-20 16:18 9361Filter驱动可以实现简单的防火墙功能。它可以过滤所有接收到 ... -
Ndis过滤驱动:拷贝NetBufferList数据
2010-04-19 22:40 9609今天我们来看看如何拷贝NBL中的数据。有时候需要更改数据包中的 ... -
在Filter驱动内核中获取IP地址
2010-04-18 01:48 3911项目开发中有时候需要在Filter驱动中获取有效地Unic ... -
如何在内核中获得当前系统时间
2010-04-16 15:08 2751在 Windows NT 内核中你是无法使用 tim ... -
Filter发送自定义数据详解
2010-04-16 10:30 5789... -
DebugPrint 格式说明符
2010-04-13 19:46 17841) 直接打印字符串。 DbgPrint(“Hello ... -
WDK+Visual Studio 2008配置编译驱动
2010-04-12 23:36 5582Introduction As it is known, ... -
疑问:关于内存释放
2010-04-12 21:33 1473今天碰到一个比较棘手的内存处理问题。 首先来看一个数据结构: ... -
Windows NT 驱动程序开发人员提示 -- 应注意避免的事项
2010-04-10 11:32 2349原讨论链接: http://community.cs ... -
关于DeviceIoControl实现异步的笔记【1】
2010-04-08 22:26 11783一直所做的都是同步实现的。当然很多情况这并不是很好的解决问题。 ... -
驱动和应用层的异步通信
2010-04-08 20:55 5414作 者: sislcb时 间: 2008-01-28,11:1 ... -
Windows系统编程之异步I/O和完成端口
2010-04-08 19:40 2352一、 同步I/O和异步I/O ... -
纵横捭阖C++之从异步谈起
2010-04-08 19:31 3254一般来说,简单的异步(Asynchronous)调用是这样一种 ... -
使用DeviceIoControl通信
2010-04-04 22:53 7947在很多时候,某些用户需要与底层驱动有一个交互式的操作,所 ... -
在驱动中使用链表
2010-04-03 14:06 3305文章作者:grayfox 作 ... -
疑问:数据包Length增大的原因
2010-04-01 14:35 1387现象: 自己定义一个仅含有Ethernet Header的数 ... -
疑问:为何无线网卡无法发送数据?
2010-03-30 22:42 4588所有的测试流程表明,程序已经成功的创建新的数据包,然后调用Nd ... -
InsertHeadList和CONTAINING_RECORD
2010-03-29 16:36 3766LIST_ENTRY定义一个双向链表的数据结构: typed ... -
如何区分不同的Filter Module Instance
2010-03-29 14:50 1555前文 说到如何区分不同Filter Module Inst ... -
大数据是否需要封装在多个MDL中发送
2010-03-27 21:40 2535前段时间,我们已经解决如何发送自定义的网络数据。那么接下来要做 ...
相关推荐
关于DeviceIoControl实现异步的笔记【2】 - **笔记内容**:进一步深入探讨DeviceIoControl实现异步通信的关键技术和最佳实践。 - **学习价值**:通过实际案例加深对异步通信的理解。 #### 42. Windows NT驱动程序...
同时,过滤驱动中也需要掌握如何分配和管理NetBufferListPool,以及如何通过DeviceIoControl进行驱动程序与应用层的异步通信。 在遇到驱动程序中的bug和错误时,例如DRIVER_CORRUPTED_EXPOOL错误,需要有能力对内核...
- **BroadcastSystemMessage** 广播系统消息给所有顶级窗口,实现全局通知。 - **GetMessagePos** 和 **GetMessageTime** 分别返回上一条消息的鼠标位置和处理时间。 - **PostMessage** 将消息放入指定窗口的消息...
- **DeviceIoControl方式**:通过设备控制码(DeviceIoControl)来传递数据并执行用户态代码。 ##### 8. 进程线程监控 - **监控进程创建**:拦截新进程的创建事件,进行相应的处理。 - **杀线程**:终止特定线程的...
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
MMC整流器技术解析:基于Matlab的双闭环控制策略与环流抑制性能研究,Matlab下的MMC整流器技术文档:18个子模块,双闭环控制稳定直流电压,环流抑制与最近电平逼近调制,优化桥臂电流波形,高效并网运行。,MMC整流器(Matlab),技术文档 1.MMC工作在整流侧,子模块个数N=18,直流侧电压Udc=25.2kV,交流侧电压6.6kV 2.控制器采用双闭环控制,外环控制直流电压,采用PI调节器,电流内环采用PI+前馈解耦; 3.环流抑制采用PI控制,能够抑制环流二倍频分量; 4.采用最近电平逼近调制(NLM), 5.均压排序:电容电压排序采用冒泡排序,判断桥臂电流方向确定投入切除; 结果: 1.输出的直流电压能够稳定在25.2kV; 2.有功功率,无功功率稳态时波形稳定,有功功率为3.2MW,无功稳定在0Var; 3.网侧电压电流波形均为对称的三相电压和三相电流波形,网侧电流THD=1.47%<2%,符合并网要求; 4.环流抑制后桥臂电流的波形得到改善,桥臂电流THD由9.57%降至1.93%,环流波形也可以看到得到抑制; 5.电容电压能够稳定变化 ,工作点关键词:MMC
Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构,Simulink建模,MPPT最大功率点追踪,扰动观察法采用功率反馈方式,若ΔP>0,说明电压调整的方向正确,可以继续按原方向进行“干扰”;若ΔP<0,说明电压调整的方向错误,需要对“干扰”的方向进行改变。 ,Boost升压;光伏并网结构;Simulink建模;MPPT最大功率点追踪;扰动观察法;功率反馈;电压调整方向。,光伏并网结构中Boost升压MPPT控制策略的Simulink建模与功率反馈扰动观察法
STM32F103C8T6 USB寄存器开发详解(12)-键盘设备
科技活动人员数专指直接从事科技活动以及专门从事科技活动管理和为科技活动提供直接服务的人员数量
Matlab Simulink仿真探究Flyback反激式开关电源性能表现与优化策略,Matlab Simulink仿真探究Flyback反激式开关电源的工作机制,Matlab Simulimk仿真,Flyback反激式开关电源仿真 ,Matlab; Simulink仿真; Flyback反激式; 开关电源仿真,Matlab Simulink在Flyback反激式开关电源仿真中的应用
基于Comsol的埋地电缆电磁加热计算模型:深度解析温度场与电磁场分布学习资料与服务,COMSOL埋地电缆电磁加热计算模型:温度场与电磁场分布的解析与学习资源,comsol 埋地电缆电磁加热计算模型,可以得到埋地电缆温度场及电磁场分布,提供学习资料和服务, ,comsol;埋地电缆电磁加热计算模型;温度场分布;电磁场分布;学习资料;服务,Comsol埋地电缆电磁加热模型:温度场与电磁场分布学习资料及服务
1、文件内容:ibus-table-chinese-yong-1.4.6-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ibus-table-chinese-yong-1.4.6-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
基于51单片机protues仿真的汽车智能灯光控制系统设计(仿真图、源代码) 一、设计项目 根据本次设计的要求,设计出一款基于51单片机的自动切换远近光灯的设计。 技术条件与说明: 1. 设计硬件部分,中央处理器采用了STC89C51RC单片机; 2. 使用两个灯珠代表远近光灯,感光部分采用了光敏电阻,因为光敏电阻输出的是电压模拟信号,单片机不能直接处理模拟信号,所以经过ADC0832进行转化成数字信号; 3. 显示部分采用了LCD1602液晶,还增加按键部分电路,可以选择手自动切换远近光灯; 4. 用超声模块进行检测距离;
altermanager的企业微信告警服务
MyAgent测试版本在线下载
Comsol技术:可调BIC应用的二氧化钒VO2材料探索,Comsol模拟二氧化钒VO2的可调BIC特性研究,Comsol二氧化钒VO2可调BIC。 ,Comsol; 二氧化钒VO2; 可调BIC,Comsol二氧化钒VO2材料:可调BIC技术的关键应用
C++学生成绩管理系统源码
基于Matlab与Cplex的激励型需求响应模式:负荷转移与电价响应的差异化目标函数解析,基于Matlab与CPLEX的激励型需求响应负荷转移策略探索,激励型需求响应 matlab +cplex 激励型需求响应采用激励型需求响应方式对负荷进行转移,和电价响应模式不同,具体的目标函数如下 ,激励型需求响应; matlab + cplex; 负荷转移; 目标函数。,Matlab与Cplex结合的激励型需求响应模型及其负荷转移策略
scratch介绍(scratch说明).zip
内容概要:本文全面介绍了深度学习模型的概念、工作机制和发展历程,详细探讨了神经网络的构建和训练过程,包括反向传播算法和梯度下降方法。文中还列举了深度学习在图像识别、自然语言处理、医疗和金融等多个领域的应用实例,并讨论了当前面临的挑战,如数据依赖、计算资源需求、可解释性和对抗攻击等问题。最后,文章展望了未来的发展趋势,如与量子计算和区块链的融合,以及在更多领域的应用前景。 适合人群:对该领域有兴趣的技术人员、研究人员和学者,尤其适合那些希望深入了解深度学习原理和技术细节的读者。 使用场景及目标:①理解深度学习模型的基本原理和结构;②了解深度学习模型的具体应用案例;③掌握应对当前技术挑战的方向。 阅读建议:文章内容详尽丰富,读者应在阅读过程中注意理解各个关键技术的概念和原理,尤其是神经网络的构成及训练过程。同时也建议对比不同模型的特点及其在具体应用中的表现。