📄 rwusb.cpp
字号:
//
((PUSB_INFO) Adapter->pUsbInfo)->UsbConfigurationHandle =
selurb->UrbSelectConfiguration.ConfigurationHandle;
if ( NULL == ((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface )
{
((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface = MemAlloc(Interface->Length);
}
if ( NULL != ((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface) {
ULONG j;
//
// 保存该设备的接口信息
//
NdisMoveMemory(((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface, Interface, Interface->Length); // 从调用者提供的位置将指定数量的字节拷贝到另一个地方
//
// Dump the interface to the debugger
//
DEBUGMSG(DBG_FUNC,("---------After Select Config \n"));
DEBUGMSG(DBG_FUNC,("NumberOfPipes 0x%x\n", ((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->NumberOfPipes));
DEBUGMSG(DBG_FUNC,("Length 0x%x\n", ((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->Length));
DEBUGMSG(DBG_FUNC,("Alt Setting 0x%x\n", ((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->AlternateSetting));
DEBUGMSG(DBG_FUNC,("Interface Number 0x%x\n", ((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->InterfaceNumber));
DEBUGMSG(DBG_FUNC,("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->Class,
((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->SubClass,
((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->Protocol));
//
// 查询Bulk in和out的管道,保存其句柄
//
for (j=0; j<Interface->NumberOfPipes; j++)
{
PUSBD_PIPE_INFORMATION pipeInformation;
pipeInformation = &((PUSB_INFO) Adapter->pUsbInfo)->UsbInterface->Pipes[j];
//
// 查找Bulk in和out的管道
//
if ( UsbdPipeTypeBulk == pipeInformation->PipeType )
{
// endpoint address with bit 0x80 set are input pipes, else output
if ( USB_ENDPOINT_DIRECTION_IN( pipeInformation->EndpointAddress ) )
{
Adapter->BulkInPipeHandle = pipeInformation->PipeHandle; // 用于以后的USBDI调用的句柄
}
if ( USB_ENDPOINT_DIRECTION_OUT( pipeInformation->EndpointAddress ) ) {
Adapter->BulkOutPipeHandle = pipeInformation->PipeHandle;
}
}
if ( UsbdPipeTypeInterrupt == pipeInformation->PipeType )
{
if ( USB_ENDPOINT_DIRECTION_IN( pipeInformation->EndpointAddress ) )
{
Adapter->InterruptInPipeHandle = pipeInformation->PipeHandle;
Adapter->IntInternalTime = pipeInformation->Interval;
}
}
DEBUGMSG(DBG_FUNC,("---------\n"));
DEBUGMSG(DBG_FUNC,("PipeType 0x%x\n", pipeInformation->PipeType));
DEBUGMSG(DBG_FUNC,("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
DEBUGMSG(DBG_FUNC,("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
DEBUGMSG(DBG_FUNC,("Interval 0x%x\n", pipeInformation->Interval));
DEBUGMSG(DBG_FUNC,("Handle 0x%x\n", pipeInformation->PipeHandle));
DEBUGMSG(DBG_FUNC,("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
}
DEBUGMSG(DBG_FUNC,("---------\n"));
}
}
//
// 最好找到input和output的bulk传输管道
//
ASSERT( Adapter->BulkInPipeHandle && Adapter->BulkOutPipeHandle );
if (selurb)
{
// 不要调用MemFree(),因为缓冲区是由USBD_CreateConfigurationRequest
// 分配的,而不是MemAlloc()
ExFreePool(selurb);
}
DEBUGMSG(DBG_FUNC,(" -SelectInterface (%x)\n", ntStatus));
return ntStatus;
}
/*****************************************************************************
//
//
// StartDevice
//
// USB设备的初始化例程,完成USB外设与主机控制器(HCD)的通信
// 该例程需要设备描述符并且配置设备
//
//
//
*****************************************************************************/
NTSTATUS
StartDevice(
IN PUSB_DEVICE DeviceExt
)
{
PUSB_DEVICE Adapter;
NTSTATUS ntStatus;
PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
PURB urb;
ULONG size;
DEBUGMSG( DBG_FUNC, (" +StartDevice()\n"));
Adapter = DeviceExt;
urb = MemAlloc(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
DEBUGCOND( DBG_ERR,!urb, ("StartDevice() FAILED MemAlloc() for URB\n"));
if (urb)
{
size = sizeof(USB_DEVICE_DESCRIPTOR);
deviceDescriptor = MemAlloc(size);
DEBUGCOND( DBG_ERR, !deviceDescriptor, ("StartDevice() FAILED MemAlloc() for deviceDescriptor\n"));
if (deviceDescriptor)
{
UsbBuildGetDescriptorRequest( // 用必要的参数去格式化一个URB,以便从主机控制器驱动程序(HCD)上获得描述符信息
urb, // 指向一个URB,为了得到HCD描述符请求而对URB进行了格式化处理
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST), // 指定URB的长度(字节数)
USB_DEVICE_DESCRIPTOR_TYPE, // 指定类型
0, // 指定即将得到的设备定义描述符索引
0, // 指定即将获得的描述符语言ID
deviceDescriptor, // 指向一个接收描述符数据的驻留缓冲区
NULL, // 指向一个描述接收描述符数据的驻留缓冲区
size, // 指定缓冲区的大小
NULL); // 指向一个已由调用程序初始化的URB
ntStatus = CallUSBD(DeviceExt, urb);
DEBUGCOND( DBG_ERR, !NT_SUCCESS(ntStatus), ("StartDevice() FAILED CallUSBD (DeviceExt, urb)\n"));
if (NT_SUCCESS(ntStatus))
{
DEBUGMSG( DBG_FUNC,("Device Descriptor = %x, len %x\n",
deviceDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength));
DEBUGMSG( DBG_FUNC,("-------------------------\n"));
DEBUGMSG( DBG_FUNC,("bLength %d\n", deviceDescriptor->bLength));
DEBUGMSG( DBG_FUNC,("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
DEBUGMSG( DBG_FUNC,("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
DEBUGMSG( DBG_FUNC,("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
DEBUGMSG( DBG_FUNC,("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
DEBUGMSG( DBG_FUNC,("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
DEBUGMSG( DBG_FUNC,("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
DEBUGMSG( DBG_FUNC,("idVendor 0x%x\n", deviceDescriptor->idVendor));
DEBUGMSG( DBG_FUNC,("idProduct 0x%x\n", deviceDescriptor->idProduct));
DEBUGMSG( DBG_FUNC,("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
DEBUGMSG( DBG_FUNC,("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
DEBUGMSG( DBG_FUNC,("iProduct 0x%x\n", deviceDescriptor->iProduct));
DEBUGMSG( DBG_FUNC,("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
DEBUGMSG( DBG_FUNC,("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
}
}
else
{
// if we got here we failed to allocate deviceDescriptor
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus))//device->deviceExt
{
((PUSB_INFO) Adapter->pUsbInfo)->UsbDeviceDescriptor = deviceDescriptor;
Adapter->IdVendor = ((PUSB_INFO) Adapter->pUsbInfo)->UsbDeviceDescriptor->idVendor;
}
MemFree(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
}
else
{
// if we got here we failed to allocate the urb
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus))
{
ntStatus = ConfigureDevice(DeviceExt);
DEBUGCOND( DBG_ERR,!NT_SUCCESS(ntStatus),("StartDevice ConfigureDevice() FAILURE (%x)\n", ntStatus));
}
if (NT_SUCCESS(ntStatus)) {
DeviceExt->fDeviceStarted = TRUE;
}
DEBUGMSG( DBG_FUNC, (" -StartDevice (%x)\n", ntStatus));
return ntStatus;
}
/*****************************************************************************
//
//
// StopDevice
//
// 终止USB设备的例程
//
//
//
*****************************************************************************/
NTSTATUS
StopDevice(
IN PUSB_DEVICE DeviceExt
)
{
PUSB_DEVICE Adapter;
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
ULONG size;
DEBUGMSG( DBG_FUNC,(" +StopDevice\n"));
Adapter = DeviceExt;
//
// 发送一个带有空指针的URB,关闭配置,置设备为非配置状态
//
size = sizeof(struct _URB_SELECT_CONFIGURATION);
urb = MemAlloc(size);
if (urb)
{
UsbBuildSelectConfigurationRequest( // 用必需的参数去格式化URB,以便选择USB设备上的配置
urb, // 指向一个被格式化为选择配置请求的URB
(USHORT) size, // 指定URB的大小(字节数)
NULL); // 指向一个初始化的USB配置描述符,此描述符标志着设备按配置被设置。如果是NULL,设备将会被设置为非配置状态
ntStatus = CallUSBD(DeviceExt, urb);
DEBUGCOND( DBG_ERR,!NT_SUCCESS(ntStatus),("StopDevice() FAILURE Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));
DEBUGCOND( DBG_WARN,NT_SUCCESS(ntStatus),("StopDevice() SUCCESS Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));
MemFree(urb, sizeof(struct _URB_SELECT_CONFIGURATION));
}
else
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
DEBUGMSG( DBG_FUNC,(" -StopDevice (%x) \n ", ntStatus));
return ntStatus;
}
/*****************************************************************************
//
//
// ResetPipeCallback
//
// 重启管道的回调例程
//
//
//
*****************************************************************************/
VOID
ResetPipeCallback (
IN PUSB_WORK_ITEM pWorkItem
)
{
PUSB_DEVICE Adapter;
HANDLE Pipe;
NTSTATUS ntStatus;
Adapter = (PUSB_DEVICE) pWorkItem->pDevice;
Pipe = ( HANDLE ) pWorkItem->InfoBuf;
if( Pipe == Adapter->BulkInPipeHandle )
{
ASSERT( TRUE == Adapter->fPendingReadClearStall );
ResetPipe( Adapter, Pipe );
CancelPendingReadIo(Adapter, TRUE );
//StopDevice( device ); // select the NULL interface
//ntStatus = SelectInterface( device, // re-select our real interface
// ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor);
InterlockedExchange( &Adapter->fPendingReadClearStall, FALSE );
}
else if( Pipe == Adapter->BulkOutPipeHandle )
{
ASSERT( TRUE == Adapter->fPendingWriteClearStall );
ResetPipe( Adapter, Pipe );
CancelPendingWriteIo( Adapter );
//ResetPipe( device, Pipe );
//StopDevice( device ); // select the NULL interface
//ntStatus = SelectInterface( device, // re-select our real interface
// ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor);
InterlockedExchange( &Adapter->fPendingWriteClearStall, FALSE );
}
else
{
ASSERT( 0 );
}
FreeWorkItem( pWorkItem );
}
/*****************************************************************************
//
//
// FreeWorkItem
//
// 释放指定的工作项目
//
//
//
*****************************************************************************/
VOID
FreeWorkItem(
PUSB_WORK_ITEM pItem // 指向一个私有IO_WORKITEM结构的指针,该结构由先前的IoAllocateWorkItem调用返回的
)
{
InterlockedExchange( (PLONG) &pItem->fInUse, FALSE );
}
/*****************************************************************************
//
//
// CancelPendingIo
//
// 清除挂起的IO操作例程
// 如果清除掉所有的挂起IO操作,则返回值为真,否则为假
//
//
//
*****************************************************************************/
BOOLEAN
CancelPendingIo(
IN PUSB_DEVICE Adapter
)
{
BOOLEAN cRes = TRUE;
DEBUGMSG( DBG_FUNC, (" +CancelPendingIo(), fDeviceStarted =%d\n", Adapter->fDeviceStarted)); // chag to FUNC later?
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
if ( Adapter->fDeviceStarted )
{
CancelPendingReadIo(Adapter, TRUE);
CancelPendingWriteIo(Adapter);
}
DEBUGMSG( DBG_FUNC, (" -CancelPendingIo()\n")); // chag to FUNC later?
return (BOOLEAN) cRes;
}
/*****************************************************************************
//
//
// CancelPendingReadIo
//
// 清除挂起的IO读操作例程
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -