mirror of
https://github.com/reactos/reactos.git
synced 2024-07-28 23:29:19 +00:00
- Remove old irp queue implementation
- Implement KsCancelIo, KsReleaseIrpOnCancelableQueue, KsRemoveIrpFromCancelableQueue, KsRemoveSpecificIrpFromCancelableQueue, KsAddIrpToCancelableQueue, KsCancelRoutine svn path=/trunk/; revision=42149
This commit is contained in:
parent
916f5b12a6
commit
db1215455b
|
@ -746,7 +746,7 @@ KsDispatchFastReadFailure(
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
VOID
|
VOID
|
||||||
|
@ -755,11 +755,55 @@ KsCancelIo(
|
||||||
IN OUT PLIST_ENTRY QueueHead,
|
IN OUT PLIST_ENTRY QueueHead,
|
||||||
IN PKSPIN_LOCK SpinLock)
|
IN PKSPIN_LOCK SpinLock)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDRIVER_CANCEL OldDriverCancel;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
PIRP Irp;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
/* acquire spinlock */
|
||||||
|
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||||
|
/* point to first entry */
|
||||||
|
Entry = QueueHead->Flink;
|
||||||
|
/* loop all items */
|
||||||
|
while(Entry != QueueHead)
|
||||||
|
{
|
||||||
|
/* get irp offset */
|
||||||
|
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
/* set cancelled bit */
|
||||||
|
Irp->Cancel = TRUE;
|
||||||
|
|
||||||
|
/* now set the cancel routine */
|
||||||
|
OldDriverCancel = IoSetCancelRoutine(Irp, NULL);
|
||||||
|
if (OldDriverCancel)
|
||||||
|
{
|
||||||
|
/* this irp hasnt been yet used, so free to cancel */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
|
|
||||||
|
/* get current irp stack */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* acquire cancel spinlock */
|
||||||
|
IoAcquireCancelSpinLock(&Irp->CancelIrql);
|
||||||
|
|
||||||
|
/* call provided cancel routine */
|
||||||
|
OldDriverCancel(IoStack->DeviceObject, Irp);
|
||||||
|
|
||||||
|
/* re-acquire spinlock */
|
||||||
|
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||||
|
}
|
||||||
|
/* move on to next entry */
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the irp has already been canceled */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
VOID
|
VOID
|
||||||
|
@ -768,7 +812,51 @@ KsReleaseIrpOnCancelableQueue(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PDRIVER_CANCEL DriverCancel OPTIONAL)
|
IN PDRIVER_CANCEL DriverCancel OPTIONAL)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PKSPIN_LOCK SpinLock;
|
||||||
|
PDRIVER_CANCEL OldDriverCancel;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
/* check for required parameters */
|
||||||
|
if (!Irp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!DriverCancel)
|
||||||
|
{
|
||||||
|
/* default to KsCancelRoutine */
|
||||||
|
DriverCancel = KsCancelRoutine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get current irp stack */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* get internal queue lock
|
||||||
|
* see KsAddIrpToCancelableQueue
|
||||||
|
*/
|
||||||
|
SpinLock = (PKSPIN_LOCK)Irp->Tail.Overlay.DeviceQueueEntry.DeviceListEntry.Flink;
|
||||||
|
|
||||||
|
/* acquire spinlock */
|
||||||
|
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||||
|
|
||||||
|
/* now set the cancel routine */
|
||||||
|
OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel);
|
||||||
|
|
||||||
|
if (Irp->Cancel && OldDriverCancel == NULL)
|
||||||
|
{
|
||||||
|
/* the irp has already been canceled */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
|
|
||||||
|
/* cancel routine requires that cancel spinlock is held */
|
||||||
|
IoAcquireCancelSpinLock(&Irp->CancelIrql);
|
||||||
|
|
||||||
|
/* cancel irp */
|
||||||
|
DriverCancel(IoStack->DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* done */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -783,49 +871,95 @@ KsRemoveIrpFromCancelableQueue(
|
||||||
IN KSLIST_ENTRY_LOCATION ListLocation,
|
IN KSLIST_ENTRY_LOCATION ListLocation,
|
||||||
IN KSIRP_REMOVAL_OPERATION RemovalOperation)
|
IN KSIRP_REMOVAL_OPERATION RemovalOperation)
|
||||||
{
|
{
|
||||||
PQUEUE_ENTRY Entry = NULL;
|
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
|
PLIST_ENTRY CurEntry;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* check parameters */
|
||||||
if (!QueueHead || !SpinLock)
|
if (!QueueHead || !SpinLock)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* check if parameter ListLocation is valid */
|
||||||
if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead)
|
if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (RemovalOperation != KsAcquireOnly && RemovalOperation != KsAcquireAndRemove)
|
/* acquire list lock */
|
||||||
return NULL;
|
|
||||||
|
|
||||||
KeAcquireSpinLock(SpinLock, &OldIrql);
|
KeAcquireSpinLock(SpinLock, &OldIrql);
|
||||||
|
|
||||||
if (!IsListEmpty(QueueHead))
|
/* point to queue head */
|
||||||
|
CurEntry = QueueHead;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
if (RemovalOperation == KsAcquireOnly)
|
/* reset irp to null */
|
||||||
|
Irp = NULL;
|
||||||
|
|
||||||
|
/* iterate to next entry */
|
||||||
|
if (ListLocation == KsListEntryHead)
|
||||||
|
CurEntry = CurEntry->Flink;
|
||||||
|
else
|
||||||
|
CurEntry = CurEntry->Blink;
|
||||||
|
|
||||||
|
/* is the end of list reached */
|
||||||
|
if (CurEntry == QueueHead)
|
||||||
{
|
{
|
||||||
if (ListLocation == KsListEntryHead)
|
/* reached end of list */
|
||||||
Entry = (PQUEUE_ENTRY)QueueHead->Flink;
|
break;
|
||||||
else
|
|
||||||
Entry = (PQUEUE_ENTRY)QueueHead->Blink;
|
|
||||||
}
|
}
|
||||||
else if (RemovalOperation == KsAcquireAndRemove)
|
|
||||||
|
/* get irp offset */
|
||||||
|
Irp = (PIRP)CONTAINING_RECORD(Irp, IRP, Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
if (Irp->Cancel)
|
||||||
{
|
{
|
||||||
if (ListLocation == KsListEntryTail)
|
/* irp has been canceled */
|
||||||
Entry = (PQUEUE_ENTRY)RemoveTailList(QueueHead);
|
break;
|
||||||
else
|
|
||||||
Entry = (PQUEUE_ENTRY)RemoveHeadList(QueueHead);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (Irp->CancelRoutine)
|
||||||
|
{
|
||||||
|
/* remove cancel routine */
|
||||||
|
Irp->CancelRoutine = NULL;
|
||||||
|
|
||||||
|
if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem)
|
||||||
|
{
|
||||||
|
/* remove irp from list */
|
||||||
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RemovalOperation == KsAcquireAndRemoveOnlySingleItem || RemovalOperation == KsAcquireOnlySingleItem)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}while(TRUE);
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
KeReleaseSpinLock(SpinLock, OldIrql);
|
KeReleaseSpinLock(SpinLock, OldIrql);
|
||||||
|
|
||||||
if (!Entry)
|
if (!Irp || Irp->CancelRoutine == NULL)
|
||||||
return NULL;
|
{
|
||||||
|
/* either an irp has been acquired or nothing found */
|
||||||
|
return Irp;
|
||||||
|
}
|
||||||
|
|
||||||
Irp = Entry->Irp;
|
/* time to remove the canceled irp */
|
||||||
|
IoAcquireCancelSpinLock(&OldIrql);
|
||||||
|
/* acquire list lock */
|
||||||
|
KeAcquireSpinLockAtDpcLevel(SpinLock);
|
||||||
|
|
||||||
if (RemovalOperation == KsAcquireAndRemove)
|
if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem)
|
||||||
ExFreePool(Entry);
|
{
|
||||||
|
/* remove it */
|
||||||
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
return Irp;
|
/* release list lock */
|
||||||
|
KeReleaseSpinLockFromDpcLevel(SpinLock);
|
||||||
|
|
||||||
|
/* release cancel spinlock */
|
||||||
|
IoReleaseCancelSpinLock(OldIrql);
|
||||||
|
/* no non canceled irp has been found */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -848,7 +982,7 @@ KsMoveIrpsOnCancelableQueue(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
VOID
|
VOID
|
||||||
|
@ -856,7 +990,22 @@ NTAPI
|
||||||
KsRemoveSpecificIrpFromCancelableQueue(
|
KsRemoveSpecificIrpFromCancelableQueue(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PKSPIN_LOCK SpinLock;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
/* get internal queue lock
|
||||||
|
* see KsAddIrpToCancelableQueue
|
||||||
|
*/
|
||||||
|
SpinLock = (PKSPIN_LOCK)Irp->Tail.Overlay.DeviceQueueEntry.DeviceListEntry.Flink;
|
||||||
|
|
||||||
|
/* acquire spinlock */
|
||||||
|
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||||
|
|
||||||
|
/* remove the irp from the list */
|
||||||
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
/* release spinlock */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -873,11 +1022,66 @@ KsAddIrpToCancelableQueue(
|
||||||
IN KSLIST_ENTRY_LOCATION ListLocation,
|
IN KSLIST_ENTRY_LOCATION ListLocation,
|
||||||
IN PDRIVER_CANCEL DriverCancel OPTIONAL)
|
IN PDRIVER_CANCEL DriverCancel OPTIONAL)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDRIVER_CANCEL OldDriverCancel;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
/* check for required parameters */
|
||||||
|
if (!QueueHead || !SpinLock || !Irp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!DriverCancel)
|
||||||
|
{
|
||||||
|
/* default to KsCancelRoutine */
|
||||||
|
DriverCancel = KsCancelRoutine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get current irp stack */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* acquire spinlock */
|
||||||
|
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||||
|
|
||||||
|
if (ListLocation == KsListEntryTail)
|
||||||
|
{
|
||||||
|
/* insert irp to tail of list */
|
||||||
|
InsertTailList(QueueHead, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* insert irp to head of list */
|
||||||
|
InsertHeadList(QueueHead, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store the spinlock in the device queue list entry,
|
||||||
|
* as other fields may have been internally been used
|
||||||
|
* used in KsCancelRoutine
|
||||||
|
*/
|
||||||
|
Irp->Tail.Overlay.DeviceQueueEntry.DeviceListEntry.Flink = (PLIST_ENTRY)SpinLock;
|
||||||
|
|
||||||
|
/* now set the cancel routine */
|
||||||
|
OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel);
|
||||||
|
|
||||||
|
if (Irp->Cancel && OldDriverCancel == NULL)
|
||||||
|
{
|
||||||
|
/* the irp has already been canceled */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
|
|
||||||
|
/* cancel routine requires that cancel spinlock is held */
|
||||||
|
IoAcquireCancelSpinLock(&Irp->CancelIrql);
|
||||||
|
|
||||||
|
/* cancel irp */
|
||||||
|
DriverCancel(IoStack->DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* done */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
VOID
|
VOID
|
||||||
|
@ -886,7 +1090,36 @@ KsCancelRoutine(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PKSPIN_LOCK SpinLock;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
/* get internal queue lock
|
||||||
|
* see KsAddIrpToCancelableQueue
|
||||||
|
*/
|
||||||
|
SpinLock = (PKSPIN_LOCK)Irp->Tail.Overlay.DeviceQueueEntry.DeviceListEntry.Flink;
|
||||||
|
|
||||||
|
/* acquire spinlock */
|
||||||
|
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* release cancel spinlock */
|
||||||
|
IoReleaseCancelSpinLock(DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* remove the irp from the list */
|
||||||
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
/* release spinlock */
|
||||||
|
KeReleaseSpinLock(SpinLock, OldLevel);
|
||||||
|
|
||||||
|
/* has the irp already been canceled */
|
||||||
|
if (Irp->IoStatus.Status != STATUS_CANCELLED)
|
||||||
|
{
|
||||||
|
/* let's complete it */
|
||||||
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -71,12 +71,6 @@ typedef struct
|
||||||
|
|
||||||
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
LIST_ENTRY Entry;
|
|
||||||
PIRP Irp;
|
|
||||||
}QUEUE_ENTRY, *PQUEUE_ENTRY;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
|
|
Loading…
Reference in a new issue