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

📄 rwusb.cpp

📁 一个无线网卡的驱动程序,基于win2
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            break;

        default:
            DEBUGMSG(DBG_ERR, (" UsbIoCompleteControl UNKNOWN WEIRD STATUS = 0x%x, dec %d\n",status,status ));
            //ASSERT( 0 );

            break;
    }


    UsbDecIoCount( Adapter );  // 跟踪挂起的IRP数目

    if  ( pIrp == ((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb ) 
	{
        ASSERT( NULL != ((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb );

        IoFreeIrp( ((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb );

        Adapter->StatusControl =  status; // save status because can't use irp after completion routine is hit!
        KeSetEvent(&Adapter->EventUrb, 0, FALSE);  //signal we're done

    }
	else
	{
        DEBUGMSG( DBG_ERR, (" UsbIoCompleteControl UNKNOWN IRP\n"));
        ASSERT( 0 );
    }



    DEBUGCOND(DBG_ERR, !( NT_SUCCESS( status ) ), ("UsbIoCompleteControl BAD status = 0x%x\n", status));

    DEBUGMSG(DBG_FUNC, ("-UsbIoCompleteControl\n"));


    // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
    // routine (IofCompleteRequest) will stop working on the irp.
    //

    status = STATUS_MORE_PROCESSING_REQUIRED;

    return status;
}

/*****************************************************************************
//
//
// 
// ResetPipe
//
// USB设备管道的重新配置例程
//
//
//
*****************************************************************************/

NTSTATUS
ResetPipe (
    IN PUSB_DEVICE   Adapter,
    IN HANDLE        Pipe
    )
{
    PURB        urb;
    NTSTATUS    ntStatus;

    DEBUGMSG(DBG_ERR, ("  +ResetPipe()\n"));

    // 
	// 为RESET_PIPE请求分配URB
    //
    urb = MemAlloc( sizeof(struct _URB_PIPE_REQUEST));

    if (urb != NULL)
    {
#if 0
        NdisZeroMemory( urb, sizeof (struct _URB_PIPE_REQUEST) );

        DEBUGMSG(DBG_ERR, ("  ResetPipe before ABORT PIPE \n"));

        // 
		// 初始化ABORT_PIPE请求的URB
        //
        urb->UrbHeader.Length   = sizeof (struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
        urb->UrbPipeRequest.PipeHandle = Pipe;

        ntStatus = CallUSBD(Adapter, urb);

        DEBUGCOND(DBG_ERR, !NT_SUCCESS(ntStatus),  ("  ResetPipe ABORT PIPE FAILED \n"));


        DEBUGMSG(DBG_ERR, ("  ResetPipe  before RESET_PIPE \n"));
#endif
        
        NdisZeroMemory( urb, sizeof (struct _URB_PIPE_REQUEST) );

        // 
		// 初始化RESET_PIPE请求的URB
        //
        urb->UrbHeader.Length   = sizeof (struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
        urb->UrbPipeRequest.PipeHandle = (USBD_PIPE_HANDLE) Pipe;

        // 
		// 递交RESET_PIPE请求的URB
        //
        ntStatus = CallUSBD(Adapter, urb);

        DEBUGCOND(DBG_ERR, !NT_SUCCESS(ntStatus),  ("  ResetPipe RESET PIPE FAILED \n"));
        DEBUGCOND(DBG_ERR, NT_SUCCESS(ntStatus),  ("  ResetPipe RESET PIPE SUCCEEDED \n"));
        // 
		// 完成RESET_PIPE请求的URB,释放URB
        //
        ExFreePool(urb);
    }
    else
    {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    DEBUGMSG(DBG_ERR, ("  -ResetPipe %08X\n", ntStatus));
    
	return ntStatus;
}

/*****************************************************************************
//
//
// 
// MyKeWaitForSingleObject
//
// 设置当前线程为等待状态直到给定的调用程序对象被置为信号状态,或直到等待期满
//
//
//
*****************************************************************************/

NTSTATUS MyKeWaitForSingleObject(
    IN  PUSB_DEVICE    Adapter,
    IN  PVOID          EventWaitingFor,
    IN  OUT PIRP       IrpWaitingFor,
    LONGLONG           timeout100ns
)
{
    NTSTATUS         status = STATUS_SUCCESS;
    LARGE_INTEGER    Timeout;
    BOOLEAN          cancelResult;

    if ( timeout100ns )
	{   //if a non-zero timeout was passed in, use it
        Timeout.QuadPart = - ( timeout100ns );

    }
	else
	{
        Timeout.QuadPart = -10000 * 1000 * 3; // default to 3 second relative delay
    }


    DEBUGMSG( DBG_FUNC,(" +MyKeWaitForSingleObject\n "));


    status = KeWaitForSingleObject( 
               EventWaitingFor, // 指向一组指向调度对象(事件、信号量、线程和定时器)的指针,调用者为其提供存储空间
               Executive,// 指明等待原因,驱动程序应当设置这个值为可执行状态
               KernelMode,// 指定调用者是在KernelMode或UserMode
               FALSE,// 定义一个布尔值指明等待状态是否为告警状态,是,则此变量为TRUE,否则为FALSE
               &Timeout); // 指向一个期满值的指针

    if ( IrpWaitingFor && (status != STATUS_SUCCESS))
    {
        // if we get here we timed out and we were passed a PIRP to cancel
        cancelResult = IoCancelIrp( IrpWaitingFor );

        DEBUGCOND( DBG_FUNC, cancelResult,(" MyKeWaitForSingleObject successfully cancelled IRP (%x),cancelResult = %x\n",IrpWaitingFor, cancelResult));
        DEBUGCOND( DBG_ERR, !cancelResult,(" MyKeWaitForSingleObject FAILED to cancel IRP (%x),cancelResult = %x\n",IrpWaitingFor, cancelResult));
    }


    DEBUGCOND( DBG_OUT,( STATUS_TIMEOUT == status ),(" MyKeWaitForSingleObject TIMED OUT\n"));
    DEBUGCOND( DBG_OUT,( STATUS_ALERTED == status ),(" MyKeWaitForSingleObject ALERTED\n"));
    DEBUGCOND( DBG_OUT,( STATUS_USER_APC == status ),(" MyKeWaitForSingleObject USER APC\n"));

    DEBUGMSG( DBG_FUNC,(" -MyKeWaitForSingleObject  (%x)\n", status));
    return status;
}


/*****************************************************************************
//
//
// 
// PassiveLevelThread
//
// 线程
//
//
//
*****************************************************************************/

VOID
PassiveLevelThread(
            IN OUT PVOID Context
            )
{
    NTSTATUS        ntStatus;
    LARGE_INTEGER   Timeout;
    int             i;
    PUSB_WORK_ITEM  pWorkItem;

    // every parameter used here is passed via Device.
    PUSB_DEVICE    Adapter = (PUSB_DEVICE) Context;

    DEBUGMSG(DBG_WARN, ("+PassiveLevelThread\n"));  // change to FUNC later?

    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

    Timeout.QuadPart = -10000 * 1000 * 3; // 3 second relative delay
    //notify this assert
	ASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL);
    
	while ( !Adapter->fKillPassiveLevelThread )
    {

        //
        // The eventPassiveThread is an auto-clearing event, so
        // we don't need to reset the event.
        //

        ntStatus = KeWaitForSingleObject( 
                   &Adapter->EventPassiveThread,
                   Suspended,
                   KernelMode,
                   FALSE,
                   &Timeout);


        for (i = 0; i < NUM_WORK_ITEMS; i++ )
        {
            if ( Adapter->WorkItems[i].fInUse ) 
			{

                Adapter->WorkItems[i].Callback(&(Adapter->WorkItems[i]));
            }
        }


    } // while !fKill

    DEBUGMSG(DBG_ERR, ("    PassiveLevelThread: HALT\n"));

    Adapter->hPassiveThread = NULL;

    DEBUGMSG(DBG_WARN, (" -PassiveLevelThread\n")); // change to FUNC later?
    PsTerminateSystemThread(STATUS_SUCCESS);

}


void DumpStatsEverySec( PUSB_DEVICE Adapter, UINT NumSeconds )
{

#if DBG  //disable unless really need it
    
    static LARGE_INTEGER   LastStatTime = { 0 };
    LARGE_INTEGER          Now;
    LARGE_INTEGER          Elapsed;

    if ( 0 == LastStatTime.QuadPart ) {
        NdisGetCurrentSystemTime( &LastStatTime ); // init
    }

    NdisGetCurrentSystemTime( &Now );

    Elapsed = RtlLargeIntegerSubtract( Now, LastStatTime );

    if ( Elapsed.QuadPart >= ( NumSeconds * USB_100ns_PER_SEC ) ) {

        NdisGetCurrentSystemTime( &LastStatTime );


        DEBUGMSG( DBG_WARN,("\n   ****Dumping statistics every %d seconds\n",NumSeconds));
        DEBUGMSG( DBG_WARN,("    Total  packetsReceived = decimal %d\n",Adapter->packetsReceived));
        DEBUGMSG( DBG_WARN,("    packetsReceivedDropped = decimal %d\n",Adapter->packetsReceivedDropped));
        DEBUGMSG( DBG_WARN,("    packetsReceivedOverflow = decimal %d\n",Adapter->packetsReceivedOverflow));
        DEBUGMSG( DBG_WARN,("    packetsSent = decimal %d\n",Adapter->packetsSent));
        DEBUGMSG( DBG_WARN,("    packetsSentDropped = decimal %d\n",Adapter->packetsSentDropped));
        //DEBUGMSG( DBG_WARN,("    packetsHeldByProtocol = decimal %d\n",Device->packetsHeldByProtocol));
//        DEBUGMSG( DBG_WARN,("    MaxPacketsHeldByProtocol = decimal %d\n",Device->MaxPacketsHeldByProtocol));
//        DEBUGMSG( DBG_WARN,("    MaxLenSendList ever attained = decimal %d\n",Device->MaxLenSendList));
//        DEBUGMSG( DBG_WARN,("    NumTimesRcvListMaxedOut = decimal %d\n",Device->NumTimesRcvListMaxedOut));
//        DEBUGMSG( DBG_WARN,("    NumSendPacketsRejected = decimal %d\n",Device->NumSendPacketsRejected));
//        DEBUGMSG( DBG_WARN,("    #Times SendList que > 1 = decimal %d\n",Device->NumTimesLongerThan1));
//        DEBUGMSG( DBG_WARN,("    Total packet data errors = decimal %d\n",Device->NumDataErrors));
//        DEBUGMSG( DBG_WARN,("    Total bytes sent  = decimal %d\n",Device->TotalBytesSent ));
//        DEBUGMSG( DBG_WARN,("    Total bytes received  = decimal %d\n",Device->TotalBytesReceived ));
//        DEBUGMSG( DBG_WARN,("    NumYesQueryMediaBusyOids = decimal %d\n",Device->NumYesQueryMediaBusyOids));
//        DEBUGMSG( DBG_WARN,("    NumNoQueryMediaBusyOids = decimal %d\n",Device->NumNoQueryMediaBusyOids));
//        DEBUGMSG( DBG_WARN,("    NumSetMediaBusyOids = decimal %d\n",Device->NumSetMediaBusyOids));
//        DEBUGMSG( DBG_WARN,("    NumMediaBusyUsbHeaders = decimal %d\n",Device->NumMediaBusyUsbHeaders));
//        DEBUGMSG( DBG_WARN,("    NumMediaNotBusyUsbHeaders = decimal %d\n",Device->NumMediaNotBusyUsbHeaders));
//        DEBUGMSG( DBG_WARN,("    NumMediaBusyIndications = decimal %d\n",Device->NumMediaBusyIndications));
//        DEBUGMSG( DBG_WARN,("    NumPacketsSentRequiringTurnaroundTime = decimal %d\n",Device->NumPacketsSentRequiringTurnaroundTime));
//        DEBUGMSG( DBG_WARN,("    NumPacketsSentNotRequiringTurnaroundTime = decimal %d\n",Device->NumPacketsSentNotRequiringTurnaroundTime));

    }

#endif // DBG
}


/*****************************************************************************
//
//
// 
// PollingThread
//
// 线程
//
//
//
*****************************************************************************/

VOID
PollingThread(
    IN PVOID   Context
    )
{
    // every parameter used here is passed via device.
    PUSB_DEVICE    Adapter = (PUSB_DEVICE) Context;
    NTSTATUS       Status;
    DEBUGMSG(DBG_WARN, (" +PollingThread\n"));  // change to FUNC later?


    while(!Adapter->fKillPollingThread  )
    {
        if ( Adapter->fReceiving )//Receivebuffer has been initialized

        {

            NTSTATUS ntStatus;
//在UsbCompleteRead中将device->pCurrentRcvBuf=pRcvBuf
            ntStatus = StartUsbRead(Adapter);

            if ( NULL != Adapter->pCurrentRcvBuf)
			{    // flag we were successful    
                 ProcessData(
                            Adapter,
                            Adapter->pCurrentRcvBuf
                            );  // BUGBUG EXPERIMENT?

                Adapter->pCurrentRcvBuf = NULL;
            }

        } // end if

    } // end while

    DEBUGMSG(DBG_WARN, (" -PollingThread\n"));  // change to FUNC later?

    Adapter->hPollingThread = NULL;
    // this thread will finish here
    // if the terminate flag is TRUE
    PsTerminateSystemThread(0);
}

BOOLEAN
InitWdmStuff(
            IN OUT PUSB_DEVICE Adapter
            )
{

    BOOLEAN fRes = TRUE;
    ULONGLONG thisContext;  //make ptr arithmetic 64-bit compatible
    PUSB_CONTEXT pCont;
    int i;

    DEBUGMSG(DBG_FUNC, (" +InitWdmStuff\n"));

	ASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL);
    //
    // Initialize a notification event for signalling PassiveLevelThread.
    //

    KeInitializeEvent(
                &Adapter->EventPassiveThread,
                SynchronizationEvent, // auto-clearing event
                FALSE                 // event initially non-signalled
                );


    KeInitializeEvent(
                &Adapter->EventUrb,
                NotificationEvent,    // non-auto-clearing event
                FALSE                 // event initially non-signalled
                );

    KeInitializeEvent(
                &Adapter->EventIoCtl,
                NotificationEvent,    // non-auto-clearing event
                FALSE                 // event initially non-signalled
                );
   
    ((PUSB_INFO) Adapter->pUsbInfo)->IrpSubmitUrb               = NULL;

    // set urblen to max possible urb size
    Adapter->UrbLen = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
    //Device->UrbLen = MAX( Device->U

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -