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

📄 ezusbinttransfer.h

📁 DriverStdio的一个USB驱动程序
💻 H
字号:
// EzUsbIntTransfer.h
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060  USA
//
// Copyright (c) 1999 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================

#ifndef ___KUsbInterruptTransfer___
#define ___KUsbInterruptTransfer___

//This is the return value status codes
//for client's OnInterrupt callback function
enum ON_INTERRUPT_STATUS 
{
	ON_INTERRUPT_SUCCESS = 0,
	ON_INTERRUPT_SETUP_CALLED,
	ON_INTERRUPT_FAILURE
};

//This is the prototype for the client's
//OnInterrupt callback function
typedef 
	ON_INTERRUPT_STATUS 
		(__stdcall * USB_INTERRUPT_CALLBACK)(
			PURB pUrb,
			PVOID pContext
			);

//Forward declaration
class KUsbInterruptTransfer;

//This is context for completion routine 
typedef struct _INT_COMPLETION_INFO
{
	KUsbInterruptTransfer* m_pClass;
	PURB m_pUrb;
	USB_INTERRUPT_CALLBACK m_pfnOnInterrupt;
	PVOID m_pClientContext;

} INT_COMPLETION_INFO, *PINT_COMPLETION_INFO;



//=============================================================================
// class KUsbInterruptTransfer
//
// This class encapsulates an interrupt transfer for a device on the USB.
// The basic idea of interrupt transfers on USB is that the device will 
// asynchronously signal the USB system on the host for a device specific 
// reason.  For devices that could potentially interrupt at any time, there
// must be an active Interrupt URB at all times.  The host will poll the 
// hardware at the Interval frequency stored in the Pipe object.
//
// After constructing this object, clients can call method StartPolling to 
// initiate continuous Interrupt
// Transfers for the device.  Clients provide an OnInterrupt handler that will 
// be called from the completion routine when an Interrupt Transfer is 
// successfully completed.  By returning a successful status code from the 
// OnInterrupt handler, another URB is sent to the device.  Clients can call  
// StopPolling to stop the continuous Interrupt transfers.
//
//	USAGE:
//
//	Allocate the object dynamically or make it a member of the device sub-class
//	Implement the OnInterrupt callback function in your driver.
//	Provide a transfer buffer for use in the URB.
//	Call StartPolling() to start sending Interrupt transfer requests to the device
//	The OnInterrupt handler will be called when the URB is successfully completed.
//		Use the PURB parameter to obtain the data from the device.  Return a  
//		successful status code to send another URB to the device.  Return a 
//		failure status to stop sending an URB to the device.
//		Optionally call SetupNextTransfer() to pass a different buffer for the 
//		transfer to the device for use in the URB.
//	Call StopPolling() to stop sending Interrupt transfer requests to the device
//		
class KUsbInterruptTransfer
{
//Constructors/Destructors
public:

	SAFE_DESTRUCTORS

	KUsbInterruptTransfer(
		KUsbLowerDevice* Dev,
		KUsbPipe* InterruptPipe,
		BOOLEAN bShortOk=TRUE
		);

	KUsbInterruptTransfer(void);

	NTSTATUS Initialize(
		KUsbLowerDevice* Dev,
		KUsbPipe* InterruptPipe,
		BOOLEAN bShortOk=TRUE
		);

	~KUsbInterruptTransfer(void);

//methods
public:

	//This initiates a USB interrupt transfer that is recycled (MDL form)
	NTSTATUS StartPolling(
		KMemory& Mdl,
		ULONG Length,
		USB_INTERRUPT_CALLBACK pfnOnInterrupt, 
		PVOID pClientContext=NULL
		);

	//This initiates a USB interrupt transfer that is recycled (PVOID form)
	NTSTATUS StartPolling(
		PVOID Buffer,
		ULONG Length,
		USB_INTERRUPT_CALLBACK pfnOnInterrupt, 
		PVOID pClientContext=NULL
		);

	//client's OnInterrupt handler can call this to update buffers
	//after a completed transfer (during the callback ISR) (PVOID form)
	void SetupNextTransfer(
		PVOID Buffer,
		ULONG Length
		);

	//client's OnInterrupt handler can call this to update buffers
	//after a completed transfer (during the callback ISR) (MDL form)
	void SetupNextTransfer(
		KMemory& Mdl,
		ULONG Length
		);

	void StopPolling(void);

	MEMBER_COMPLETEIRPWITHCONTEXT( INT_COMPLETION_INFO, InterruptTransferComplete )

//Accessors
public:

	ULONG InterruptsReceived(void) {return m_NumInterrupts;}
	NTSTATUS Status(void) {return m_CtorStatus;}

//data members
protected:

	//URB continuously recycled
	PURB		m_pIntUrb;
	//IRP continuously recycled
	KIrp		m_KIrp;
	//Pipe to submit the request 
	KUsbPipe*	m_InterruptPipe;
	//Flag to set SHORT_TRANSFER_OK flag in URB
	BOOLEAN		m_bShortOk;
	//Number of stacks 
	CCHAR		m_Stacks;
	NTSTATUS	m_CtorStatus;
	PVOID		m_pClientContext;
	//Counter of number of interrupts
	ULONG		m_NumInterrupts;
	//Flag indicating that the user has requested a stop
	LONG		m_lStopRequested;
	//Flag indicating that an IRP is outstanding
	LONG		m_lPolling;
};



inline KUsbInterruptTransfer::KUsbInterruptTransfer(void) :
	m_pIntUrb(NULL),
	m_KIrp(),
	m_InterruptPipe(NULL),
	m_bShortOk(FALSE),
	m_Stacks(0),
	m_CtorStatus(STATUS_SUCCESS),
	m_pClientContext(NULL),
	m_NumInterrupts(0),
	m_lStopRequested(0),
	m_lPolling(0)
{
}


inline KUsbInterruptTransfer::~KUsbInterruptTransfer(void)
{
	delete m_pIntUrb;

	if (m_KIrp.m_Irp)
		m_KIrp.Deallocate(m_KIrp);
}


//client's OnInterrupt handler can call this to update buffer
//to use during transfer after a completed transfer  (PVOID form)
inline void KUsbInterruptTransfer::SetupNextTransfer(
	PVOID Buffer,
	ULONG Length
	)
{
	m_InterruptPipe->BuildInterruptTransfer(
		Buffer,
		Length,
		m_bShortOk,
		NULL,
		m_pIntUrb
		);

	m_KIrp.Reuse();
}

//client's OnInterrupt handler can call this to update buffer
//to use during transfer after a completed transfer (MDL form)
inline void KUsbInterruptTransfer::SetupNextTransfer(
	KMemory& Mdl,
	ULONG Length
	)
{
	m_InterruptPipe->BuildInterruptTransfer(
		Mdl,
		Length,
		m_bShortOk,
		NULL,
		m_pIntUrb
		);

	m_KIrp.Reuse();
}

//client's can call this method to cancel an outstanding URB
//on the device.  
inline void KUsbInterruptTransfer::StopPolling(void)
{
	InterlockedExchange(&m_lStopRequested, 1);
	if( INTERLOCKED_COMPARE_EXCHANGE(&m_lPolling, 1, 1) )
		IoCancelIrp(m_KIrp);
}


#endif //#ifndef ___KUsbInterruptTransfer___
	

⌨️ 快捷键说明

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