📄 cdevice.cpp
字号:
// Notes: Calling this function directly is rather useless (it will
// just have the same effect as SetEvent( context ) ), so
// it should only be used as a callback
// ******************************************************************
{
DEBUGCHK( context );
SetEvent( (HANDLE) context );
return 0;
}
// ******************************************************************
CDevice::CDevice( IN const UCHAR address,
IN const USB_DEVICE_INFO& rDeviceInfo,
IN const BOOL fIsLowSpeed,IN const BOOL fIsHighSpeed,
IN const UCHAR tierNumber,
IN CDeviceGlobal * const pDeviceGlobal ,
IN CHub * const pAttachedHub,const UCHAR sAttachedPort)
//
// Purpose: Constructor for CDevice
//
// Parameters: address - USB address of this device. This will also be
// used as the device's index number when
// communicating with USBD
//
// rDeviceInfo- object containing device's USB descriptors
//
// fIsLowSpeed - indicates whether this device is low speed
//
// tierNumber - indicates how far away this device is from
// the root hub
//
// Returns: Nothing.
//
// Notes: Do not initialize static variables here. Do that in
// the Initialize() routine
// ******************************************************************
: m_address( address ) // USB address of this device
, m_deviceInfo( rDeviceInfo ) // USB descriptors/information about this device
, m_fIsLowSpeed( fIsLowSpeed ) // indicates TRUE for low speed devices
, m_fIsHighSpeed(fIsHighSpeed)
, m_tierNumber( tierNumber ) // tier number of device (0 for root hub, 1 for first tier, etc)
, m_pDeviceGlobal (pDeviceGlobal )
, m_pAttachedHub (pAttachedHub)
, m_sAttachedPort(sAttachedPort)
, m_maxNumPipes( 0 ) // current size of m_ppCPipe array
, m_ppCPipe( NULL ) // dynamically allocated array of pointers to open pipes
{
DEBUGMSG( ZONE_DEVICE && ZONE_VERBOSE, (TEXT("+CDevice::CDevice\n")) );
m_fIsSuspend = FALSE;
DEBUGCHK( m_deviceInfo.dwCount == sizeof( USB_DEVICE ) &&
m_deviceInfo.Descriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE &&
m_deviceInfo.Descriptor.bLength == sizeof( USB_DEVICE_DESCRIPTOR ) &&
address <= USB_MAX_ADDRESS &&
tierNumber <= USB_MAXIMUM_HUB_TIER + 1 );
InitializeCriticalSection( &m_csDeviceLock );
DEBUGMSG( ZONE_DEVICE && ZONE_VERBOSE, (TEXT("-CDevice::CDevice\n")) );
}
// ******************************************************************
CDevice::~CDevice( )
//
// Purpose: Destructor for CDevice
//
// Parameters: None
//
// Returns: Nothing.
//
// Notes: Do not delete static variables here. Do that in
// DeInitialize();
// ******************************************************************
{
DEBUGMSG( ZONE_DEVICE && ZONE_VERBOSE, (TEXT("+CDevice::~CDevice\n")) );
// delete m_deviceInfo structure
if ( m_deviceInfo.lpConfigs != NULL ) {
DEBUGCHK( m_deviceInfo.Descriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE &&
m_deviceInfo.Descriptor.bLength == sizeof( USB_DEVICE_DESCRIPTOR ) &&
m_deviceInfo.dwCount == sizeof( USB_DEVICE_INFO ) &&
m_deviceInfo.Descriptor.bNumConfigurations > 0 );
for ( UINT config = 0; config < m_deviceInfo.Descriptor.bNumConfigurations; config++ ) {
DeleteUsbConfigurationStructure( m_deviceInfo.lpActiveConfig[ config ] );
}
delete [] m_deviceInfo.lpConfigs;
m_deviceInfo.lpConfigs = NULL;
}
m_deviceInfo.lpActiveConfig = NULL;
#ifdef DEBUG
{
DEBUGCHK( (m_ppCPipe == NULL && m_maxNumPipes == 0) ||
(m_ppCPipe != NULL && m_maxNumPipes > 0) );
// all pipes should have been closed/deleted by HandleDetach
for ( UCHAR pipe = 0; m_ppCPipe && pipe < m_maxNumPipes; pipe++ ) {
DEBUGCHK( m_ppCPipe[ pipe ] == NULL );
}
}
#endif // DEBUG
delete [] m_ppCPipe;
m_ppCPipe = NULL;
m_maxNumPipes = 0;
// free address
FreeAddress( m_address );
// nothing to be done with any of these:
// m_deviceInfo; // holds device's USB descriptors
// m_fIsLowSpeed; // indicates if device is low speed
// m_tierNumber; // indicates tier # of device
DeleteCriticalSection( &m_csDeviceLock );
DEBUGMSG( ZONE_DEVICE && ZONE_VERBOSE, (TEXT("-CDevice::~CDevice\n")) );
}
// ******************************************************************
CHub * CDevice::GetUSB2TT(PUCHAR pTTAddr, PUCHAR pTTPort)
//
// Purpose: Found Transaction Translate for Full Speed Device.
// Returns: The Hub object where this TT located
//
// ******************************************************************
{
if (!m_fIsHighSpeed) {
CHub * pHub = m_pAttachedHub;
UCHAR sAttachedPort = m_sAttachedPort;
while (pHub!=NULL && pHub->m_fIsHighSpeed!=TRUE) {
sAttachedPort = pHub->m_sAttachedPort;
pHub = pHub->m_pAttachedHub;
}
if (pHub) {
if (pTTAddr)
*pTTAddr = pHub->m_address;
if (pTTPort)
*pTTPort = sAttachedPort;
}
return pHub;
}
return NULL;
}
// ******************************************************************
BOOL CDevice::CreateUsbConfigurationStructure( IN NON_CONST_USB_CONFIGURATION& rConfig, IN const PUCHAR pDataBuffer, IN const UINT dataBufferLen ) const
//
// Purpose: Fill in rConfig using data from the given pDataBuffer
//
// Parameters: rConfig - reference to NON_CONST_USB_CONFIGURATION structure to fill in
//
// pDataBuffer - data buffer from which to create NON_CONST_USB_CONFIGURATION.
// This should have been the data retrieved from the USB
// device's GET_CONFIGURATION_DESCRIPTOR request
//
// dataBufferLen - length of pDataBuffer
//
// Returns: TRUE if configuration set properly, else FALSE
//
// Notes: This should be called after the Descriptor field of the configuration
// has already been filled in
//
// This function is protected
// ******************************************************************
{
DEBUGMSG( ZONE_DESCRIPTORS && ZONE_VERBOSE, (TEXT("+CDevice::CreateUsbConfigurationStructure\n")));
DEBUGCHK( pDataBuffer != NULL &&
dataBufferLen == rConfig.Descriptor.wTotalLength );
PUSB_CONFIGURATION_DESCRIPTOR pusbConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR) pDataBuffer;
DEBUGCHK( memcmp( &rConfig.Descriptor, pusbConfigDesc, sizeof( USB_CONFIGURATION_DESCRIPTOR ) ) == 0 );
#ifdef DEBUG
DumpConfigDescriptor( &rConfig.Descriptor );
#endif // DEBUG
rConfig.dwNumInterfaces = 0;
rConfig.lpbExtended = NULL;
rConfig.lpInterfaces = NULL;
BOOL retval = FALSE;
if ( pusbConfigDesc != NULL &&
pusbConfigDesc->wTotalLength == rConfig.Descriptor.wTotalLength &&
dataBufferLen == pusbConfigDesc->wTotalLength &&
pusbConfigDesc->bLength >= sizeof( USB_CONFIGURATION_DESCRIPTOR ) &&
pusbConfigDesc->bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE ) {
UINT offset = pusbConfigDesc->bLength;
PUSB_COMMON_DESCRIPTOR pusbCommon = NULL;
// first step - count number of extended bytes for this config descriptor,
// and copy data if needed
{
UINT configDescExtendedBytes = 0;
while ( offset + configDescExtendedBytes < dataBufferLen ) {
pusbCommon = (PUSB_COMMON_DESCRIPTOR)(pDataBuffer + offset + configDescExtendedBytes );
if ( pusbCommon->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE ) {
configDescExtendedBytes += pusbCommon->bLength;
} else {
break;
}
}
// next, copy Config Descriptor's extended bytes
if ( configDescExtendedBytes > 0 ) {
rConfig.lpbExtended = new BYTE[ configDescExtendedBytes ];
if ( rConfig.lpbExtended == NULL ) {
goto configDescMemoryError;
}
memcpy( rConfig.lpbExtended, pDataBuffer + offset, configDescExtendedBytes );
offset += configDescExtendedBytes;
#ifdef DEBUG
DumpExtendedBytes( rConfig.lpbExtended, configDescExtendedBytes );
#endif // DEBUG
}
}
// second step - get the number of interfaces for this configuration
// note - this isn't always the same as the bNumInterfaces field of
// rConfig.Descriptor, due to Alternate settings for Interfaces
{
UINT x = 0; // temporary counter
DEBUGCHK( rConfig.dwNumInterfaces == 0 );
while ( offset + x + sizeof( USB_INTERFACE_DESCRIPTOR ) < dataBufferLen ) {
pusbCommon = (PUSB_COMMON_DESCRIPTOR)(pDataBuffer + offset + x);
if ( pusbCommon->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE ) {
rConfig.dwNumInterfaces++;
}
x += pusbCommon->bLength;
}
}
// next - create array for INTERFACE objects
DEBUGCHK( rConfig.lpInterfaces == NULL );
if ( rConfig.dwNumInterfaces > 0 ) {
// allocate this many interface objects
rConfig.lpInterfaces = new NON_CONST_USB_INTERFACE[ rConfig.dwNumInterfaces ];
if ( rConfig.lpInterfaces == NULL ) {
goto configDescMemoryError;
}
memset( rConfig.lpInterfaces, 0, rConfig.dwNumInterfaces * sizeof( NON_CONST_USB_INTERFACE ) );
for ( UCHAR interfaceNumber = 0; interfaceNumber < rConfig.dwNumInterfaces; interfaceNumber++ ) {
NON_CONST_USB_INTERFACE & rInterface = rConfig.lpInterfaces[ interfaceNumber ];
rInterface.dwCount = sizeof( NON_CONST_USB_INTERFACE );
// for each interface,
// 1) Copy the interface descriptor
// 2) Allocate and copy any extended bytes
// 3) Allocate room for endpoints, if any
// 4) Copy over endpoints -
// for each endpoint:
// a) copy the endpoint descriptor
// b) copy any extended bytes
// we should now be pointing to a complete USB_INTERFACE_DESCRIPTOR
DEBUGCHK( offset + sizeof( USB_CONFIGURATION_DESCRIPTOR ) <= dataBufferLen );
PUSB_INTERFACE_DESCRIPTOR pusbInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)(pDataBuffer + offset);
DEBUGCHK( pusbInterfaceDesc->bLength >= sizeof( USB_INTERFACE_DESCRIPTOR ) &&
pusbInterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE );
// 1) copy interface descriptor, and skip over it
memcpy( &rInterface.Descriptor, pusbInterfaceDesc, sizeof( USB_INTERFACE_DESCRIPTOR ) );
offset += pusbInterfaceDesc->bLength;
#ifdef DEBUG
DumpInterfaceDescriptor( &rInterface.Descriptor );
#endif // DEBUG
// 2) copy any extended info, if it exists
{
UINT interfaceDescExtendedBytes = 0;
while ( offset + interfaceDescExtendedBytes < dataBufferLen ) {
pusbCommon = (PUSB_COMMON_DESCRIPTOR)(pDataBuffer + offset + interfaceDescExtendedBytes);
if ( pusbCommon->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE &&
pusbCommon->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE &&
offset + interfaceDescExtendedBytes + pusbCommon->bLength <= dataBufferLen ) {
interfaceDescExtendedBytes += pusbCommon->bLength;
} else {
break;
}
}
DEBUGCHK( rInterface.lpbExtended == NULL );
if ( interfaceDescExtendedBytes > 0 ) {
rInterface.lpbExtended = new BYTE[ interfaceDescExtendedBytes ];
if ( rInterface.lpbExtended == NULL ) {
goto configDescMemoryError;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -