⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rwusb.cpp

📁 一个无线网卡的驱动程序,基于win2
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 如果清除掉所有的挂起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 + -