Canceling Irps: Packet driver (win2K)

I believe the cancel implementation in the packet driver on W2K has
a window where it will fail to cancel read requests.

The relevant code when an Irp is submitted is essentually:

IoSetCancelRoutine(Irp, PacketCancelRoutine);

// XXXXXX

ExInterlockedInsertTailList(
&open->RcvList,
&RESERVED(pPacket)->ListElement,
&open->RcvQSpinLock);

PacketCancelRoutine is:
KeAcquireSpinLockAtDpcLevel(&open->RcvQSpinLock);

IoReleaseCancelSpinLock( KeGetCurrentIrql() );

search list for IRP. If found, dequeue and complete it with error.

If the cancel operation occurs while the IRP is being received, at XXXXXX,
the cancel routine will not find the IRP, and the Irp will be queued, perhaps
forever.

Is there some higher level reason why this can’t happen?

I think the code should be something like:

KeAcquireSpinLock(&open->RcvQSpinLock);
if (!Irp->Cancel) {

IoSetCancelRoutine(Irp, PacketCancelRoutine)

InsertTailList(&open->RcvList, &RESERVED(pPacket)->ListElement);
release lock
}
else {
release lock
return Irp with error.
}

Furthermore, I assert that it is impossible to close this window, and to also use
only ExInterlockedInsertTailList.

The Win2000 DDK has a more convoluted way of doing the above, which ensures
(and requires) that the cancel routine will find the request. This appears to also be correct, but
perhaps a bit of overkill.
-DH


Dave Harvey, System Software Solutions, Inc.
617-964-7039, FAX 208-361-9395, xxxxx@syssoftsol.com, http://www.syssoftsol.com
Specialists in fault tolerance, SMP, clusters, and Windows/NT.