21,597
社区成员
发帖
与我相关
我的任务
分享
VOID
KeyboardClassCleanupQueue (
IN PDEVICE_OBJECT DeviceObject,
IN PKDB_DEVICE_EXTENSION DeviceExtension,
IN PFILE_OBJECT FileObject
)
/*++
Routine Description:
This does the work of MouseClassCleanup so that we can also do that work
during remove device for when the grand master isn't enabled.
--*/
{
KdPrint(("In KeyboardClassCleanupQueue\n"));
PIRP irp;
LIST_ENTRY listHead, *entry;
KIRQL irql;
PIO_STACK_LOCATION stack;
PDRIVER_CANCEL oldCancelRoutine;
UNREFERENCED_PARAMETER(DeviceObject);
InitializeListHead(&listHead);
KeAcquireSpinLock(&DeviceExtension->SpinLock, &irql);
/*if (IsListEmpty(DeviceExtension->ReadQueue.Flink))
{
KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
return ;
}*/
for (entry = DeviceExtension->ReadQueue.Flink;
entry != &DeviceExtension->ReadQueue;) {
PLIST_ENTRY nextEntry = entry->Flink;
irp = CONTAINING_RECORD (entry, IRP, Tail.Overlay.ListEntry);
stack = IoGetCurrentIrpStackLocation (irp);
//
// If no FileObject is given, lets cleanup all of them,
// otherwise lets try to find only the matching ones
//
if (NULL == FileObject || stack->FileObject == FileObject) {
RemoveEntryList (entry);
oldCancelRoutine = IoSetCancelRoutine (irp, NULL);
//
// IoCancelIrp() could have just been called on this IRP.
// What we're interested in is not whether IoCancelIrp() was called
// (ie, nextIrp->Cancel is set), but whether IoCancelIrp() called (or
// is about to call) our cancel routine. To check that, check the result
// of the test-and-set macro IoSetCancelRoutine.
//
if (oldCancelRoutine) {
//
// Cancel routine not called for this IRP. Queue this IRP.
//
irp->IoStatus.Status = STATUS_CANCELLED;
irp->IoStatus.Information = 0;
InsertTailList (&listHead, &irp->Tail.Overlay.ListEntry);
}
else {
//
// This IRP was just cancelled and the cancel routine was (or will
// be) called. The cancel routine will complete this IRP as soon as
// we drop the spinlock. So don't do anything with the IRP.
//
// Also, the cancel routine will try to dequeue the IRP, so make the
// IRP's listEntry point to itself.
//
ASSERT (irp->Cancel);
InitializeListHead (&irp->Tail.Overlay.ListEntry);
}
}
entry = nextEntry;
// break;
}
KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
//
// Complete these irps outside of the spin lock
//
while (! IsListEmpty (&listHead)) {
entry = RemoveHeadList (&listHead);
irp = CONTAINING_RECORD (entry, IRP, Tail.Overlay.ListEntry);
IoCompleteRequest (irp, IO_NO_INCREMENT);
IoReleaseRemoveLock (&DeviceExtension->RemoveLock, irp);
}
}