fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
阅读:4554回复:26

怎么在应用层取消Overlap的ReadFile动作?100分!

楼主#
更多 发布于:2002-06-14 12:30
创建了一个驱动程序,我用CreateFile打开,用ReadFile从这个驱动程序中读取数据,当ReadFile返回错误,如果错误代码是ERROR_IO_PENDING的时候,我就用GetOverlappedResult来等待数据的到来。问题是,如果数据没来的时候,我想停止掉这个操作怎么办?我尝试过直接修改Overlap的Event, 但是这样的话,在最后CloseHandle的时候,时间好长,不知为何?那位高手解答一下。

最新喜欢:

linwnlinwn
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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.版主能不能解释为何.
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-08-04 10:43
谢谢.
      不错,ReadFile()传给下层IoCallDriver()后.是返回STATUS_PENDING.
      另外.我想取消pending的IRP可以用DeviceIoControl(),在驱动程序中.增加相应的代码.取消所有暂停的IRP.是否可行自己打了个问寒问号?因为DeviceIoControl()是对控制端点操作的.(我自己试的是这样,不知道别人的如何?)
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-08-04 09:54
下面是引用tianrongcai于2005-08-03 16:25发表的:
不知道何原因?按照15楼的方法就是可以正常退出,驱动程序不改变.


可能是你的irp已经交给下层处理,下层返回pending的,你取消irp的时候,取消irp也由下层处理,
所以你的驱动程序就不用改变了阿
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-08-03 16:25
不知道何原因?按照15楼的方法就是可以正常退出,驱动程序不改变.
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
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都没有发现该入口可加入.
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
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()入口吧.
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
7楼#
发布于:2002-06-17 12:38
哦,明白,我重开一贴,你来领分吧。
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-06-17 12:33
驱动中
IoMarkIrpPending(Irp);
IoSetCancelRoutine(Irp,CancelIrpRoutine);设置Cancel例程。在应用中调用CancelIO时,CancelIrpRoutine会由系统调用。
VOID CancelIrpRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
9楼#
发布于:2002-06-17 12:16
对了,CancelIo的时候,驱动程序里面会得到什么响应?我在驱动程序里面做了一个Pending Irp的队列,把Irp的指针保存起来了,Cancel的时候我应该把他们删除掉啊。
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-06-17 12:10
那就while(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT)
{
if(m_Cancel)
{
CancelIO(hDevice);
break;
}
}
然后在主线程要退出或者想停止子线程的运行的时候m_Cancel = TRUE;
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
11楼#
发布于:2002-06-17 12:02
[quote] “我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了。”

胡扯。
if(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT)
{
     CancelIO(hDevice);  
}
怎么不行?!为什么我屡试不爽呢?! [/quote]

不用试我也知道你这种做法能行,但我的情形跟你不大一样。我的读动作是在一个线程里面,只有当主线程要退出或者想停止子线程的运行的时候,采取消读动作。我不想每次都设置一个超时。
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-06-17 11:44
原来你异步调用方法错误,应该这样:
if(GetLastError()==ERROR_IO_PENDING)
{
if(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT)
{
CancelIO(hDevice);
}
GetOverlappedResult(hDevice, &ol, &nWriteBytes, FALSE);
}
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-06-17 11:40
“我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了。”

胡扯。
if(WaitForSingleObject(FileIOWaiter, 100)==WAIT_TIMEOUT)
{
     CancelIO(hDevice);  
}
怎么不行?!为什么我屡试不爽呢?!
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
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,也未遂。

无心再试了,哪位能解决,给个例子,另外给分,本帖结账了。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
15楼#
发布于:2002-06-17 09:54
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.
 


I think it is a way out, although I didn\'t try it.
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
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.
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
17楼#
发布于:2002-06-15 23:07
[quote]不过也还是不在同一个线程啊。


“我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了,而我如果在别的线程调用这个函数又没用,所以还是没有能解决问题。”

嘿嘿。。。。是在不同的线程中。。。。。。。。。

“在另外一个线程里面调用CancelIo也不行。”

--------用此DuplicateHandle之,再在其他的线程中CancelIo,应该行的。。。。。。。。。。。

:)

可行与否,还望fracker兄明“试”。


 :P [/quote]

谢谢关照,下周答复。

magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-06-15 17:35
不过也还是不在同一个线程啊。


“我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了,而我如果在别的线程调用这个函数又没用,所以还是没有能解决问题。”

嘿嘿。。。。是在不同的线程中。。。。。。。。。

“在另外一个线程里面调用CancelIo也不行。”

--------用此DuplicateHandle之,再在其他的线程中CancelIo,应该行的。。。。。。。。。。。

:)

可行与否,还望fracker兄明“试”。


 :P
[color=red]大头鬼! :P[/color]
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
19楼#
发布于:2002-06-15 01:38
不过也还是不在同一个线程啊。
上一页
游客

返回顶部