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

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

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

最新喜欢:

linwnlinwn
lms2000
驱动牛犊
驱动牛犊
  • 注册日期2001-05-19
  • 最后登录2018-05-30
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望102点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-06-14 16:54
试试
BOOL CancelIo(
  HANDLE hFile  // handle to file
);
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
板凳#
发布于:2002-06-14 17:13
The CancelIo function cancels all pending input and output (I/O) operations that were issued by the calling thread for the specified file handle. The function does not cancel I/O operations issued for the file handle by other threads.

这是MSDN里面的原话,从这段话看出,除非你在本线程内部调用这个函数,可以取消在该handle上的I/O操作,然而要注意的是,我是调用GetOverlappedResult,这个函数在没有数据的时候是阻塞的,我根本就得不到CPU的控制权,也就没有机会来调用CancelIo了,而我如果在别的线程调用这个函数又没用,所以还是没有能解决问题。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
地板#
发布于:2002-06-14 17:18
不过不清楚这段话的意思是不是可以在不同的线程取消同一个handle的I/O,还是每个线程里面只能取消本线程打开的handle.先试试再来。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
地下室#
发布于:2002-06-14 17:30
在另外一个线程里面调用CancelIo也不行。
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-06-14 17:35

高分啊。。。。。。。。

 :(
[color=red]大头鬼! :P[/color]
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-06-14 17:45
创建了一个驱动程序,我用CreateFile打开,用ReadFile从这个驱动程序中读取数据,当ReadFile返回错误,如果错误代码是ERROR_IO_PENDING的时候,我就用GetOverlappedResult来等待数据的到来。问题是,如果数据没来的时候,我想停止掉这个操作怎么办?我尝试过直接修改Overlap的Event, 但是这样的话,在最后CloseHandle的时候,时间好长,不知为何?那位高手解答一下。


The DuplicateHandle function duplicates an object handle.

BOOL DuplicateHandle(
  HANDLE hSourceProcessHandle,  // handle to the source process
  HANDLE hSourceHandle,         // handle to duplicate
  HANDLE hTargetProcessHandle,  // handle to process to duplicate to
  LPHANDLE lpTargetHandle,  // pointer to duplicate handle
  DWORD dwDesiredAccess,    // access for duplicate handle
  BOOL bInheritHandle,      // handle inheritance flag
  DWORD dwOptions           // optional actions
);

fracker 兄:

用此法,再结合lms2000兄的BOOL CancelIo( HANDLE hFile // handle to file
);

试试。。。。。。。。。。。。


 :)
[color=red]大头鬼! :P[/color]
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
7楼#
发布于:2002-06-15 01:37
[quote]创建了一个驱动程序,我用CreateFile打开,用ReadFile从这个驱动程序中读取数据,当ReadFile返回错误,如果错误代码是ERROR_IO_PENDING的时候,我就用GetOverlappedResult来等待数据的到来。问题是,如果数据没来的时候,我想停止掉这个操作怎么办?我尝试过直接修改Overlap的Event, 但是这样的话,在最后CloseHandle的时候,时间好长,不知为何?那位高手解答一下。


The DuplicateHandle function duplicates an object handle.

BOOL DuplicateHandle(
  HANDLE hSourceProcessHandle,  // handle to the source process
  HANDLE hSourceHandle,         // handle to duplicate
  HANDLE hTargetProcessHandle,  // handle to process to duplicate to
  LPHANDLE lpTargetHandle,  // pointer to duplicate handle
  DWORD dwDesiredAccess,    // access for duplicate handle
  BOOL bInheritHandle,      // handle inheritance flag
  DWORD dwOptions           // optional actions
);

fracker 兄:

用此法,再结合lms2000兄的BOOL CancelIo( HANDLE hFile // handle to file
);

试试。。。。。。。。。。。。


 :) [/quote]

好点子,这两天休息,下周一再来试。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
8楼#
发布于:2002-06-15 01:38
不过也还是不在同一个线程啊。
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于: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分
  • 社区居民
10楼#
发布于:2002-06-15 23:07
[quote]不过也还是不在同一个线程啊。


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

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

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

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

:)

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


 :P [/quote]

谢谢关照,下周答复。

zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于: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分
  • 社区居民
12楼#
发布于: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.
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
13楼#
发布于: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,也未遂。

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

返回顶部