📄 rwusb.cpp
字号:
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 + -