📄 rwusb.cpp
字号:
// 如果清除掉所有的挂起IO读操作,则返回值为真,否则为假
//
//
//
*****************************************************************************/
BOOLEAN
CancelPendingReadIo(
IN PUSB_DEVICE DeviceExt,
BOOLEAN fWaitCancelComplete
)
{
PUSB_DEVICE Adapter = DeviceExt;
BOOLEAN cRes = FALSE;
NTSTATUS timeStat;
int i;
DEBUGMSG( DBG_FUNC, (" +CancelPendingReadIo()\n"));
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
for (i = 0; i < NUM_RCV_BUFS; i++)
{
PRCV_BUFFER pRcvBuf = &Adapter->rcvBufs[i];
if ( ( STATE_PENDING == pRcvBuf->state ) &&
( NULL != pRcvBuf->Irp ) )
{
PIRP pIrp = (PIRP) pRcvBuf->Irp;
DEBUGMSG( DBG_FUNC, (" CancelPendingReadIo() about to CANCEL a read IRP!\n"));
KeClearEvent( &pRcvBuf->Event ); // 清除事件
cRes = IoCancelIrp( (PIRP) pRcvBuf->Irp ); // CancelPendingReadIo()
DEBUGCOND( DBG_ERR, !cRes, (" CancelPendingReadIo() COULDN'T CANCEL IRP!\n"));
DEBUGCOND( DBG_FUNC, cRes, (" CancelPendingReadIo() CANCELLED IRP SUCCESS!\n"));
if ( cRes && fWaitCancelComplete )
{
timeStat = MyKeWaitForSingleObject( //设置当前线程为等待状态直到给定的调用程序对象被置为信号状态,或直到等待期满
Adapter,
&pRcvBuf->Event,
NULL, // 清除了IRP,所以置为NULL
0 );
ASSERT( pRcvBuf->Irp == NULL);
}
} // if pending
} // for
DEBUGMSG( DBG_FUNC, (" -CancelPendingReadIo()\n"));
return (BOOLEAN) cRes;
}
/*****************************************************************************
//
//
// CancelPendingWriteIo
//
// 清除挂起的IO写操作例程
// 如果清除掉所有的挂起IO写操作,则返回值为真,否则为假
//
//
//
*****************************************************************************/
BOOLEAN
CancelPendingWriteIo(
IN PUSB_DEVICE DeviceExt
)
{
PUSB_DEVICE Adapter = DeviceExt;
BOOLEAN cRes = FALSE;
NTSTATUS timeStat;
PUSB_CONTEXT pCont;
ULONGLONG thisContext; //make ptr arithmetic 64-bit compatible
int i;
DEBUGMSG( DBG_FUNC, (" +CancelPendingWriteIo()\n"));
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
//
// 释放所有为发送缓冲区队列而分配的资源
//
thisContext = (ULONGLONG) Adapter->pSendContexts;
for ( i= 0; i < NUM_SEND_CONTEXTS; i++ ) {
pCont = (PUSB_CONTEXT)thisContext;
if( TRUE == pCont->fInUse ) {
//
// 获取USB_CONTEXT并清除它的IRP
//
ASSERT( NULL != pCont->Irp );
DEBUGMSG( DBG_WARN, (" CancelPendingWriteIo() about to CANCEL a write IRP!\n"));
// Completion routine ( USBCompleteWrite() )will free irps, mdls, buffers, etc as well
cRes = IoCancelIrp( pCont->Irp );
DEBUGCOND( DBG_ERR, !cRes, (" CancelPendingWriteIo() COULDN'T CANCEL IRP! 0x%x\n", pCont->Irp ));
DEBUGCOND( DBG_FUNC, cRes, (" CancelPendingWriteIo() CANCELLED IRP SUCCESS! 0x%x\n\n", pCont->Irp));
//
// Sleep 200 microsecs to give cancellation time to work
//
NdisMSleep(200);
}
thisContext += sizeof( USB_CONTEXT );
} // for
DEBUGMSG( DBG_FUNC, (" -CancelPendingWriteIo()\n"));
return (BOOLEAN) cRes;
}
/*****************************************************************************
//
//
// CancelPendingControlIo
//
// 清除挂起的IO控制操作例程
// 如果清除掉所有的挂起IO控制操作,则返回值为真,否则为假
//
//
//
*****************************************************************************/
BOOLEAN
CancelPendingControlIo(
IN PUSB_DEVICE DeviceExt,
IN PIRP IrpToCancel,
IN PKEVENT EventToClear
)
{
PUSB_DEVICE Adapter = DeviceExt;
BOOLEAN cRes = FALSE;
NTSTATUS timeStat;
DEBUGMSG( DBG_FUNC, (" +CancelPendingControlIo()\n"));
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL );
//
//置于非信号态
//
KeClearEvent( EventToClear );
if(IrpToCancel)
cRes = IoCancelIrp( IrpToCancel ); //CancelPendingControlIo()
DEBUGCOND( DBG_ERR, !cRes, (" CancelPendingControlIo() COULDN'T CANCEL IRP!\n"));
DEBUGCOND( DBG_FUNC, cRes, (" CancelPendingControlIo() CANCELLED IRP SUCCESS!\n"));
if ( cRes )
{
timeStat = MyKeWaitForSingleObject( //设置当前线程为等待状态直到给定的调用程序对象被置为信号状态,或直到等待期满
Adapter,
EventToClear,
NULL, // 清除了IRP,所以置为NULL
0 );
}
DEBUGMSG( DBG_FUNC, (" -CancelPendingControlIo()\n"));
return (BOOLEAN) cRes;
}
/*****************************************************************************
//
//
//
// CallUSBD()
//
// 传递格式化好的URB到USBD,设置IRP的各个参数
//
//
//
*****************************************************************************/
NTSTATUS
CallUSBD(
IN PUSB_DEVICE Adapter, // 指向适配器的指针
IN PURB Urb // 指向格式化后的URB结构体的指针
)
{
NTSTATUS ntStatus;
PDEVICE_OBJECT urbTargetDev;
PIO_STACK_LOCATION nextStack;
PMDL mdl;
DEBUGMSG( DBG_FUNC,(" +CallUSBD\n"));
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL );
ASSERT( Adapter );
ASSERT( NULL == ((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb );
urbTargetDev = Adapter->pUsbDevObj;
ASSERT( urbTargetDev );
// make an irp sending to usbhub?用IoAllocateIrp来创建Irp其StackSize均要+1
((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb =
IoAllocateIrp( (CCHAR)(Adapter->pUsbDevObj->StackSize +1), FALSE );
if ( NULL == ((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb )
{
DEBUGMSG(DBG_ERR, (" CallUsbd failed to alloc IRP\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto release;
}
//
// STATUS_NOT_SUPPORTED:
// The miniclass driver cannot distinguish the target condition
//
((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb->IoStatus.Status = STATUS_NOT_SUPPORTED;
((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb->IoStatus.Information = 0;
//
// 调用类驱动程序处理操作,如果返回挂起状态,则等待完成请求
//
nextStack = IoGetNextIrpStackLocation(((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb);
ASSERT(nextStack != NULL);
//
// pass the URB to the USB driver stack
//
nextStack->Parameters.Others.Argument1 = Urb;
//
// pass the URB to the USB driver stack
//
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.Others.Argument1 = Urb;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
//
// 注册一个IoCompletion例程,当下一层驱动程序已经完成对给定IRP的请求操作时调用它
//
IoSetCompletionRoutine(
((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb, // 指向驱动程序想追踪的irp
UsbIoCompleteControl, // 指定驱动程序提供的IoCompletion例程的入口,在下一层驱动程序完成信息包时调用它
DEV_TO_CONTEXT(Adapter), // 指向驱动程序决定的传递到IoCompletion例程的上下文
TRUE, // 如果IRP在I/O状态块中用STATUS_SUCCESS完成,则确定是否调用完成例程
TRUE, // 如果IRP在I/O状态块中用STATUS_XXX完成,则确定是否调用完成例程
TRUE); // 如果IRP在I/O状态块中用STATUS_CANCELLED完成,则确定是否调用完成例程
KeClearEvent(&Adapter->EventUrb);
UsbIncIoCount( Adapter );
ntStatus = IoCallDriver(
urbTargetDev, // 指向下一层驱动程序的设备对象,该对象为请求I/O操作描述目标设备
((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb ); // 指向IRP
DEBUGMSG( DBG_OUT,("CallUSBD () return from IoCallDriver USBD %x\n", ntStatus));
if ((ntStatus == STATUS_PENDING) || (ntStatus == STATUS_SUCCESS))
{
if (ntStatus == STATUS_PENDING)
{
ntStatus = MyKeWaitForSingleObject( Adapter, &Adapter->EventUrb, NULL, 0 );
if ( ntStatus == STATUS_TIMEOUT )
{
DEBUGMSG( DBG_ERR,("CallUSBD () TIMED OUT! return from IoCallDriver USBD %x\n", ntStatus));
CancelPendingControlIo( Adapter, ((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb, &Adapter->EventUrb );
}
}
}
else
{
DEBUGMSG( DBG_ERR, ("CallUSBD IoCallDriver FAILED(%x)\n",ntStatus));
}
DEBUGMSG( DBG_OUT,("CallUSBD () URB status = %x IRP status = %x\n",
Urb->UrbHeader.Status, ntStatus ));
release:
((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb = NULL;
DEBUGCOND( DBG_ERR, !NT_SUCCESS( ntStatus ), ("exit CallUSBD FAILED (%x)\n", ntStatus));
DEBUGMSG( DBG_FUNC,(" -CallUSBD\n"));
return ntStatus;
}
/*****************************************************************************
//
//
//
// UsbIoCompleteControl
//
// USB设备的完成例程
//
//
//
*****************************************************************************/
NTSTATUS
UsbIoCompleteControl(
IN PDEVICE_OBJECT pUsbDevObj, // 指向完成该IRP的USB设备
IN PIRP pIrp, // 该USB设备完成的IRP
IN PVOID Context // 指向设备扩展区的指针
)
{
PUSB_DEVICE Adapter;
NTSTATUS status;
DEBUGMSG(DBG_FUNC, ("+UsbIoCompleteControl\n"));
//
// 提供给IoSetCompletionRoutine的环境区指针,就是指向适配器的指针
//
Adapter = CONTEXT_TO_DEV(Context);
status = pIrp->IoStatus.Status;
switch (status)
{
case STATUS_SUCCESS:
DEBUGMSG(DBG_OUT, (" UsbIoCompleteControl STATUS_SUCCESS\n"));
break; // STATUS_SUCCESS
case STATUS_TIMEOUT:
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_TIMEOUT\n"));
break;
case STATUS_PENDING:
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_PENDING\n"));
break;
case STATUS_DEVICE_DATA_ERROR:
// can get during shutdown
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_DEVICE_DATA_ERROR\n"));
break;
case STATUS_UNSUCCESSFUL:
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_UNSUCCESSFUL\n"));
break;
case STATUS_INSUFFICIENT_RESOURCES:
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_INSUFFICIENT_RESOURCES\n"));
break;
case STATUS_INVALID_PARAMETER:
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_INVALID_PARAMETER\n"));
break;
case STATUS_CANCELLED:
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_CANCELLED\n"));
break;
case STATUS_DEVICE_NOT_CONNECTED:
// can get during shutdown
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_DEVICE_NOT_CONNECTED\n"));
break;
case STATUS_DEVICE_POWER_FAILURE:
// can get during shutdown
DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl STATUS_DEVICE_POWER_FAILURE\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -