UNIMPLEMENTED;
}
+/*
+ @unimplemented
+*/
+KSDDKAPI
+VOID
+NTAPI
+KsDereferenceSoftwareBusObject(
+ IN KSDEVICE_HEADER Header)
+{
+ UNIMPLEMENTED;
+}
+
/*
@implemented
*/
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
VOID
IN OUT PLIST_ENTRY QueueHead,
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
VOID
IN PIRP Irp,
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 */
+ SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
+
+ /* 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);
+ }
}
/*
IN KSLIST_ENTRY_LOCATION ListLocation,
IN KSIRP_REMOVAL_OPERATION RemovalOperation)
{
- PQUEUE_ENTRY Entry = NULL;
PIRP Irp;
+ PLIST_ENTRY CurEntry;
KIRQL OldIrql;
+ /* check parameters */
if (!QueueHead || !SpinLock)
return NULL;
+ /* check if parameter ListLocation is valid */
if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead)
return NULL;
- if (RemovalOperation != KsAcquireOnly && RemovalOperation != KsAcquireAndRemove)
- return NULL;
-
+ /* acquire list lock */
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)
- Entry = (PQUEUE_ENTRY)QueueHead->Flink;
- else
- Entry = (PQUEUE_ENTRY)QueueHead->Blink;
+ /* reached end of list */
+ break;
}
- else if (RemovalOperation == KsAcquireAndRemove)
+
+ /* get irp offset */
+ Irp = (PIRP)CONTAINING_RECORD(Irp, IRP, Tail.Overlay.ListEntry);
+
+ if (Irp->Cancel)
{
- if (ListLocation == KsListEntryTail)
- Entry = (PQUEUE_ENTRY)RemoveTailList(QueueHead);
- else
- Entry = (PQUEUE_ENTRY)RemoveHeadList(QueueHead);
+ /* irp has been canceled */
+ break;
}
- }
+
+ 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);
- if (!Entry)
- return NULL;
+ if (!Irp || Irp->CancelRoutine == NULL)
+ {
+ /* either an irp has been acquired or nothing found */
+ return Irp;
+ }
+
+ /* time to remove the canceled irp */
+ IoAcquireCancelSpinLock(&OldIrql);
+ /* acquire list lock */
+ KeAcquireSpinLockAtDpcLevel(SpinLock);
- Irp = Entry->Irp;
+ if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem)
+ {
+ /* remove it */
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+ }
- if (RemovalOperation == KsAcquireAndRemove)
- ExFreePool(Entry);
+ /* release list lock */
+ KeReleaseSpinLockFromDpcLevel(SpinLock);
- return Irp;
+ /* release cancel spinlock */
+ IoReleaseCancelSpinLock(OldIrql);
+ /* no non canceled irp has been found */
+ return NULL;
}
/*
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
VOID
KsRemoveSpecificIrpFromCancelableQueue(
IN PIRP Irp)
{
- UNIMPLEMENTED;
+ PKSPIN_LOCK SpinLock;
+ KIRQL OldLevel;
+
+ /* get internal queue lock */
+ SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
+
+ /* acquire spinlock */
+ KeAcquireSpinLock(SpinLock, &OldLevel);
+
+ /* remove the irp from the list */
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+
+ /* release spinlock */
+ KeReleaseSpinLock(SpinLock, OldLevel);
}
IN KSLIST_ENTRY_LOCATION ListLocation,
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 internal queue lock */
+ KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) = 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
VOID
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- UNIMPLEMENTED;
+ PKSPIN_LOCK SpinLock;
+ KIRQL OldLevel;
+
+ /* get internal queue lock */
+ SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
+
+ /* 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);
+ }
}
/*
return STATUS_NOT_FOUND;
}
-NTAPI
NTSTATUS
+NTAPI
KspCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
}
-NTAPI
NTSTATUS
+NTAPI
KspDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
}
-NTAPI
NTSTATUS
+NTAPI
KspDispatchIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
}
+
+/*
+ @unimplemented
+*/
+KSDDKAPI
+ULONG
+NTAPI
+KsGetNodeIdFromIrp(
+ IN PIRP Irp)
+{
+ UNIMPLEMENTED
+ return (ULONG)-1;
+}
+
+/*
+ @unimplemented
+*/
+KSDDKAPI
+PKSPIN
+NTAPI
+KsGetPinFromIrp(
+ IN PIRP Irp)
+{
+ UNIMPLEMENTED
+ return NULL;
+}