IoCompleteRequest or not?

Dear all,

I’ve been looking for information on the Internet on whether a driver that handles an Irp synchronously SHOULD or SHOULD NOT call IoCompleteRequest on it before returning (with a result OTHER THAN STATUS_PENDING).

I’ve found http://technologeeks.com/Courses/Windows%20Kernel%20-%20Excerpt.pdf which seems to indicate it SHOULD NOT call IoCompleteRequest, but then the post of Scott Noone in https://www.osronline.com/showthread.cfm?link=243753 seems to indicate it SHOULD.

My problem with the latter is that calling IoCompleteRequest causes an Apc to be queued (even if the call was handled synchronously as far as I can see). If the caller was holding a guarded mutex (thereby blocking Apc handling) when doing a call to IoCallDriver with an Ipc without completion-routine, but with a PKEVENT, then:

  1. The driver executes what it needs to do and then calls IoCompleteRequest (which queues an Apc that would call IopCompleteRequest) - but because of the mutex, the Apc is held back - and then returns a status OTHER THAN STATUS_PENDING.
  2. The IoCallDriver call returns and the caller then frees the event it created for waiting on in case of async handling (not needed here), its IO_STATUS_BLOCK and anything else it needed for the call, since it thinks the call was fully executed.
  3. At some point the caller releases the guarded mutex it was holding and then Windows triggers the Apc, but the resulting execution of IopCompleteRequest then tries to access stuff (event & IO_STATUS_BLOCK) which just isn’t there anymore, sometimes causing a pagefault.

The same also happens if the caller would be holding a spinlock i.s.o. a guarded mutex and although I cannot go into the details, we really need synchronization here. As far as I can tell from the IoCallDriver documentation of MS it should be OK to call it at IRQL <= DISPATCH_LEVEL, so …

If I don’t do the IoCompleteRequest call in the lower driver when completing the request synchronously (which is actually always the case), then the problem isn’t seen, but it bothers me that I cannot find conclusive documentation on whether that’s the correct approach or not. Can someone clear this up and indicate how to then address the problem above?

Thanks,
K

Yes, you definitely need to call IoCompleteRequest on a request that is
completed synchronously.

IoCompleteRequest only queues an APC if the driver at the top of the I/O
stack calls IoMarkIrpPending. If this driver called IoMarkIrpPending then it
must also return STATUS_PENDING.

If the driver is going to return anything other than STATUS_PENDING then it
must not call IoMarkIrpPending. If it calls IoMarkIrpPending and returns a
non-pending status then you get the (incorrect) behavior that you’ve
described below.

Does your driver pass Driver Verifier? It should catch this.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Dear all,

I’ve been looking for information on the Internet on whether a driver that
handles an Irp synchronously SHOULD or SHOULD NOT call IoCompleteRequest on
it before returning (with a result OTHER THAN STATUS_PENDING).

I’ve found
http://technologeeks.com/Courses/Windows%20Kernel%20-%20Excerpt.pdf which
seems to indicate it SHOULD NOT call IoCompleteRequest, but then the post of
Scott Noone in https://www.osronline.com/showthread.cfm?link=243753 seems to
indicate it SHOULD.

My problem with the latter is that calling IoCompleteRequest causes an Apc
to be queued (even if the call was handled synchronously as far as I can
see). If the caller was holding a guarded mutex (thereby blocking Apc
handling) when doing a call to IoCallDriver with an Ipc without
completion-routine, but with a PKEVENT, then:

  1. The driver executes what it needs to do and then calls IoCompleteRequest
    (which queues an Apc that would call IopCompleteRequest) - but because of
    the mutex, the Apc is held back - and then returns a status OTHER THAN
    STATUS_PENDING.
  2. The IoCallDriver call returns and the caller then frees the event it
    created for waiting on in case of async handling (not needed here), its
    IO_STATUS_BLOCK and anything else it needed for the call, since it thinks
    the call was fully executed.
  3. At some point the caller releases the guarded mutex it was holding and
    then Windows triggers the Apc, but the resulting execution of
    IopCompleteRequest then tries to access stuff (event & IO_STATUS_BLOCK)
    which just isn’t there anymore, sometimes causing a pagefault.

The same also happens if the caller would be holding a spinlock i.s.o. a
guarded mutex and although I cannot go into the details, we really need
synchronization here. As far as I can tell from the IoCallDriver
documentation of MS it should be OK to call it at IRQL <= DISPATCH_LEVEL, so

If I don’t do the IoCompleteRequest call in the lower driver when completing
the request synchronously (which is actually always the case), then the
problem isn’t seen, but it bothers me that I cannot find conclusive
documentation on whether that’s the correct approach or not. Can someone
clear this up and indicate how to then address the problem above?

Thanks,
K

It is important to understand that IRQL and APC delivery state depends on a driver interface you are calling. For example you can hardly find a file system driver that is able to process IRP_MJ_READ at DISPATCH_LEVEL.

Some notes on IRP completion:

  1. You must call IoCompleteRequest if your driver finished with IRP and is not going to pass it further .

  2. If you do not call IoCompleteRequests the IRP will never be freed and completion routines will never be called. The IRP will be in the system forever and some drivers might wait for its completion indefinitely.

  3. APC is scheduled inside IoCompleteRequest independent of whether IRP is synchronous or not if a caller doesn’t set IRP_DEFER_IO_COMPLETION flag. This flag means that a caller will call APC routine as a normal routine if IoCallDriver returns anything except STATUS_PENDING. This option is not available for third party drivers that allocate and initialize IRP instead calling Nt/Zw* routines.

  4. A synchronous IRP can be completed in a context different from a caller’s thread. For example a driver waits in a dispatch routine for an event set by a worker thread that calls IoCompleteRequest for synchronous IRP. Synchronous means that a driver doesn’t return from a dispatch routine before a call to IoCompleteRequest returns. In that case either APC completes the job or a caller calls APC routine after IoCallDriver returns( see IRP_DEFER_IO_COMPLETION case ).

  5. You can call IoCallDriver and IoCompleteRequest at IRQL<= DISPATCH_LEVEL or with disabled APC delivery if a driver interface allows this. You must understand that you might receive APC asynchronously and adjust the code accordingly. One of the options for IRP originator is to set a completion routine that returns STATUS_MORE_PROCESSING_REQUIRED and then (or before ) freeing IRP and its resources.

Hi guys,

First of all thanks for your quick responses.

@Scott, no the involved drivers do not pass Driver Verifier tests at the moment. Most of it is “inherited” code and we’re trying to get it to pass running with the Driver Verifier on, but the pagefault triggered by the Apc (so with the IoCompleteRequest still in) is one of the things blocking that.

However, your statement “IoCompleteRequest only queues an APC if the driver at the top of the I/O
stack calls IoMarkIrpPending” is not backed by my findings. As also mentioned by Slava, I notice IoCompleteRequest always schedules an APC, even though our driver did not call IoMarkIrpPending and did NOT return STATUS_PENDING.

The problem is probably in the caller. It uses the following type of code (left out some details and the actual IOCTL called can simply be setting the Irp->IoStatus.Status, calling IoCompleteRequest and returning the same NON-PENDING status):

{
KEVENT event;
IO_STATUS_BLOCK ios;
char buf[INBUF_SIZE]; // Filled in somehow before the call.
KeInitializeEvent(&event,NotificationEvent,FALSE);
PIRP pIrp = IoBuildDeviceIoControlRequest((ULONG)IOCTL_OUR_TEST,pDevObj,
buf,sizeof(buf),NULL,0,TRUE,&event,&ios);
NTSTATUS status = IoCallDriver(pDevObj,pIrp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
status = ios.Status;
}
}

IOCTL_OUR_TEST is something like CTL_CODE(…,…,METHOD_OUT_DIRECT,FILE_ANY_ACCESS).

If this type of code is used while holding a mutex or @ DPC, the call to IoCallDriver will trigger an IoCompleteRequest which queues mentioned APC, but that one only gets executed after the stack-frame on which “event”, “ios” and “buf” reside is already removed (and possibly its page unmapped). The APC executing IopCompleteRequest however still references those (in case of unmapped page now giving a pagefault @ DPC).

So, what would be the better way to do this type of IoCallDriver call which in the driver is executed synchronously? I guess creating the KEVENT, IO_STATUS_BLOCK and buffer (extra problem as this buffer in the real case comes from the stack-frame of the caller of this code) on the heap would be an option, but then when to free them? Always waiting for the event would probably cause a dead-lock (as the event would be signaled by the APC, which cannot run due to the held mutex). It is unclear to me at the moment whether adding a completion routine would suffer from the same deadlock or would be called before the APC (if so, freeing stuff there would still be too early for the APC).

@Slava, your mention of IRP_DEFER_IO_COMPLETION sounds interesting, but is there some way the above code could use that?

Thanks, K.

The problem here is that IoBuildDeviceIoControlRequest is used to build the IRP. This function makes an IRP which is bound to a current thread( literally it is in the thread’s IRP list ) and only the completion APC routine can unbound it from the thread. You can’t avoid queuing or calling APC routine for this case. The completion APC code is required to be executed here.

The workaround is to build an IRP with a call to IoAllocateIrp() and initializing required IRP fields to values expected by a driver called in IoCallDriver. To avoid APC queuing you will set a completion routine that returns STATUS_MORE_PROCESSING_REQUIRED and then release IRP and all buffers, MDLs allocated when it was initialized. You can also release the IRP inside a completion routine before returning STATUS_MORE_PROCESSING_REQUIRED.

A completion routine is called before queuing the completion APC and if a completion routine returns STATUS_MORE_PROCESSING_REQUIRED the completion APC is not queued.

You can set the IRP_DEFER_IO_COMPLETION flag and release IRP after IoCallDriver returns. With one exception - if STATUS_PENDING is returned by IoCallDriver the completion APC will be(or have been) used to complete the Irp. IRP_DEFER_IO_COMPLETION is reserved for the system use so it is better to refrain from using it.

Hi Slava,

Having to construct the IRP myself seem pretty tricky - several sources on the net indicate that. I also notice that the mechanism used here is also used by other code found on the Internet (ex. https://github.com/Microsoft/Windows-driver-samples/blob/master/storage/class/cdrom/src/zpodd.c#L628 ). Are those programmers than also in for a surprise?

Thanks,
Kurt

If somebody calls this routine(DeviceZPODDGetPowerupReason) with special kernel mode APCs disabled he will get a corrupted stack. This routine implies that special kernel mode APCs are enabled.

Aha. I missed that this was a driver generated IRP and not an IRP from user mode.

As Slava noted this is a bug in the caller, that particular I/O routine is notorious for causing this type of issue for people due. If you’re going to call it like this you need to make sure that you’re running at PASSIVE_LEVEL and not in a Guarded Region so the APC can be delivered before the stack frame unwinds.

If you’re going to do this at IRQL <= APC_LEVEL you can use IoBuildAsynchronousFsdRequest for an almost drop in replacement (the fact that it has Fsd in the name is misleading, any driver can use it). This does not queue the IRP to the thread so you won’t get the APC.

If you’re at DISPATCH_LEVEL you need to build the IRP by hand and set a completion routine that returns STATUS_MORE_PROCESSING_REQUIRED. It’s not hard and it’s going to be required for correctness anyway. It’s barely that much more code in the end.

-scott

Hi Scott,

So bottom-line: no IoBuildDeviceIoControlRequest while holding a GUARDED_MUTEX or being at IRQL > APC_LEVEL, right? All of the calls to this code should be a PASSIVE level in our case, so in principle I could give IoBuildAsynchronousFsdRequest a try, but … Asynchronous? Should that not by synchronous? …

Thanks, K.

No calls at >= APC_LEVEL (e.g. holding a FAST_MUTEX).

FWIW you can confirm that the environment is right for this API by checking
that KeAreAllApcsDisabled returns FALSE.

Ignore the name. It just builds a non-threaded IRP that you can use however
you like (i.e. if you block and wait you’ll make it synchronous). Here’s an
example:

https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/verfysup.c#L967

You’d also need to fill in the arguments to the next I/O stack location for
the device control.

Alternatively, if you want the hand built route there’s a pretty clear
example here:

https://github.com/Microsoft/Windows-driver-samples/blob/master/storage/class/disk/src/geometry.c#L1028

Pretty much the only difference is that the IoBuildXxx routine will do
something initialization for you that the IoAllocateIrp version won’t.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Hi Scott,

So bottom-line: no IoBuildDeviceIoControlRequest while holding a
GUARDED_MUTEX or being at IRQL > APC_LEVEL, right? All of the calls to
this code should be a PASSIVE level in our case, so in principle I could
give IoBuildAsynchronousFsdRequest a try, but … Asynchronous? Should that
not by synchronous? …

Thanks, K.

Hey Guys,

Again thanks for all the support. I ended up taking (what I hope is) the easy way out: instead of a GUARDED_MUTEX, I just changed the synchronization at the higher level over to use a KMUTEX. I assume that does not cause blocking of APCs or raising of the IRQL, correct? As mentioned, in our case the stuff being synchronized is always running at IRQL == PASSIVE, so the GUARDED_MUTEX was just in an attempt to be more efficient which backfired …

Kind regards, K

Yup, that works.

I’d also add an:

ASSERT(KeAreAllApcsDisabled() == FALSE);

At the top of your function to save yourself in the future.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Hey Guys,

Again thanks for all the support. I ended up taking (what I hope is) the
easy way out: instead of a GUARDED_MUTEX, I just changed the synchronization
at the higher level over to use a KMUTEX. I assume that does not cause
blocking of APCs or raising of the IRQL, correct? As mentioned, in our case
the stuff being synchronized is always running at IRQL == PASSIVE, so the
GUARDED_MUTEX was just in an attempt to be more efficient which backfired

Kind regards, K

Just because you sync with the completion handler does not necessarily mean
you do or don’t complete the request. If you return STATUS_MPR, in the
completion handler, then yes, you must complete. If you return
STATUS_SUCCESS then you do not.

On Tue, Apr 25, 2017, 1:29 PM Scott Noone wrote:

> Yup, that works.
>
> I’d also add an:
>
> ASSERT(KeAreAllApcsDisabled() == FALSE);
>
> At the top of your function to save yourself in the future.
>
> -scott
> OSR
> @OSRDrivers
>
> wrote in message news:xxxxx@ntfsd…
>
> Hey Guys,
>
> Again thanks for all the support. I ended up taking (what I hope is) the
> easy way out: instead of a GUARDED_MUTEX, I just changed the
> synchronization
> at the higher level over to use a KMUTEX. I assume that does not cause
> blocking of APCs or raising of the IRQL, correct? As mentioned, in our
> case
> the stuff being synchronized is always running at IRQL == PASSIVE, so the
> GUARDED_MUTEX was just in an attempt to be more efficient which backfired
> …
>
> Kind regards, K
>
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

I’m having trouble imagining a legitimate case where you force the
dispatching of the IRP to be synchronous but you allow the completion
processing to be asynchronous. Can you provide a case where you think this
would be valid?

-scott
OSR
@OSRDrivers

“Jamey Kirby” wrote in message news:xxxxx@ntfsd…

Just because you sync with the completion handler does not necessarily mean
you do or don’t complete the request. If you return STATUS_MPR, in the
completion handler, then yes, you must complete. If you return
STATUS_SUCCESS then you do not.

On Tue, Apr 25, 2017, 1:29 PM Scott Noone wrote:
Yup, that works.

I’d also add an:

ASSERT(KeAreAllApcsDisabled() == FALSE);

At the top of your function to save yourself in the future.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Hey Guys,

Again thanks for all the support. I ended up taking (what I hope is) the
easy way out: instead of a GUARDED_MUTEX, I just changed the synchronization
at the higher level over to use a KMUTEX. I assume that does not cause
blocking of APCs or raising of the IRQL, correct? As mentioned, in our case
the stuff being synchronized is always running at IRQL == PASSIVE, so the
GUARDED_MUTEX was just in an attempt to be more efficient which backfired


Kind regards, K


NTFSD is sponsored by OSR

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:>

If I want to know when a request completes inline without holding up
completion.

On Fri, Apr 28, 2017, 10:19 AM Scott Noone wrote:

> I’m having trouble imagining a legitimate case where you force the
> dispatching of the IRP to be synchronous but you allow the completion
> processing to be asynchronous. Can you provide a case where you think this
> would be valid?
>
> -scott
> OSR
> @OSRDrivers
>
> “Jamey Kirby” wrote in message news:xxxxx@ntfsd.
> …
>
> Just because you sync with the completion handler does not necessarily mean
> you do or don’t complete the request. If you return STATUS_MPR, in the
> completion handler, then yes, you must complete. If you return
> STATUS_SUCCESS then you do not.
>
>
>
> On Tue, Apr 25, 2017, 1:29 PM Scott Noone wrote:
> Yup, that works.
>
> I’d also add an:
>
> ASSERT(KeAreAllApcsDisabled() == FALSE);
>
> At the top of your function to save yourself in the future.
>
> -scott
> OSR
> @OSRDrivers
>
> wrote in message news:xxxxx@ntfsd…
>
> Hey Guys,
>
> Again thanks for all the support. I ended up taking (what I hope is) the
> easy way out: instead of a GUARDED_MUTEX, I just changed the
> synchronization
> at the higher level over to use a KMUTEX. I assume that does not cause
> blocking of APCs or raising of the IRQL, correct? As mentioned, in our
> case
> the stuff being synchronized is always running at IRQL == PASSIVE, so the
> GUARDED_MUTEX was just in an attempt to be more efficient which backfired
> …
>
> Kind regards, K
>
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:></http:>

If I want to truly wait, I’d call ioforwardirpsynchronously

On Fri, Apr 28, 2017, 10:46 PM Jamey Kirby wrote:

> If I want to know when a request completes inline without holding up
> completion.
>
> On Fri, Apr 28, 2017, 10:19 AM Scott Noone wrote:
>
>> I’m having trouble imagining a legitimate case where you force the
>> dispatching of the IRP to be synchronous but you allow the completion
>> processing to be asynchronous. Can you provide a case where you think this
>> would be valid?
>>
>> -scott
>> OSR
>> @OSRDrivers
>>
>> “Jamey Kirby” wrote in message news:xxxxx@ntfsd.
>> …
>>
>> Just because you sync with the completion handler does not necessarily
>> mean
>> you do or don’t complete the request. If you return STATUS_MPR, in the
>> completion handler, then yes, you must complete. If you return
>> STATUS_SUCCESS then you do not.
>>
>>
>>
>> On Tue, Apr 25, 2017, 1:29 PM Scott Noone wrote:
>> Yup, that works.
>>
>> I’d also add an:
>>
>> ASSERT(KeAreAllApcsDisabled() == FALSE);
>>
>> At the top of your function to save yourself in the future.
>>
>> -scott
>> OSR
>> @OSRDrivers
>>
>> wrote in message news:xxxxx@ntfsd…
>>
>> Hey Guys,
>>
>> Again thanks for all the support. I ended up taking (what I hope is) the
>> easy way out: instead of a GUARDED_MUTEX, I just changed the
>> synchronization
>> at the higher level over to use a KMUTEX. I assume that does not cause
>> blocking of APCs or raising of the IRQL, correct? As mentioned, in our
>> case
>> the stuff being synchronized is always running at IRQL == PASSIVE, so the
>> GUARDED_MUTEX was just in an attempt to be more efficient which backfired
>> …
>>
>> Kind regards, K
>>
>>
>>
>> —
>> NTFSD is sponsored by OSR
>>
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software
>> drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http:
>>
>>
>> —
>> NTFSD is sponsored by OSR
>>
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
></http:></http:></http:>

Always found IoForwardIrpSynchronously to be incredibly annoying. Between
checking the return value and needing a current IRP stack location I just
end up rolling my own. IoSynchronousCallDriver would be much better but it’s
Win8+ only.

-scott
OSR
@OSRDrivers

“Jamey Kirby” wrote in message news:xxxxx@ntfsd…

If I want to truly wait, I’d call ioforwardirpsynchronously

On Fri, Apr 28, 2017, 10:46 PM Jamey Kirby wrote:

If I want to know when a request completes inline without holding up
completion.

On Fri, Apr 28, 2017, 10:19 AM Scott Noone wrote:
I’m having trouble imagining a legitimate case where you force the
dispatching of the IRP to be synchronous but you allow the completion
processing to be asynchronous. Can you provide a case where you think this
would be valid?

-scott
OSR
@OSRDrivers

“Jamey Kirby” wrote in message news:xxxxx@ntfsd…

Just because you sync with the completion handler does not necessarily mean
you do or don’t complete the request. If you return STATUS_MPR, in the
completion handler, then yes, you must complete. If you return
STATUS_SUCCESS then you do not.

On Tue, Apr 25, 2017, 1:29 PM Scott Noone wrote:
Yup, that works.

I’d also add an:

ASSERT(KeAreAllApcsDisabled() == FALSE);

At the top of your function to save yourself in the future.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Hey Guys,

Again thanks for all the support. I ended up taking (what I hope is) the
easy way out: instead of a GUARDED_MUTEX, I just changed the synchronization
at the higher level over to use a KMUTEX. I assume that does not cause
blocking of APCs or raising of the IRQL, correct? As mentioned, in our case
the stuff being synchronized is always running at IRQL == PASSIVE, so the
GUARDED_MUTEX was just in an attempt to be more efficient which backfired


Kind regards, K


NTFSD is sponsored by OSR

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:


NTFSD is sponsored by OSR

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:></http:>

I agree that it is a bit uncomfortable to use at first.

On Tue, May 2, 2017 at 9:10 AM Scott Noone wrote:

>
> Always found IoForwardIrpSynchronously to be incredibly annoying. Between
> checking the return value and needing a current IRP stack location I just
> end up rolling my own. IoSynchronousCallDriver would be much better but
> it’s
> Win8+ only.
>
> -scott
> OSR
> @OSRDrivers
>
> “Jamey Kirby” wrote in message news:xxxxx@ntfsd.
> …
>
> If I want to truly wait, I’d call ioforwardirpsynchronously
>
>
>
> On Fri, Apr 28, 2017, 10:46 PM Jamey Kirby wrote:
>
>
> If I want to know when a request completes inline without holding up
> completion.
>
>
>
> On Fri, Apr 28, 2017, 10:19 AM Scott Noone wrote:
> I’m having trouble imagining a legitimate case where you force the
> dispatching of the IRP to be synchronous but you allow the completion
> processing to be asynchronous. Can you provide a case where you think this
> would be valid?
>
> -scott
> OSR
> @OSRDrivers
>
> “Jamey Kirby” wrote in message news:xxxxx@ntfsd.
> …
>
> Just because you sync with the completion handler does not necessarily mean
> you do or don’t complete the request. If you return STATUS_MPR, in the
> completion handler, then yes, you must complete. If you return
> STATUS_SUCCESS then you do not.
>
>
>
> On Tue, Apr 25, 2017, 1:29 PM Scott Noone wrote:
> Yup, that works.
>
> I’d also add an:
>
> ASSERT(KeAreAllApcsDisabled() == FALSE);
>
> At the top of your function to save yourself in the future.
>
> -scott
> OSR
> @OSRDrivers
>
> wrote in message news:xxxxx@ntfsd…
>
> Hey Guys,
>
> Again thanks for all the support. I ended up taking (what I hope is) the
> easy way out: instead of a GUARDED_MUTEX, I just changed the
> synchronization
> at the higher level over to use a KMUTEX. I assume that does not cause
> blocking of APCs or raising of the IRQL, correct? As mentioned, in our
> case
> the stuff being synchronized is always running at IRQL == PASSIVE, so the
> GUARDED_MUTEX was just in an attempt to be more efficient which backfired
> …
>
> Kind regards, K
>
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
>
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:></http:></http:></http:>