Author: cgutman Date: Tue Jan 3 19:37:03 2012 New Revision: 54823
URL: http://svn.reactos.org/svn/reactos?rev=54823&view=rev Log: [NDISUIO] - Make reads cancelable - Fix a bug in IOCTL_CANCEL_READ handling
Modified: branches/wlan-bringup/drivers/network/ndisuio/ioctl.c branches/wlan-bringup/drivers/network/ndisuio/readwrite.c
Modified: branches/wlan-bringup/drivers/network/ndisuio/ioctl.c URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndi... ============================================================================== --- branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] (original) +++ branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] Tue Jan 3 19:37:03 2012 @@ -109,7 +109,7 @@ { PacketEntry->PacketLength = 0;
- ExInterlockedInsertTailList(&AdapterContext->PacketList, + ExInterlockedInsertHeadList(&AdapterContext->PacketList, &PacketEntry->ListEntry, &AdapterContext->Spinlock);
Modified: branches/wlan-bringup/drivers/network/ndisuio/readwrite.c URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndi... ============================================================================== --- branches/wlan-bringup/drivers/network/ndisuio/readwrite.c [iso-8859-1] (original) +++ branches/wlan-bringup/drivers/network/ndisuio/readwrite.c [iso-8859-1] Tue Jan 3 19:37:03 2012 @@ -10,6 +10,30 @@
#define NDEBUG #include <debug.h> + +VOID +NTAPI +ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; + PNDISUIO_PACKET_ENTRY PacketEntry; + + /* Release the cancel spin lock */ + IoReleaseCancelSpinLock(Irp->CancelIrql); + + /* Indicate a 0-byte packet on the queue to cancel the read */ + PacketEntry = ExAllocatePool(PagedPool, sizeof(NDISUIO_PACKET_ENTRY)); + if (PacketEntry) + { + PacketEntry->PacketLength = 0; + + ExInterlockedInsertHeadList(&AdapterContext->PacketList, + &PacketEntry->ListEntry, + &AdapterContext->Spinlock); + + KeSetEvent(&AdapterContext->PacketReadEvent, IO_NO_INCREMENT, FALSE); + } +}
NTSTATUS NTAPI @@ -19,7 +43,7 @@ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2; - KIRQL OldIrql; + KIRQL OldIrql, OldCancelIrql; NTSTATUS Status; PLIST_ENTRY ListEntry; PNDISUIO_PACKET_ENTRY PacketEntry = NULL; @@ -35,6 +59,22 @@
return STATUS_INVALID_PARAMETER; } + + /* Make the read cancellable */ + IoAcquireCancelSpinLock(&OldCancelIrql); + IoSetCancelRoutine(Irp, ReadIrpCancel); + if (Irp->Cancel) + { + IoReleaseCancelSpinLock(OldCancelIrql); + + /* Indicate a 0 byte read */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + IoReleaseCancelSpinLock(OldCancelIrql);
while (TRUE) { @@ -52,10 +92,22 @@ TRUE, NULL); if (Status != STATUS_SUCCESS) + { + /* Remove the cancel routine */ + IoAcquireCancelSpinLock(&OldCancelIrql); + IoSetCancelRoutine(Irp, NULL); + IoReleaseCancelSpinLock(OldCancelIrql); + break; + } } else { + /* Remove the cancel routine */ + IoAcquireCancelSpinLock(&OldCancelIrql); + IoSetCancelRoutine(Irp, NULL); + IoReleaseCancelSpinLock(OldCancelIrql); + /* Remove the first packet in the list */ ListEntry = RemoveHeadList(&AdapterContext->PacketList); PacketEntry = CONTAINING_RECORD(ListEntry, NDISUIO_PACKET_ENTRY, ListEntry);