?? cdevice.hpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Module Name:
// CPipe.hpp
//
// Abstract: Implements classes for managing USB devices
//
// CDevice (ADT)
// / \
// CFunction CHub (ADT)
// / \
// CRootHub CExternalHub
//
// Notes:
//
#ifndef __CDEVICE_HPP__
#define __CDEVICE_HPP__
#include <globals.hpp>
#include <sync.hpp>
#include <pipeabs.hpp>
class CHcd;
class CDevice;
class CFunction;
class CHub;
class CRootHub;
class CExternalHub;
class CHcd;
class CDeviceGlobal {
public:
CDeviceGlobal();
~CDeviceGlobal();
BOOL Initialize(IN PVOID pHcd );
void DeInitialize( void );
BOOL ReserveAddress( OUT UCHAR& rAddress );
void FreeAddress( IN const UCHAR address );
// Address 0 function
CritSec_Status Addr0LockEntry(ULONG ulTimeout) { return m_csAddress0Lock.EnterCritSec_Ex(ulTimeout); };
void Addr0LockPrepareDelete() { m_csAddress0Lock.PrepareDeleteCritSec_Ex ();};
void Addr0LockLeave() { m_csAddress0Lock.LeaveCritSec_Ex ();};
//Object Countdown
BOOL ObjCountdownInc () {return m_objCountdown.IncrCountdown (); };
void ObjCountdownDec () { m_objCountdown.DecrCountdown ();};
public:
LPUSBD_ATTACH_PROC GetpUSBDAttachProc() { return m_pUSBDAttachProc; };
LPUSBD_DETACH_PROC GetpUSBDDetachProc() { return m_pUSBDDetachProc; };
LPVOID GetpHcdContext() { return m_pvHcdContext ;};
private:
PVOID m_pHcd;
CRITICAL_SECTION m_csFreeAddressArrayLock;
DWORD m_dwFreeAddressArray[4];
CritSec_Ex m_csAddress0Lock; // critical section when using address 0
Countdown m_objCountdown; // counts stray detach threads
// USBD.dll related variables
HINSTANCE m_hUSBDInstance;
// this procedure is called when new USB devices (functions) are attached
LPUSBD_ATTACH_PROC m_pUSBDAttachProc;
// this procedure is called when USB devices (functions) are detached
LPUSBD_DETACH_PROC m_pUSBDDetachProc;
// OUT param for lpHcdAttachProc call
LPVOID m_pvHcdContext;
#ifdef DEBUG
BOOL g_fAlreadyCalled;
#endif // DEBUG
};
// abstract base class for devices
class CDevice
{
public:
// ****************************************************
// Public Functions for CDevice
// ****************************************************
CDevice();
CDevice( IN const UCHAR address,
IN const USB_DEVICE_INFO& rDeviceInfo,
IN const BOOL fIsLowSpeed,
IN const UCHAR tierNumber,
IN CDeviceGlobal * const pDeviceGlobal);
virtual ~CDevice();
virtual BOOL EnterOperationalState( IN CPipeAbs* const pEndpoint0Pipe ) = 0;
virtual HCD_REQUEST_STATUS OpenPipe( IN const UINT address,
IN LPCUSB_ENDPOINT_DESCRIPTOR const lpEndpointDescriptor,
OUT LPUINT const lpPipeIndex ) = 0;
virtual HCD_REQUEST_STATUS ClosePipe( IN const UINT address,
IN const UINT pipeIndex ) = 0;
virtual HCD_REQUEST_STATUS IssueTransfer(
IN const UINT address,
IN const UINT pipeIndex,
IN LPTRANSFER_NOTIFY_ROUTINE const lpStartAddress,
IN LPVOID const lpvNotifyParameter,
IN const DWORD dwFlags,
IN LPCVOID const lpvControlHeader,
IN const DWORD dwStartingFrame,
IN const DWORD dwFrames,
IN LPCDWORD const aLengths,
IN const DWORD dwBufferSize,
IN_OUT LPVOID const lpvBuffer,
IN const ULONG paBuffer,
IN LPCVOID const lpvCancelId,
OUT LPDWORD const adwIsochErrors,
OUT LPDWORD const adwIsochLengths,
OUT LPBOOL const lpfComplete,
OUT LPDWORD const lpdwBytesTransfered,
OUT LPDWORD const lpdwError ) = 0;
virtual HCD_REQUEST_STATUS AbortTransfer(
IN const UINT address,
IN const UINT pipeIndex,
IN LPTRANSFER_NOTIFY_ROUTINE const lpCancelAddress,
IN LPVOID const lpvNotifyParameter,
IN LPCVOID const lpvCancelId ) = 0;
virtual HCD_REQUEST_STATUS IsPipeHalted( IN const UINT address,
IN const UINT pipeIndex,
OUT LPBOOL const lpbHalted ) = 0;
virtual HCD_REQUEST_STATUS ResetPipe( IN const UINT address,
IN const UINT pipeIndex ) = 0;
virtual void HandleDetach( void ) = 0;
#ifdef DEBUG
void DumpDeviceDescriptor( IN const PUSB_DEVICE_DESCRIPTOR pDescriptor )const;
void DumpConfigDescriptor( IN const PUSB_CONFIGURATION_DESCRIPTOR pDescriptor )const;
void DumpInterfaceDescriptor( IN const PUSB_INTERFACE_DESCRIPTOR pDescriptor )const;
void DumpEndpointDescriptor( IN const PUSB_ENDPOINT_DESCRIPTOR pDescriptor )const;
void DumpExtendedBytes( IN const PBYTE pByteArray, IN const DWORD dwSize )const;
#endif // DEBUG
// ****************************************************
// Public Variables for CDevice
// ****************************************************
private:
// ****************************************************
// Private Functions for CDevice
// ****************************************************
public:
// utility functions for managing NON_CONST_USB_CONFIGURATION structures
BOOL CreateUsbConfigurationStructure( IN NON_CONST_USB_CONFIGURATION& rConfig, IN const PUCHAR pDataBuffer, IN const UINT dataBufferLen )const;
void DeleteUsbConfigurationStructure( IN NON_CONST_USB_CONFIGURATION& rConfig ) const;
// ****************************************************
// Private Variables for CDevice
// ****************************************************
protected:
// ****************************************************
// Protected Functions for CDevice
// ****************************************************
static DWORD CALLBACK TransferDoneCallbackSetEvent( PVOID context );
BOOL AllocatePipeArray( void );
#ifdef DEBUG
virtual const TCHAR* GetDeviceType( void ) const = 0;
#endif // DEBUG
// ****************************************************
// Protected Variables for CDevice
// ****************************************************
CRITICAL_SECTION m_csDeviceLock; // critical section for device
const UCHAR m_address; // address/deviceIndex of this device
USB_DEVICE_INFO m_deviceInfo; // holds device's USB descriptors
const BOOL m_fIsLowSpeed; // indicates if device is low speed
const UCHAR m_tierNumber; // indicates tier # of device (i.e. how far
// it is from the root hub) See the USB spec
// 1.1, section 4.1.1
CDeviceGlobal * const m_pDeviceGlobal;
UCHAR m_maxNumPipes; // size of m_apCPipe array
#define ENDPOINT0_CONTROL_PIPE UCHAR(0) // control pipe is at m_ppCPipe[ 0 ]
#define STATUS_CHANGE_INTERRUPT_PIPE UCHAR(1) // for hubs, status change pipe is m_ppCPipe[ 1 ]
CPipeAbs** m_ppCPipe; // array of pipes for this device
public:
BOOL ReserveAddress( OUT UCHAR& rAddress ) { return m_pDeviceGlobal->ReserveAddress(rAddress); };
void FreeAddress( IN const UCHAR address ) { m_pDeviceGlobal->FreeAddress(address); };
};
// this enum is used in AttachNewDevice
enum DEVICE_CONFIG_STATUS
{
//
// KEEP THIS ARRAY IN SYNC WITH cszCfgStateStrings array below!
//
// these steps are common for both hubs and functions
DEVICE_CONFIG_STATUS_OPENING_ENDPOINT0_PIPE,
DEVICE_CONFIG_STATUS_USING_ADDRESS0,
DEVICE_CONFIG_STATUS_RESET_AND_ENABLE_PORT,
DEVICE_CONFIG_STATUS_SCHEDULING_SET_ADDRESS,
DEVICE_CONFIG_STATUS_LEAVE_ADDRESS0,
DEVICE_CONFIG_STATUS_SCHEDULING_GET_INITIAL_DEVICE_DESCRIPTOR,
DEVICE_CONFIG_STATUS_SCHEDULING_GET_DEVICE_DESCRIPTOR,
DEVICE_CONFIG_STATUS_SETUP_CONFIGURATION_DESCRIPTOR_ARRAY,
DEVICE_CONFIG_STATUS_SCHEDULING_GET_INITIAL_CONFIG_DESCRIPTOR,
DEVICE_CONFIG_STATUS_SCHEDULING_GET_CONFIG_DESCRIPTOR,
DEVICE_CONFIG_STATUS_DETERMINE_CONFIG_TO_CHOOSE,
DEVICE_CONFIG_STATUS_SCHEDULING_SET_CONFIG,
// if ( device is a hub ) {
DEVICE_CONFIG_STATUS_SCHEDULING_GET_INITIAL_HUB_DESCRIPTOR,
DEVICE_CONFIG_STATUS_SCHEDULING_GET_HUB_DESCRIPTOR,
DEVICE_CONFIG_STATUS_CREATE_NEW_HUB,
// } else {
DEVICE_CONFIG_STATUS_CREATE_NEW_FUNCTION,
// }
DEVICE_CONFIG_STATUS_INSERT_NEW_DEVICE_INTO_UPSTREAM_HUB_PORT_ARRAY,
DEVICE_CONFIG_STATUS_SIGNAL_NEW_DEVICE_ENTER_OPERATIONAL_STATE,
DEVICE_CONFIG_STATUS_FAILED,
DEVICE_CONFIG_STATUS_DONE,
DEVICE_CONFIG_STATUS_INVALID // must be last item in list
};
#ifdef DEBUG
static const TCHAR *cszCfgStateStrings[] =
{
//
// KEEP THIS ARRAY IN SYNC WITH DEVICE_CONFIG_STATUS enum above!
//
TEXT("DEVICE_CONFIG_STATUS_OPENING_ENDPOINT0_PIPE"),
TEXT("DEVICE_CONFIG_STATUS_USING_ADDRESS0"),
TEXT("DEVICE_CONFIG_STATUS_RESET_AND_ENABLE_PORT"),
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_SET_ADDRESS"),
TEXT("DEVICE_CONFIG_STATUS_LEAVE_ADDRESS0"),
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_GET_INITIAL_DEVICE_DESCRIPTOR"),
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_GET_DEVICE_DESCRIPTOR"),
TEXT("DEVICE_CONFIG_STATUS_SETUP_CONFIGURATION_DESCRIPTOR_ARRAY"),
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_GET_INITIAL_CONFIG_DESCRIPTOR"),
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_GET_CONFIG_DESCRIPTOR"),
TEXT("DEVICE_CONFIG_STATUS_DETERMINE_CONFIG_TO_CHOOSE"),
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_SET_CONFIG"),
// if ( device is a hub ) {
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_GET_INITIAL_HUB_DESCRIPTOR"),
TEXT("DEVICE_CONFIG_STATUS_SCHEDULING_GET_HUB_DESCRIPTOR"),
TEXT("DEVICE_CONFIG_STATUS_CREATE_NEW_HUB"),
// } else {
TEXT("DEVICE_CONFIG_STATUS_CREATE_NEW_FUNCTION"),
// }
TEXT("DEVICE_CONFIG_STATUS_INSERT_NEW_DEVICE_INTO_UPSTREAM_HUB_PORT_ARRAY"),
TEXT("DEVICE_CONFIG_STATUS_SIGNAL_NEW_DEVICE_ENTER_OPERATIONAL_STATE"),
TEXT("DEVICE_CONFIG_STATUS_FAILED"),
TEXT("DEVICE_CONFIG_STATUS_DONE"),
TEXT("DEVICE_CONFIG_STATUS_INVALID")
};
#define STATUS_TO_STRING(status) (( (status) < DEVICE_CONFIG_STATUS_INVALID) ? \
cszCfgStateStrings[ (status) ] : TEXT("Invalid"))
#endif // DEBUG
// abstract base class for hubs
class CHub : public CDevice
{
public:
// ****************************************************
// Public Functions for CHub
// ****************************************************
CHub( IN const UCHAR address,
IN const USB_DEVICE_INFO& rDeviceInfo,
IN const BOOL fIsLowSpeed,
IN const UCHAR tierNumber,
IN const USB_HUB_DESCRIPTOR& rUsbHubDescriptor,
IN CHcd * const pCHcd );
virtual ~CHub();
void HandleDetach( void );
HCD_REQUEST_STATUS OpenPipe( IN const UINT address,
IN LPCUSB_ENDPOINT_DESCRIPTOR const lpEndpointDescriptor,
OUT LPUINT const lpPipeIndex );
HCD_REQUEST_STATUS ClosePipe( IN const UINT address,
IN const UINT pipeIndex );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -