即使驱动程序没有完成irp,同步I/O是否可以自动取消?

发布于 2024-10-17 10:08:51 字数 424 浏览 12 评论 0原文

在用户模式代码中:

CreateFile(A device);
ReadFile(The device handle); // synchronously

在相应驱动程序的 IRP_MJ_READ 调度例程中:

// To hold the irp. It will never complete the irp.
// This driver doesn't even have a cancel routine.
Sleep(INFINITE); 

当我在执行 ReadFile() 之后强制终止用户模式应用程序时,可以取消 I/O 吗?
如果是异步 I/O,则应用程序无法终止。
但是如果 I/O 是同步的,I/O 管理器会自动取消它吗?

如果是这样,怎么办?

In user mode code:

CreateFile(A device);
ReadFile(The device handle); // synchronously

In correspond driver's IRP_MJ_READ dispatch routine:

// To hold the irp. It will never complete the irp.
// This driver doesn't even have a cancel routine.
Sleep(INFINITE); 

When I terminate the user mode app forcedly after do ReadFile(), can the I/O be canceled?
If it was asynchronous I/O, the app couldn't be terminated.
But if I/O is synchronous, does I/O manager cancel it automatically?

If so, how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三寸金莲 2024-10-24 10:08:51

首先,异步和同步 I/O 都是通过 IRP 实现的。用户模式 ​​API ReadFile 调用内部 NT API(系统调用)NtReadFile,最终发送 IRP。如果驱动程序返回 STATUS_PENDING,NT API 将返回相同的状态。如果用户模式应用程序对 ReadFile 进行同步调用,ReadFile 将等待文件句柄以等待 I/O 完成。驱动程序还可以同步完成 IRP(无论用户模式 ​​API 的调用方式如何)。我认为这就是您感兴趣的情况。IRP

与发送它们的线程相关联。因此,当线程终止时(例如由于终止进程),I/O 管理器会尝试取消与该线程关联的所有 IRP。在所有 IRP 完成之前,线程无法终止。

当关闭句柄时,I/O 管理器会向驱动程序发送 IRP_MJ_CLEANUP 和 IRP_MJ_CLOSE。在这种情况下,是驱动程序取消挂起的IRP(或者只是以取消的方式完成它们)。

取消 IRP 的能力取决于驱动程序的配合。驱动程序必须通过调用 IoSetCancelRoutine。

如果驱动程序只是阻塞而不使 IRP 可取消,则 IRP 将不会被取消。

First, both both asynchronous and synchronous I/O are implemented with IRPs. The user-mode API ReadFile calls an internal NT API (system call) NtReadFile which ends up sending an IRP. If the driver returns STATUS_PENDING, the NT API will return same status. If the user-mode application makes a synchronous call to ReadFile, ReadFile will wait on the file handle for the I/O to complete. The driver can also complete the IRP synchronously (regardless of the way the user-mode API is called). I think that this is the case you are interested in.

IRPs are associated with the thread that sent them. So when a thread is terminated (for example due to killing the process), the I/O manager attempts to cancel all the IRPs that are associated with that thread. The thread cannot terminate until all the IRPs are completed.

When you close a handle, the I/O manager sends the driver IRP_MJ_CLEANUP, and IRP_MJ_CLOSE. It is the driver that cancels pending IRPs (or just completes them as canceled) in this case.

The ability to cancel an IRP depends on the cooperation of the driver. The driver must explicitly make the IRP cancelable by calling IoSetCancelRoutine.

If the driver just blocks without making the IRP cancelable, the IRP will not get canceled.

剧终人散尽 2024-10-24 10:08:51

在 Vista 及更高版本上,您可以使用 CancelSynchronousIo 将线程的所有挂起 IO 标记为已取消。 NtCancelIoFile可用于取消IO对于特定文件。 (免责声明:我还没有实际测试过这个函数)

这些调用的效果会有所不同,具体取决于驱动程序实现。

从用户模式应用程序来看,效果应该是立即取消,即使驱动程序可能会等待很长时间才能完全清除 IO 请求。

MSDN:I/O 完成/取消指南

On Vista and up, you can use CancelSynchronousIo to mark all pending IO for a thread as canceled. NtCancelIoFile can be used to cancel IO for a specific file. (disclaimer: I haven't actually tested this function)

The effects of these calls will vary, depending a.o. on the driver implementation.

Seen from the user mode application, the effect should be an immediate cancellation, even though the driver may keep waiting for a long time before the IO request is completely cleaned up.

MSDN: I/O Completion/Cancellation Guidelines ???? has a lot of information on cancellation:

I/O Completion/Cancellation Guidelines

The following are guidelines that all drivers that are shipped with or
intended to be used with Windows Vista and Windows Server 2008 should
adhere to.

Drivers written for previous versions of Windows may not automatically
satisfy these guidelines due to an important change for Windows Vista
and Windows Server 2008, namely support for cancellation of
IRP_MJ_CREATE IRPs.

Use of the Windows Driver Foundation or Cancel-Safe IRP Queues library
is strongly recommended, because they automatically implement these
guidelines.

Definitions

Reasonable period means here less than 10 seconds for most operations and their cancellations. This time is derived from a user's
tolerance to delays when closing an application or canceling an I/O
operation that the user perceives is taking too long. It should be
much shorter for most operations. There may also be legitimate reasons
for it to be longer for some types of devices and/or operations.

IRPs are issued by the I/O Manager on behalf of a user-mode application.

Long-term IRPs are IRPs that take more than a reasonable period to complete.

Pend means a driver should return STATUS_PENDING and mark the IRP pending.

Guidelines

  • All IRPs (including Create) that can take an indefinite amount of time must be able to be cancelled. These are waits that block on
    user-initiated events, for example named pipes or waiting for keyboard
    input.
  • Close-IRPs should never block for more than a reasonable period.
  • All long-term IRPs should be pended. Drivers should not block a user-mode thread (for example, to acquire a mutex) inside its dispatch
    routine for more than a reasonable period.
  • Whenever a driver pends an IRP, including Create, it must either:
  • Support IRP cancellation; or
  • Complete the operation within a reasonable period. This may require implementing time-outs. The only exception is for hardware that is
    malfunctioning.
  • If a driver creates new IRPs that are passed to other drivers, then it must pass on cancellation or be able to disassociate these IRPs
    from the original IRP issued by the I/O Manager.
  • All IRPs should be completed in a reasonable period once canceled. A driver that is about to complete an IRP for anything other than the
    current thread must be suspension-proof. The only exceptions are
    delays that are caused by hardware that is malfunctioning. If the
    hardware is likely to malfunction frequently, then the driver should
    have sufficient recovery mechanisms to complete the IRP in a
    reasonable period.
  • A driver should never pend a canceled IRP.
  • Drivers should not have any path that would miss a cancellation unless the IRP will be completed shortly anyway (code just has to run
    forward).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文