阅读:4554回复:26
怎么在应用层取消Overlap的ReadFile动作?100分!
创建了一个驱动程序,我用CreateFile打开,用ReadFile从这个驱动程序中读取数据,当ReadFile返回错误,如果错误代码是ERROR_IO_PENDING的时候,我就用GetOverlappedResult来等待数据的到来。问题是,如果数据没来的时候,我想停止掉这个操作怎么办?我尝试过直接修改Overlap的Event, 但是这样的话,在最后CloseHandle的时候,时间好长,不知为何?那位高手解答一下。
|
|
最新喜欢:![]() |
沙发#
发布于:2005-08-05 15:55
调用if(!ReadFile(m_hEP1Read,buf,*len,&mByte,&m_OvRead1)) status = GetLastError();的确是返回了.但是status = 998,MSDN解释是ERROR_NOACCESS 998 Invalid access to memory location. 访问的内存位置无效.使用if(!ReadFile(m_hEP1Read,buf,*len,&mByteNULL)) status = GetLastError();时,XP DDK SP1的bulkusb无论是异步还是同步,嵌入式系统都无反应,而且桌面的图标也被自动隐藏.但NT DDK的bulkusb在同步时是用反应的,并且桌面的图标也不会自动隐藏,异步时同XP.版主能不能解释为何.
|
|
板凳#
发布于:2005-08-04 10:43
谢谢.
不错,ReadFile()传给下层IoCallDriver()后.是返回STATUS_PENDING. 另外.我想取消pending的IRP可以用DeviceIoControl(),在驱动程序中.增加相应的代码.取消所有暂停的IRP.是否可行自己打了个问寒问号?因为DeviceIoControl()是对控制端点操作的.(我自己试的是这样,不知道别人的如何?) |
|
地板#
发布于:2005-08-04 09:54
下面是引用tianrongcai于2005-08-03 16:25发表的: 可能是你的irp已经交给下层处理,下层返回pending的,你取消irp的时候,取消irp也由下层处理, 所以你的驱动程序就不用改变了阿 |
|
地下室#
发布于:2005-08-03 16:25
不知道何原因?按照15楼的方法就是可以正常退出,驱动程序不改变.
|
|
5楼#
发布于:2005-08-03 16:03
我查WDM.H的所有入口
// // Define the major function codes for IRPs. // #define IRP_MJ_CREATE 0x00 #define IRP_MJ_CREATE_NAMED_PIPE 0x01 #define IRP_MJ_CLOSE 0x02 #define IRP_MJ_READ 0x03 #define IRP_MJ_WRITE 0x04 #define IRP_MJ_QUERY_INFORMATION 0x05 #define IRP_MJ_SET_INFORMATION 0x06 #define IRP_MJ_QUERY_EA 0x07 #define IRP_MJ_SET_EA 0x08 #define IRP_MJ_FLUSH_BUFFERS 0x09 #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a #define IRP_MJ_SET_VOLUME_INFORMATION 0x0b #define IRP_MJ_DIRECTORY_CONTROL 0x0c #define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d #define IRP_MJ_DEVICE_CONTROL 0x0e #define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f #define IRP_MJ_SHUTDOWN 0x10 #define IRP_MJ_LOCK_CONTROL 0x11 #define IRP_MJ_CLEANUP 0x12 #define IRP_MJ_CREATE_MAILSLOT 0x13 #define IRP_MJ_QUERY_SECURITY 0x14 #define IRP_MJ_SET_SECURITY 0x15 #define IRP_MJ_POWER 0x16 #define IRP_MJ_SYSTEM_CONTROL 0x17 #define IRP_MJ_DEVICE_CHANGE 0x18 #define IRP_MJ_QUERY_QUOTA 0x19 #define IRP_MJ_SET_QUOTA 0x1a #define IRP_MJ_PNP 0x1b #define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... #define IRP_MJ_MAXIMUM_FUNCTION 0x1b 以及PDRIVER_EXTENSION 和 PDRIVER_OBJECT都没有发现该入口可加入. |
|
6楼#
发布于:2005-08-03 15:32
老兄.
如何在驱动程序的入口中增加该函数 VOID CancelIrpRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 比如DriverObject->MajorFunction[IRP_MJ_WRITE] = BulkUsb_DispatchReadWrite;之类的东西.我的驱动是用XP DDK里的BULK_USB改的,应用程序调用CancelIo()时,驱动程序没有任何反应,当然ReadFile()就一直阻塞了,线程无法终止.相信是没有在驱动程序中增加相应的CancelIo()入口吧. |
|
7楼#
发布于:2002-06-17 12:38
哦,明白,我重开一贴,你来领分吧。
|
|
8楼#
发布于:2002-06-17 12:33
驱动中
IoMarkIrpPending(Irp); IoSetCancelRoutine(Irp,CancelIrpRoutine);设置Cancel例程。在应用中调用CancelIO时,CancelIrpRoutine会由系统调用。 VOID CancelIrpRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); |
|
|
9楼#
发布于:2002-06-17 12:16
对了,CancelIo的时候,驱动程序里面会得到什么响应?我在驱动程序里面做了一个Pending Irp的队列,把Irp的指针保存起来了,Cancel的时候我应该把他们删除掉啊。
|
|
10楼#
发布于:2002-06-17 12:10
那就while(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT)
{ if(m_Cancel) { CancelIO(hDevice); break; } } 然后在主线程要退出或者想停止子线程的运行的时候m_Cancel = TRUE; |
|
|
11楼#
发布于:2002-06-17 12:02
[quote] “我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了。” 胡扯。 if(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT) { CancelIO(hDevice); } 怎么不行?!为什么我屡试不爽呢?! [/quote] 不用试我也知道你这种做法能行,但我的情形跟你不大一样。我的读动作是在一个线程里面,只有当主线程要退出或者想停止子线程的运行的时候,采取消读动作。我不想每次都设置一个超时。 |
|
12楼#
发布于:2002-06-17 11:44
原来你异步调用方法错误,应该这样:
if(GetLastError()==ERROR_IO_PENDING) { if(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT) { CancelIO(hDevice); } GetOverlappedResult(hDevice, &ol, &nWriteBytes, FALSE); } |
|
|
13楼#
发布于:2002-06-17 11:40
“我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了。” 胡扯。 if(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT) { CancelIO(hDevice); } 怎么不行?!为什么我屡试不爽呢?! |
|
|
14楼#
发布于:2002-06-17 10:02
[quote]不过也还是不在同一个线程啊。 “我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了,而我如果在别的线程调用这个函数又没用,所以还是没有能解决问题。” 嘿嘿。。。。是在不同的线程中。。。。。。。。。 “在另外一个线程里面调用CancelIo也不行。” --------用此DuplicateHandle之,再在其他的线程中CancelIo,应该行的。。。。。。。。。。。 :) 可行与否,还望fracker兄明“试”。 :P [/quote] 试过了,如果不是我写得不对的话,我想这也行不通。 我试过在以下几种情况 1。在主线程中CreateFile,DuplicateHandle,然后将handle传到子线程,在子线程中ReadFile,最后在主线程中CancelIo那两个handle(分别CancelIo了一次,未遂)。 2。将主线程中的handle传到子线程中,在子线程中DuplicateHandle,然后在主线程中CancelIo,也未遂。 无心再试了,哪位能解决,给个例子,另外给分,本帖结账了。 |
|
15楼#
发布于:2002-06-17 09:54
you can do all wait and cancel in one thread. I think it is a way out, although I didn\'t try it. |
|
16楼#
发布于:2002-06-16 00:21
you can do all wait and cancel in one thread.
1. create event for asyn io 2. create event for cancel io. 3. ReadFile(Ex) in Asyn Mode. 4. WaitForMultiObject if finish event (for asyn io) fired, get data. if cancel io fired, you can cancel io now. notice. set waitformultiobject third para as FALSE. |
|
17楼#
发布于:2002-06-15 23:07
[quote]不过也还是不在同一个线程啊。 “我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了,而我如果在别的线程调用这个函数又没用,所以还是没有能解决问题。” 嘿嘿。。。。是在不同的线程中。。。。。。。。。 “在另外一个线程里面调用CancelIo也不行。” --------用此DuplicateHandle之,再在其他的线程中CancelIo,应该行的。。。。。。。。。。。 :) 可行与否,还望fracker兄明“试”。 :P [/quote] 谢谢关照,下周答复。 |
|
18楼#
发布于:2002-06-15 17:35
不过也还是不在同一个线程啊。 “我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了,而我如果在别的线程调用这个函数又没用,所以还是没有能解决问题。” 嘿嘿。。。。是在不同的线程中。。。。。。。。。 “在另外一个线程里面调用CancelIo也不行。” --------用此DuplicateHandle之,再在其他的线程中CancelIo,应该行的。。。。。。。。。。。 :) 可行与否,还望fracker兄明“试”。 :P |
|
|
19楼#
发布于:2002-06-15 01:38
不过也还是不在同一个线程啊。
|
|
上一页
下一页