Mark, thank you for your answer.
Yes, you’re right, it can be done by ignoring those
requests which can’t be canceled in some short
time and let them to do “anything they want to do” :-))
but there is one problem: I use only one Irp because
I can send only one request down at the same time -
thus not needing still allocate and free Irps. One only
Irp is enough for me… Except the case when the Irp
can’t be cancelled quickly. Then it would be better to
forget this Irp and allocate a new one (and also mark
the current as non-active and thus force my completion
routine to free it on eventual completion).
But I want to know if the is some better solution before
I implement this kind of “optimization”.
Paul
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Mark Roddy
Sent: Monday, January 28, 2002 7:51 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Cancelling an Irp
I don’t think you can assign an arbitrary time here and just hope that
the lower driver will manage to complete your irp. When the iomanager,
for example, does its generic thread-termination irp cancelling, I think
it waits five minutes for the irps to complete, and then assigns the
tardy (or perhaps retarded,) irps to a loser queue in case they ever
manage to complete.
The usb stack does deal with cancellation of at least some irps
correctly, as the various polling-based usb input devices always park an
irp with the bus driver for the next io request, and have to cancel that
irp if somebody unplugs the device.
Perhaps it would be better to just call IoCancelIrp and let your
completion handler deal with the irps as they complete, if they ever
complete, and not worry about the ones that don’t?
=====================
Mark Roddy
Windows XP/2000/NT Consulting
Hollis Technology Solutions 603-321-1032
www.hollistech.com
xxxxx@hollistech.com
For Windows Device Driver Training: see www.azius.com
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@compelson.com
Sent: Monday, January 28, 2002 1:10 PM
To: NT Developers Interest List
Subject: [ntdev] Cancelling an Irp
Hello all developers,
I have a following problem with canceling
my own Irps which I’m sending to the USB
device stack:
I send and Irp and if the returned status from
IoCallDriver is STATUS_PENDING, I have to wait
for the completion. I’m the owner of the Irp and
I have set a completion routine on it to set
some event on which I’m waiting - so I’m the one
who ensures that the Irp will not be completed
unexpectedly and it remains valid until I free it.
The wait after pending has been returned has timeout
value specified and if the wait times out, I want to
cancel the Irp and return - which is logical, I think ;-).
I’m using the following code to cancel my Irps:
VOID
XxxCancelUrbIrp (
IN PIRP Irp,
IN PKEVENT Event
)
{
LARGE_INTEGER CancelTimeout;
NTSTATUS Status;
BOOLEAN Cancelled;
Cancelled = IoCancelIrp(Irp);
//BUGBUG: what time should we set here?
CancelTimeout.QuadPart = -50*1000*10; //50 ms for now
Status = KeWaitForSingleObject(Event, Executive, KernelMode, FALSE,
&CancelTimeout);
ASSERT(Status == STATUS_WAIT_0);
if (Cancelled)
{
ASSERT(Irp->IoStatus.Status == STATUS_IO_TIMEOUT);
ASSERT(!Irp->Cancel);
}
else
{
ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
ASSERT(Irp->Cancel);
Irp->Cancel = FALSE;
}
}
But sometimes the first assertion fails and then also
the following ones. The wait returns status of STATUS_TIMEOUT, which
means that the Irp is still not completed after 50 milliseconds. Then
the result will be unpredictable, because the Irp is reused for
something else and it can be still pending.
So, what is the proper way to ensure that the Irp will
be completed by the lower level components in some short
time after I cancel it?
Maybe someone at Microsoft who has written the USBD.SYS knows some
issues for canceling the Irps sent to it.
Thank you very much for your help,
it’s the first time I really need it on this list 
Paul
PS: You might argue how can I assert some status and not set the
cancel flag… Of course this behaviour is ensured in my completion
routine ;-))
The other case is when I tried to cancel already completed Irp (or
at least I think the Irp must be already completed because it had no
completion routine at the cancel time).
You are currently subscribed to ntdev as: xxxxx@hollistech.com To
unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
You are currently subscribed to ntdev as: xxxxx@compelson.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com