Search code examples
windowsoperating-systemiodriverdevice-driver

Can synchronous I/O be canceled automatically even if the driver doesn't complete irp?


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?


Solution

  • 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.