📄 usbfx2lk_queue.cpp
字号:
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_READWRITE,
("OsrCsqPeekNextIoIrp: Next Irp is Irp 0x%p...\n",nextIrp));
return nextIrp;
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrCsqAcquireIoLock
//
// We're called here when the CSQ lib wants to synchronize
// access to our queue.
//
// INPUTS:
//
// Csq - Our cancel safe queue
//
// OUTPUTS:
//
// Irql - We return the IRQL at which we want to drop
// back down to when called at our release routine
// in the Irql parameter
//
// RETURNS:
//
// None
//
// IRQL:
//
// This routine is called at IRQL <= DISPATCH_LEVEL
//
// CONTEXT:
//
// Arbitrary
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID OsrCsqAcquireIoLock(PIO_CSQ Csq,PKIRQL Irql)
{
PUSBFX2LK_EXT devExt;
//
// We should never be here and not at <= DISPATCH_LEVEL
//
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
//
// Get a pointer to our device extension...
//
devExt = CONTAINING_RECORD(Csq, USBFX2LK_EXT, CancelSafeIoQueue);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_READWRITE,
("OsrCsqAcquireIoLock: Acquiring the cancel safe queue lock...\n"));
//
// Simply acquire our spinlock. The current IRQL (which
// is the IRQL we'll want to return to when dropping the lock)
// will be returned in the Irql parameter.
//
KeAcquireSpinLock(&devExt->CancelSafeIoLock, Irql);
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrCsqReleaseIoLock
//
// We're called here when the CSQ lib is finished accessing
// our queue
//
// INPUTS:
//
// Csq - Our cancel safe queue
//
// Irql - This is the IRQL value that we previously stored
// in OsrCsqAcquireIoLock
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
// IRQL:
//
// This routine is called at IRQL == DISPATCH_LEVEL (since
// we're holding the CancelSafeIoLock)
//
// CONTEXT:
//
// Arbitrary
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID OsrCsqReleaseIoLock(PIO_CSQ Csq,KIRQL Irql)
{
PUSBFX2LK_EXT devExt;
//
// We should never be here and not at DISPATCH_LEVEL
//
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
//
// Get a pointer to our device extension...
//
devExt = CONTAINING_RECORD(Csq,
USBFX2LK_EXT,
CancelSafeIoQueue);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_READWRITE,
("OsrCsqReleaseIoLock: Releasing the cancel safe queue lock...\n"));
//
// Drop the lock, restoring the old Irql...
//
KeReleaseSpinLock(&devExt->CancelSafeIoLock, Irql);
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrCsqCompleteCancelledIoIrp
//
// The CSQ library calls us here when it has a Irp that needs to be
// cancelled.
//
// INPUTS:
//
// Csq - Our cancel safe queue
//
// Irp - The Irp to cancel
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
// IRQL:
//
// This routine is called at IRQL <= DISPATCH_LEVEL
//
// CONTEXT:
//
// Arbitrary
//
// NOTES:
//
// Note that while the Irp is in our Queue the
// Irp->Tail.Overlay.DriverContext[0], contains our IO Context for the
// operation.
//
///////////////////////////////////////////////////////////////////////////////
VOID OsrCsqCompleteCancelledIoIrp(PIO_CSQ Csq,PIRP Irp)
{
PUSBFX2LK_EXT devExt;
PUSBFX2LK_IO_CONTEXT pFx2Context = NULL;
PURB ioctlUrb = NULL;
//
// We should never be here and not at <= DISPATCH_LEVEL
//
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
//
// Get a pointer to our device extension...
//
devExt = (PUSBFX2LK_EXT)CONTAINING_RECORD(Csq, USBFX2LK_EXT, CancelSafeIoQueue);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_READWRITE,
("OsrCsqCompleteCancelledIoIrp: Cancelling Irp 0x%p!\n",
Irp));
//
// See if we have a read/write context stored in the DriverContext field.
// We can do this because we are not using system queuing. Also
// we can use DriverContext[0]. The IoCsq routines use DriverContext[3]
//
pFx2Context = (PUSBFX2LK_IO_CONTEXT) Irp->Tail.Overlay.DriverContext[0];
if(pFx2Context) {
IoFreeMdl(pFx2Context->Mdl);
ExFreePool(pFx2Context->Urb);
IoFreeWorkItem(pFx2Context->PWorkItem);
ExFreePool(pFx2Context);
}
//
// For some IOCTLs, we queue them off and put the
// URBs that we've allocated in the DriverContext[1]
// pointer. Again, we can do this because these contexts
// are ours while we own the IRP
//
ioctlUrb = (PURB)Irp->Tail.Overlay.DriverContext[1];
if (ioctlUrb) {
ExFreePool(ioctlUrb);
}
//
// Just go ahead and cancel the Irp
//
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// One less request, don't forget to decrement our outstanding
// IO count!
//
OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
}
///////////////////////////////////////////////////////////////////////////////
//
// OsrClearQueues
//
// This routine is called to clear out all read and write requests
// that are either in progress or pending
//
// INPUTS:
//
// DevExt - The device extension for the device whose queues we want
// clear
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// None
//
// IRQL:
//
// This routine is called at IRQL <= DISPATCH_LEVEL
//
// CONTEXT:
//
// This routine can be called from anywhere in the driver
// so the context should be assumed arbitrary
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID OsrClearQueues(PUSBFX2LK_EXT DevExt)
{
PIRP irp;
PUSBFX2LK_IO_CONTEXT pFx2Context = NULL;
PURB ioctlUrb = NULL; ;
//
// We should never be here and not at <= DISPATCH_LEVEL
//
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
//
// Traverse the Io queue and fail any outstanding write
// requests
//
while(irp = IoCsqRemoveNextIrp(&DevExt->CancelSafeIoQueue, NULL)) {
//
// See if we have a context stored in the DriverContext field. We can do this
// because we are not using system queuing. Also we can use DriverContext[0],
// The IoCsq routines use DriverContext[3].
//
pFx2Context = (PUSBFX2LK_IO_CONTEXT) irp->Tail.Overlay.DriverContext[0];
if(pFx2Context) {
IoFreeMdl(pFx2Context->Mdl);
ExFreePool(pFx2Context->Urb);
IoFreeWorkItem(pFx2Context->PWorkItem);
ExFreePool(pFx2Context);
}
//
// For some IOCTLs, we queue them off and put the
// URBs that we've allocated in the DriverContext[1]
// pointer. Again, we can do this because these contexts
// are ours while we own the IRP
//
ioctlUrb = (PURB)irp->Tail.Overlay.DriverContext[1];
if (ioctlUrb) {
ExFreePool(ioctlUrb);
}
//
// Mark the Irp as offline.....
//
irp->IoStatus.Status = STATUS_DEVICE_OFF_LINE;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -