From: Matteo Bruni mbruni@codeweavers.com
This matches https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/using-a-dr... and, as far as I can see, is the intended idea and what the comment implies.
The idea, as I understand it, is to avoid a TOCTOU hazard by first setting the cancel routine and only afterwards checking the Cancel flag. If it's set while the previous cancel routine (returned by the second IoSetCancelRoutine call) is not NULL, that means it's been enabled before our first IoSetCancelRoutine call and we have to take care of it.
Conversely, if there is no previous routine set, it must mean that ntoskrnl has removed the routine we just set and it's going to call it, or has already called it (and it's probably now trying to acquire the spinlock). In that case we leave handling the cancellation to the routine and do nothing special here. --- dlls/hidclass.sys/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 852c8ebfbff..5b7a675db7f 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -163,7 +163,7 @@ static NTSTATUS hid_queue_push_irp( struct hid_queue *queue, IRP *irp ) KeAcquireSpinLock( &queue->lock, &irql );
IoSetCancelRoutine( irp, read_cancel_routine ); - if (irp->Cancel && !IoSetCancelRoutine( irp, NULL )) + if (irp->Cancel && IoSetCancelRoutine( irp, NULL )) { /* IRP was canceled before we set cancel routine */ InitializeListHead( &irp->Tail.Overlay.ListEntry );