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

📄 ch375wdm.c

📁 CH375 是南京沁恒公司开发的一个USB总线的通用接口芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
// 2003.09.08, 2003.12.28, 2004.10.15
//****************************************
//**  Copyright  (C)  W.ch  1999-2004   **
//**  Web:  http://www.winchiphead.com  **
//****************************************
//**  WDM for USB interface chip CH375  **
//**  C, VC5.0, Windows 98 DDK          **
//****************************************
//
// USB总线接口芯片CH375的WDM驱动程序   V1.2
// 南京沁恒电子有限公司  作者: W.ch 2004.10
// CH375-WDM  V1.2 , Support: Ctrl/Bulk/Int
// 运行环境: Windows 98/ME, Windows 2000/XP
// support USB chip: CH372/CH375
//


#define		mTHIS_VERSION			0x12		// 当前版本
#define		mTHIS_VER_STR			"1.2"		// 当前版本字符串

#include	<wdm.h>
#include	<usbdi.h>
#include	<usbdlib.h>


#include	"CH375WDM.H"


typedef	struct	_DEVICE_EXTENSION {				// 定义设备扩展结构
	UNICODE_STRING		mExtDeviceName;			// 设备名称
	PDEVICE_OBJECT		mExtPhysicalTarget;		// 物理设备对象指针
	PDEVICE_OBJECT		mExtNextLowerDevice;	// 下级设备对象指针
	USBD_PIPE_HANDLE	mExtInterUpPipe;		// USB中断数据上传管道的句柄
	USBD_PIPE_HANDLE	mExtDataDownPipe;		// USB数据块下传管道的句柄
	USBD_PIPE_HANDLE	mExtDataUpPipe;			// USB数据块上传管道的句柄
	ULONG				mExtIoCount;			// 计数正在进行的操作,以阻止操作中途停止或者移除设备
	ULONG				mExtDeviceOpen;			// 指示设备被打开的次数
	BOOLEAN				mExtDeviceStart;		// 指示设备启动状态
	BOOLEAN				mExtDeviceRemove;		// 指示设备移除状态
	KEVENT				mExtDownCancelEvent;	// USB数据块下传管道的取消事件
	KEVENT				mExtUpCancelEvent;		// USB数据块上传管道的取消事件
	ULONG				mExtDownTimeout;		// USB数据块下传管道的通讯超时
	ULONG				mExtUpTimeout;			// USB数据块上传管道的通讯超时
} mDEVICE_EXTENSION, *mPDEVICE_EXTENSION;

#define		IO_CH375_INCREMENT		8			// CH375操作后的优先级增量


// 驱动程序说明
UCHAR			mDescription[128] = " CH375 WDM V" mTHIS_VER_STR " "
									" Author : W.ch  "
									"HX.S065  2003.12\xd\xa"
									" www.wch99.com  \xd\xa"
									" Copyright (C) W.ch 1999-2004 \xd\xa\x0";

PDRIVER_OBJECT	mDriverObject = NULL;			// 驱动程序对象,无效则指示系统线程终止


// 子程序说明


NTSTATUS		DriverEntry( PDRIVER_OBJECT iDriverObject, PUNICODE_STRING iRegistryPath );
VOID			mDriverUnload( PDRIVER_OBJECT iDriverObject );
NTSTATUS		mAddDevice( PDRIVER_OBJECT iDriverObject, PDEVICE_OBJECT iPhysicalDeviceObject );
VOID			mRemoveDevice( PDEVICE_OBJECT iDeviceObject );
NTSTATUS		mDispatchCreate( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mDispatchClose( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mDispatchDeviceControl( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mRequestPipe( PDEVICE_OBJECT iDeviceObject, PURB iUrb, USHORT iFunction, ULONG iPipe );
VOID			mCancelCurrentUp( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
VOID			mCancelCurrentDown( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mDispatchCleanup( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mDispatchPower( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mDispatchSystemControl( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mDispatchPnp( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mWaitCompletion( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mCompletionRoutine( PDEVICE_OBJECT iDeviceObject, PIRP iIrp, PVOID iContext );
NTSTATUS		mActiveConfig( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mDeactiveConfig( PDEVICE_OBJECT iDeviceObject, PIRP iIrp );
NTSTATUS		mUsbSubmitUrb( PDEVICE_OBJECT iDeviceObject, PURB iUrb );


// 初始化完成后可丢弃的代码
#ifdef		ALLOC_PRAGMA
#pragma		alloc_text( INIT, DriverEntry )
#endif


NTSTATUS	DriverEntry(  // 驱动程序初始化入口
	PDRIVER_OBJECT	iDriverObject,  // 驱动程序对象
	PUNICODE_STRING	iRegistryPath )
{
	mDriverObject = iDriverObject;  // 保存驱动程序对象
//	while ( mDriverObject );  // 调试
	iDriverObject -> MajorFunction[ IRP_MJ_CREATE ] = mDispatchCreate;  // 创建或者打开设备
	iDriverObject -> MajorFunction[ IRP_MJ_CLOSE ] = mDispatchClose;  // 关闭设备
	iDriverObject -> MajorFunction[ IRP_MJ_DEVICE_CONTROL ] = mDispatchDeviceControl;  // 设备控制
	iDriverObject -> MajorFunction[ IRP_MJ_CLEANUP ] = mDispatchCleanup;  // 取消操作
	iDriverObject -> MajorFunction[ IRP_MJ_POWER ] = mDispatchPower;  // 电源管理
	iDriverObject -> MajorFunction[ IRP_MJ_SYSTEM_CONTROL ] = mDispatchSystemControl;  // 系统WMI接口
	iDriverObject -> MajorFunction[ IRP_MJ_PNP ] = mDispatchPnp;  // 设备PnP操作
	iDriverObject -> DriverUnload = mDriverUnload;  // 卸载驱动程序
	iDriverObject -> DriverExtension -> AddDevice = mAddDevice;  // 检测到新硬件设备
	return( STATUS_SUCCESS );
}

VOID		mDriverUnload(  // 卸载驱动程序
	PDRIVER_OBJECT	iDriverObject )
{
	mDriverObject = NULL;  // 清除驱动程序对象,指示系统线程终止
}

NTSTATUS	mAddDevice(  // 添加新设备的PnP例程
	PDRIVER_OBJECT	iDriverObject,  // 驱动程序对象
	PDEVICE_OBJECT	iPhysicalDeviceObject )
{
	PDEVICE_OBJECT		mDeviceObject = NULL;
	mPDEVICE_EXTENSION	mDeviceExtension;
	NTSTATUS			mStatus = STATUS_INSUFFICIENT_RESOURCES;
	__try {  // 确保退出前的处理
		mStatus = IoCreateDevice( iDriverObject, sizeof( mDEVICE_EXTENSION ), NULL,  // 创建设备对象
								  FILE_DEVICE_UNKNOWN, 0, FALSE, &mDeviceObject );  // 返回的设备对象
		if ( ! NT_SUCCESS( mStatus ) ) __leave;  // 创建设备失败
		mDeviceExtension = mDeviceObject -> DeviceExtension;  // 设备扩展指针
		RtlZeroMemory( mDeviceExtension, sizeof( mDEVICE_EXTENSION ) );  // 清除内存
		mDeviceExtension -> mExtPhysicalTarget = iPhysicalDeviceObject;  // 物理设备的功能设备对象
		mDeviceExtension -> mExtIoCount = 0;  // 清操作计数
		mDeviceExtension -> mExtDeviceOpen = 0;  // 清除设备打开标志
		mDeviceExtension -> mExtDeviceStart = FALSE;  // 清除设备启动标志
		mDeviceExtension -> mExtDeviceRemove = FALSE;  // 清除设备移除标志
		KeInitializeEvent( & mDeviceExtension -> mExtDownCancelEvent, NotificationEvent, FALSE );  // USB数据块下传管道的取消事件
		KeInitializeEvent( & mDeviceExtension -> mExtUpCancelEvent, NotificationEvent, FALSE );  // USB数据块上传管道的取消事件
		mDeviceExtension -> mExtDownTimeout = 0xFFFFFFFF;  // USB数据块下传管道的通讯超时
		mDeviceExtension -> mExtUpTimeout = 0xFFFFFFFF;  // USB数据块上传管道的通讯超时
		mDeviceExtension -> mExtNextLowerDevice = IoAttachDeviceToDeviceStack( mDeviceObject,  // 挂接设备栈,返回下级设备
																			   iPhysicalDeviceObject );  // 指向物理对象
		if ( mDeviceExtension -> mExtNextLowerDevice == NULL ) {  // 挂接设备栈失败
			mStatus = STATUS_UNSUCCESSFUL;  // 返回错误信息
			__leave;
		}
		mStatus = IoRegisterDeviceInterface( iPhysicalDeviceObject, &CH375Guid,  // 注册设备接口
											 NULL, & mDeviceExtension -> mExtDeviceName );  // 保存符号链接名称
		mDeviceObject -> Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;  // 缓冲IO,指示代码可能在分页内存中
		mDeviceObject -> Flags &= ~DO_DEVICE_INITIALIZING;  // 初始化完成
	}
	__finally {  // 退出前的处理
		if ( ! NT_SUCCESS( mStatus ) ) {  // 初始化失败
			mRemoveDevice( mDeviceObject );  // 移除设备
		}
	}
	return( STATUS_SUCCESS );
}

VOID		mRemoveDevice(  // 移除设备
	PDEVICE_OBJECT	iDeviceObject )
{
	ULONG				mDeviceInstance;
	mPDEVICE_EXTENSION	mDeviceExtension;
	if ( iDeviceObject == NULL ) return;  // 设备对象无效
	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	if ( mDeviceExtension -> mExtDeviceName.Buffer != NULL ) {  // 已经注册设备接口
		IoSetDeviceInterfaceState( & mDeviceExtension -> mExtDeviceName, FALSE );  // 禁用设备接口
		RtlFreeUnicodeString( & mDeviceExtension -> mExtDeviceName );  // 释放设备名称缓冲区
		mDeviceExtension -> mExtDeviceName.Buffer = NULL;
	}
	if ( mDeviceExtension -> mExtNextLowerDevice != NULL ) {  // 已经挂接到设备栈
		IoDetachDevice( mDeviceExtension -> mExtNextLowerDevice );  // 撤出设备栈
		mDeviceExtension -> mExtNextLowerDevice = NULL;
	}
	IoDeleteDevice( iDeviceObject );  // 删除设备对象
}

NTSTATUS	mDispatchCreate(  // 新建或者打开
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	InterlockedIncrement( & mDeviceExtension -> mExtDeviceOpen );  // 打开计数增量
	iIrp -> IoStatus.Status = STATUS_SUCCESS;  // 返回操作状态
	iIrp -> IoStatus.Information = 0;
	IoCompleteRequest( iIrp, IO_NO_INCREMENT );  // 完成请求
	return( STATUS_SUCCESS );  // 返回状态
}

NTSTATUS	mDispatchClose(  // 关闭
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	InterlockedDecrement( & mDeviceExtension -> mExtDeviceOpen );  // 关闭则打开计数减量
	iIrp -> IoStatus.Status = STATUS_SUCCESS;  // 返回操作状态
	iIrp -> IoStatus.Information = 0;
	IoCompleteRequest( iIrp, IO_NO_INCREMENT );  // 完成请求
	return( STATUS_SUCCESS );  // 返回状态
}

NTSTATUS	mDispatchDeviceControl(  // 设备控制
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	UCHAR				mRequestType, mRequestCode;
	USHORT				mRequestValue, mRequestIndex;
	ULONG				mControlCode;
	ULONG				mFunction, mLength, mReturn;
	ULONG				mTransferFlags, mParameter;
	LARGE_INTEGER		mWaitTime;
	PLARGE_INTEGER		mTimeout;
	PVOID				mBuffer;
	mPWIN32_COMMAND		mWin32Command;
	NTSTATUS			mStatus, mWaitStatus;
	PIRP				mIrp;
	PURB				mUrb;
	KEVENT				mEvent;
	PKEVENT				mEventArray[2];
	IO_STATUS_BLOCK		mIoStatusBlock;
	PIO_STACK_LOCATION	mCurrentIrpStack;
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	InterlockedIncrement( & mDeviceExtension -> mExtIoCount );  // 操作计数增量,阻止中途停止或者移除设备
	mCurrentIrpStack = IoGetCurrentIrpStackLocation( iIrp );  // 当前栈单元指针
	mControlCode = mCurrentIrpStack -> Parameters.DeviceIoControl.IoControlCode;  // 操作命令
	if ( mControlCode == IOCTL_CH375_COMMAND ) {  // 专用接口
		mStatus = STATUS_SUCCESS;  // 返回状态预置为成功
		mReturn = 0;  // 返回数据长度预置为0
		mUrb = ExAllocatePool( NonPagedPool, sizeof( URB ) );  // 分配内存作为URB请求块
		if (  mUrb != NULL && mCurrentIrpStack -> Parameters.DeviceIoControl.InputBufferLength >= mWIN32_COMMAND_HEAD ) {  // 输入缓冲区长度有效
			mWin32Command = iIrp -> AssociatedIrp.SystemBuffer;  // 命令缓冲区
			mFunction = mWin32Command -> mFunction;  // 功能代码
			mLength = mWin32Command -> mLength;  // 存取长度
			mBuffer = & mWin32Command -> mBuffer[0];  // 数据缓冲区
			switch( mFunction ) {  // 分析功能代码
				case mFuncGetVersion:  // 获取版本号
					while ( mLength >= sizeof( ULONG ) && *(PULONG)mBuffer == 'hc.W' );  // 等待调试工具W.ch
					*(PUCHAR)mBuffer = mTHIS_VERSION;  // 驱动程序版本号
					mReturn = sizeof( UCHAR );  // 返回数据长度
					break;
				case mFuncGetConfig:  // 获取USB设备配置描述符
					UsbBuildGetDescriptorRequest( mUrb, sizeof( struct _URB_CONTROL_DESCRIPTOR_REQUEST ),  // 构造获取描述符URB
												  USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, mBuffer, NULL, mLength, NULL );
					mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
					mReturn = mUrb -> UrbControlDescriptorRequest.TransferBufferLength;  // 实际传输长度
					break;
				case mPipeDeviceCtrl:  // CH375的综合控制管道
					mRequestType = mWin32Command -> mSetupPkt.mUspReqType;  // 请求类型
					mRequestCode = mWin32Command -> mSetupPkt.mUspRequest;  // 请求码
					mRequestValue = mWin32Command -> mSetupPkt.mUspValue;  // 数值参数
					mRequestIndex = mWin32Command -> mSetupPkt.mUspIndex;  // 索引参数
					mLength = mWin32Command -> mSetupPkt.mLength;  // 后续操作的数据长度
					mTransferFlags = ( ( mRequestType & 0x80 ) != 0 ? USBD_TRANSFER_DIRECTION_IN : 0 ) | USBD_SHORT_TRANSFER_OK;  // 传输标志
					switch( mRequestType >> 5 & 0x03 ) {  // 分析请求类型
						case 0:  // 标准请求
							switch( mRequestCode ) {  // 分析请求码
								case USB_REQUEST_CLEAR_FEATURE:  // 清除特性
									UsbBuildFeatureRequest( mUrb, URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE,  // 构造清除特性URB
															mRequestValue, mRequestIndex, NULL );
									mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
									break;
								case USB_REQUEST_SET_FEATURE:  // 设置特性
									UsbBuildFeatureRequest( mUrb, URB_FUNCTION_SET_FEATURE_TO_DEVICE,  // 构造设置特性URB
															mRequestValue, mRequestIndex, NULL );
									mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
									break;
								case USB_REQUEST_GET_STATUS:  // 获取状态
									UsbBuildGetStatusRequest( mUrb, URB_FUNCTION_GET_STATUS_FROM_DEVICE,  // 构造获取状态URB
															  mRequestIndex, mBuffer, NULL, NULL );
									mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
									mReturn = mUrb -> UrbControlGetStatusRequest.TransferBufferLength;  // 实际传输长度
									break;
								case USB_REQUEST_GET_DESCRIPTOR:  // 获取描述符
									mParameter = ( mRequestValue >> 8 ) == 1 ? USB_DEVICE_DESCRIPTOR_TYPE : USB_CONFIGURATION_DESCRIPTOR_TYPE;  // 描述符类型
									UsbBuildGetDescriptorRequest( mUrb, sizeof( struct _URB_CONTROL_DESCRIPTOR_REQUEST ),  // 构造获取描述符URB
																  (UCHAR)mParameter, 0, 0, mBuffer, NULL, mLength, NULL );
									mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
									mReturn = mUrb -> UrbControlDescriptorRequest.TransferBufferLength;  // 实际传输长度
									break;
								default:  // 不支持
									mStatus = STATUS_INVALID_PARAMETER;  // 返回错误

⌨️ 快捷键说明

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