mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 22:55:05 +00:00
[NDISUIO]
- Make reads cancelable - Fix a bug in IOCTL_CANCEL_READ handling svn path=/branches/wlan-bringup/; revision=54823
This commit is contained in:
parent
90d838bf1a
commit
31b309b74d
|
@ -109,7 +109,7 @@ CancelPacketRead(PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PacketEntry->PacketLength = 0;
|
PacketEntry->PacketLength = 0;
|
||||||
|
|
||||||
ExInterlockedInsertTailList(&AdapterContext->PacketList,
|
ExInterlockedInsertHeadList(&AdapterContext->PacketList,
|
||||||
&PacketEntry->ListEntry,
|
&PacketEntry->ListEntry,
|
||||||
&AdapterContext->Spinlock);
|
&AdapterContext->Spinlock);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,30 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NduDispatchRead(PDEVICE_OBJECT DeviceObject,
|
NduDispatchRead(PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -19,7 +43,7 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
|
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
|
||||||
PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2;
|
PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql, OldCancelIrql;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PNDISUIO_PACKET_ENTRY PacketEntry = NULL;
|
PNDISUIO_PACKET_ENTRY PacketEntry = NULL;
|
||||||
|
@ -36,6 +60,22 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject,
|
||||||
return STATUS_INVALID_PARAMETER;
|
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)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
|
KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
|
||||||
|
@ -52,10 +92,22 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject,
|
||||||
TRUE,
|
TRUE,
|
||||||
NULL);
|
NULL);
|
||||||
if (Status != STATUS_SUCCESS)
|
if (Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Remove the cancel routine */
|
||||||
|
IoAcquireCancelSpinLock(&OldCancelIrql);
|
||||||
|
IoSetCancelRoutine(Irp, NULL);
|
||||||
|
IoReleaseCancelSpinLock(OldCancelIrql);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Remove the cancel routine */
|
||||||
|
IoAcquireCancelSpinLock(&OldCancelIrql);
|
||||||
|
IoSetCancelRoutine(Irp, NULL);
|
||||||
|
IoReleaseCancelSpinLock(OldCancelIrql);
|
||||||
|
|
||||||
/* Remove the first packet in the list */
|
/* Remove the first packet in the list */
|
||||||
ListEntry = RemoveHeadList(&AdapterContext->PacketList);
|
ListEntry = RemoveHeadList(&AdapterContext->PacketList);
|
||||||
PacketEntry = CONTAINING_RECORD(ListEntry, NDISUIO_PACKET_ENTRY, ListEntry);
|
PacketEntry = CONTAINING_RECORD(ListEntry, NDISUIO_PACKET_ENTRY, ListEntry);
|
||||||
|
|
Loading…
Reference in a new issue