Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

Driver created IRP's and CancelSynchronousIo

Bill_ZissimopoulosBill_Zissimopoulos Member Posts: 113

I have an FSD (file system driver and not filter driver) that responds to special FSCTL (IRP_MJ_FILE_SYSTEM_CONTROL) requests. The driver uses a variant of FsRtlCancellableWaitForSingleObject to perform a cancellable wait on a kernel object and the FSCTL IRP.

I now have a second driver that wishes to send an FSCTL IRP to the FSD and a requirement that this must be done in a manner so that CancelSynchronousIo is functional. My question is: how should I build the IRP so that it can be cancelled with CancelSynchronousIo?

At first I built the FSCTL IRP using IoAllocateIrp. This method does not create a threaded IRP and therefore cannot be canceled with CancelSynchronousIo. (There is IoQueueThreadIrp but it is reserved for system use.)

Now I am using IoBuildDeviceIoControlRequest and patch the returned IRP fields with IRP_MJ_FILE_SYSTEM_CONTROL/IRP_MN_KERNEL_CALL, etc. because IoBuildDeviceIoControlRequest creates IRP_MJ_DEVICE_CONTROL IRP's. This creates a threaded IRP (confirmed with !thread). Unfortunately CancelSynchronousIo still cannot cancel the IRP.

The problem is that although the internal IopCancelIrpsInCurrentThreadListSpecialApc finds the IRP in the thread's IrpList, the IRP is not marked IRP_SYNCHRONOUS_API and is therefore ignored. My obvious next move is to add that bit to Irp->Flags, but I am beginning to wonder if I should not be doing what I am doing.

I appreciate any advice you may have on the subject. If your advice is "don't do that" I would love to hear alternatives.

Bill

PS: I have wondered in the past how an IRP passed to FsRtlCancellableWaitForSingleObject can be cancelled if there is no cancellation routine on it. Turns out that IopCancelIrpsInCurrentThreadListSpecialApc first sets Irp->Cancel and then alerts the thread with KeAlertThread. This wakes up the alertable KeWaitForSingleObject inside FsRtlCancellableWaitForSingleObject, which then checks Irp->Cancel. Mystery solved.

Comments

  • Cecilia_wllCecilia_wll Member Posts: 13

    Perhaps you can set the IRP structure's member IoStatus.Status = STATUS_ACCESS_DENIED; that the IRP will be cancelled?
    I am not sure it's ok. Hope the idea can help you.

  • Bill_ZissimopoulosBill_Zissimopoulos Member Posts: 113

    @Cecilia_wll said:
    Perhaps you can set the IRP structure's member IoStatus.Status = STATUS_ACCESS_DENIED; that the IRP will be cancelled?
    I am not sure it's ok. Hope the idea can help you.

    Thanks for your response.

    My issue has to do more with whether it is a good idea to set the IRP_SYNCHRONOUS_API bit as I do not fully understand the implications of doing so. As I control both the FSD and the second driver that wishes to communicate with it, it is likely that my use is ok and I wanted to confirm this with the list.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,515

    In general, I'm not liking this whole design... which feels overly forced.

    WHY do you need to support, specifically, the Win32 function CancelSynchrnousIo? Heck, until you mentioned it, I had never even HEARD of it.

    Now, having SAID that... setting IRP_SYNCHRONOUS_API shouldn't cause any problems. It's merely a way to tell the file system that the request was issued from a "synchronous API" and the IRP must be processed synchronously (even if the FILE_OBJECT was not opened for synchronous access). This flag typically gets set for things like queries that are inherently synchronous, regardless of how the File Object was opened.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Bill_ZissimopoulosBill_Zissimopoulos Member Posts: 113

    Peter, thanks for your answer.

    WHY do you need to support, specifically, the Win32 function CancelSynchrnousIo? Heck, until you mentioned it, I had never even HEARD of it.

    In general I agree with you. CancelSynchronousIo is not my favorite API as it requires care to make it work right.

    In this case I am porting a user mode library from UNIX, which uses synchronous calls like read(2) and likes to pthread_cancel(3) a lot. On top of that my file system driver's special FSCTL's are all synchronous (they never return STATUS_PENDING) as they effectively implement a "GetNextQueueItem" from a queue.

    For these reasons I chose to implement pthread_cancel(3) in terms of CancelSynchronousIo (and some other machinery). It was the path of least resistance in this case and I do not like to overcomplicate things when I do not have to.

    setting IRP_SYNCHRONOUS_API shouldn't cause any problems

    Thanks for the confirmation. It does work indeed in my tests. But this is new software and my test suite is still small.

    I think the combination of using IoBuildDeviceIoControlRequest (to get a threaded IRP) and then patching the IRP to change MJ/MN function, adding a FileObject and setting the IRP_SYNCHRONOUS_API flag made me uneasy. I would much prefer the IoAllocateIrp route, but IoQueueThreadIrp is marked as "reserved for system use".

    Bill

  • Martin_DrábMartin_Dráb Member - All Emails Posts: 73

    Hello,

    ïf you wish to make an IRP cancel you need to set a cancellation routine for it (IoSetCancelRoutine). Basically, the routine is then invoked when the IRP is cancelled and you may complete it (usually with STATUS_CANCELLED).

    You may do this only for IRPs that are owned by your driver. If your driver sends an IRP to another driver you should again set its canel routine to NULL, thus making it not cancellable again.

    Martin Dráb

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Writing WDF Drivers 21 Oct 2019 OSR Seminar Space & ONLINE
Internals & Software Drivers 18 Nov 2019 Dulles, VA
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 27 Apr 2020 OSR Seminar Space & ONLINE