Driver: Reset Cancel Routine of cancelled IRP

This commit is contained in:
Nodir Temirkhodjaev 2023-02-13 15:39:51 +03:00
parent 3677c59838
commit a79fc8493d
2 changed files with 9 additions and 5 deletions

View File

@ -264,8 +264,10 @@ FORT_API NTSTATUS fort_buffer_cancel_pending(PFORT_BUFFER buf, PIRP irp, ULONG_P
*info = 0; *info = 0;
/* Cancel routines are called at IRQL = DISPATCH_LEVEL */
KLOCK_QUEUE_HANDLE lock_queue; KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireInStackQueuedSpinLock(&buf->lock, &lock_queue); KeAcquireInStackQueuedSpinLockAtDpcLevel(&buf->lock, &lock_queue);
if (irp == buf->irp) { if (irp == buf->irp) {
buf->irp = NULL; buf->irp = NULL;
buf->out_len = 0; buf->out_len = 0;
@ -277,7 +279,7 @@ FORT_API NTSTATUS fort_buffer_cancel_pending(PFORT_BUFFER buf, PIRP irp, ULONG_P
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
} }
} }
KeReleaseInStackQueuedSpinLock(&lock_queue); KeReleaseInStackQueuedSpinLockFromDpcLevel(&lock_queue);
return status; return status;
} }

View File

@ -117,6 +117,7 @@ static void fort_device_cancel_pending(PDEVICE_OBJECT device, PIRP irp)
const NTSTATUS status = fort_buffer_cancel_pending(&g_device->buffer, irp, &info); const NTSTATUS status = fort_buffer_cancel_pending(&g_device->buffer, irp, &info);
IoSetCancelRoutine(irp, NULL);
IoReleaseCancelSpinLock(irp->CancelIrql); /* before IoCompleteRequest()! */ IoReleaseCancelSpinLock(irp->CancelIrql); /* before IoCompleteRequest()! */
fort_request_complete_info(irp, status, info); fort_request_complete_info(irp, status, info);
@ -177,12 +178,13 @@ static NTSTATUS fort_device_control_getlog(PVOID out, ULONG out_len, PIRP irp, U
const NTSTATUS status = fort_buffer_xmove(&g_device->buffer, irp, out, out_len, info); const NTSTATUS status = fort_buffer_xmove(&g_device->buffer, irp, out, out_len, info);
if (status == STATUS_PENDING) { if (status == STATUS_PENDING) {
KIRQL cirq;
IoMarkIrpPending(irp); IoMarkIrpPending(irp);
KIRQL cirq;
IoAcquireCancelSpinLock(&cirq); IoAcquireCancelSpinLock(&cirq);
{
IoSetCancelRoutine(irp, fort_device_cancel_pending); IoSetCancelRoutine(irp, fort_device_cancel_pending);
}
IoReleaseCancelSpinLock(cirq); IoReleaseCancelSpinLock(cirq);
} }
return status; return status;