I wrote about both (rolling your own irps, unload synchronization) if
you care to read about it
Threaded irps:
http://blogs.msdn.com/doronh/archive/2006/07/27/681179.aspx
IoSetCompletionRoutineEx:
http://blogs.msdn.com/doronh/archive/2006/08/08/692479.aspx
d
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Arlie Davis
Sent: Wednesday, September 06, 2006 9:00 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Sending Own Irp to Lower driver from Filter.
If you allocated your own IRP, then submitted to a lower device, and
your completion routine was called, then yes, you SHOULD call IoFreeIrp
and then return STATUS_MORE_PROCESSING_REQUIRED.
It’s not dangerous because IoCompleteRequest was designed for just this
scenario. When a driver calls IoCompleteRequest, the I/O manager starts
walking the list of I/O stack locations, looking for completion
routines, and it calls those completion routines. Each time it does so,
it moves the current I/O stack location pointer. If any of those
routines returns STATUS_MORE_PROCESSING_REQUIRED, then IoCompleteRequest
*immediately* returns, without touching any more IRP fields, because the
IRP may have already been deleted.
If you do a thought-experiment, you’ll see that IoCompleteRequest *must*
work this way. Consider the classical meaning of
STATUS_MORE_PROCESSING_REQUIRED, where a completion routine realizes
that it needs to do more work on the current IRP before it can allow the
IRP completion to continue. (As a hypothetical case, maybe the driver
processing the IRP is working on segmenting a large transfer into many
smaller ones, and the current IRP completion was not the last segment
transferred, so the driver re-submits the IRP to the lower layer.) If
the completion routine re-submits that IRP, then the lower driver could
process that IRP, and call IoCompleteRequest on a different processor.
That second instance of the completion routine could free the IRP and
return STATUS_MORE_PROCESSING_REQUIRED, or if it was an IRP received on
a dispatch function and not allocated using IoAllocateIrp, it could just
return STATUS_SUCCESS. At this point, the IRP has been destroyed, so
the first instance of the completion routine, including the code in
IoCompleteRequest, *must not* touch the IRP.
This behavior is guaranteed. If you allocate your own IRP, using
IoAllocateIrp, and submit it to a lower driver, then you should free it
in your completion routine and should return
STATUS_MORE_PROCESSING_REQUIRED. This is safe, supported behavior.
Nota bene: If you are doing this, then you need to be aware of a certain
race condition that can occur during shutdown. Your driver can be
unloaded while your completion routine is running, because the OS has
not incremented the reference count on your PDEVICE_OBJECT or your
PDRIVER_OBJECT. So if you are using this design pattern, you must use
IoSetCompletionRoutineEx, instead of IoSetCompletionRoutine. And
because IoSetCompletionRoutineEx can fail (because it necessarily
allocates memory), you must check its return value.
– arlie
P.S. Please restrict use of “M$” to sycophantic fan-boy posts on
Slashdot. It’s childish.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of MM
Sent: Wednesday, September 06, 2006 4:30 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Sending Own Irp to Lower driver from Filter.
Ok, I’ve love if someone could explain this too me.
I originally thought that calling IoFreeIrp before returning from a
completion routine with STATUS_MORE_PROCESSING_REQUIRED would cause an
error. It was originally my
contention:
“I’d guess that freeing the IRP before returning from your completion
routine with status_more_processing_required is the problem. Your nuking
the IRP then telling the IOmanager you still need to do some processing
on the operation.”
Max said this is OK, so I assumed I misunderstood what IoFreeIrp does.
I looked to the ddk and read this:
“The *IoFreeIrp* routine releases a caller-allocated IRP from the
caller’s /IoCompletion/ routine.”. I then looked too the samples and saw
that they all call IoFreeIrp before returning
STATUS_MORE_PROCESSING_REQUIRED.
Max also indicated that when you do a IoFreeIrp followed by
STATUS_MORE_PROCESSING_REQUIRED your telling the IO manager:
“you tell IO manager - “hands off this IRP, abort the completion
processing and return from IoCompleteRequest”.”.
Tim then chimed in with: “STATUS_STOP_PROCESSING_IRP or
STATUS_IRP_FINISHED might express the sentiment better.”
Max also reinforced my ‘original’ veiw that IoFreeIrp deallocated memory
for the IRP by
stating: “IoFreeIrp really frees the IRP’s memory.”
So what’s happening here? In the completion routine you free the IRP and
release all memory associated with it. Then, you tell the IO manager to
stop processing the IRP (which no longer exist because you just freed
it). Why is this not dangerous? How can you tell the Io Manager to stop
processing something you just destroyed; shouldn’t there be a crap load
of bad pointers now, all referencing bad memory?
Just curious here,
m.
Maxim S. Shatskih wrote:
>M$ could of picked a better name for IoFreeIrp - that has always
>always confused me. Every time I see that function, I think it’s
>deallocating the memory for the IRP…
>
>
IoFreeIrp really frees the IRP’s memory.
STATUS_MORE_PROCESSING_REQUIRED is not a good name -
STATUS_ABORT_COMPLETION would be better.
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer