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

📄 ch375wdm.c

📁 CH375 是南京沁恒公司开发的一个USB总线的通用接口芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
									break;
							}
							break;
						case 2:  // 供应商请求
							switch( mRequestType & 0x03 ) {  // 分析接受器
								case 0:  // 设备
									mParameter = URB_FUNCTION_VENDOR_DEVICE;
									break;
								case 1:  // 接口
									mParameter = URB_FUNCTION_VENDOR_INTERFACE;
									break;
								case 2:  // 端点
									mParameter = URB_FUNCTION_VENDOR_ENDPOINT;
									break;
								default:  // 其它
									mParameter = URB_FUNCTION_VENDOR_OTHER;
									break;
							}
							UsbBuildVendorRequest( mUrb, (USHORT)mParameter,  // 构造USB供应商请求
												   sizeof( struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST ),  // URB结构长度
												   mTransferFlags, 0, mRequestCode, mRequestValue, mRequestIndex,  // 请求参数
												   mBuffer, NULL, mLength, NULL );  // 缓冲区及长度
							mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
							mReturn = mUrb -> UrbControlVendorClassRequest.TransferBufferLength;  // 实际传输长度
							break;
						default:  // 不支持的请求
							mStatus = STATUS_INVALID_PARAMETER;  // 返回错误
							break;
					}
					break;
				case mPipeInterUp:  // CH375的中断数据上传管道
					if ( mDeviceExtension -> mExtInterUpPipe != NULL ) {  // 管道有效
						mTransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;  // 传输标志
						UsbBuildInterruptOrBulkTransferRequest( mUrb, sizeof( struct _URB_BULK_OR_INTERRUPT_TRANSFER ),  // 构造USB请求
																mDeviceExtension -> mExtInterUpPipe,  // 管道的句柄
																mBuffer, NULL, mLength, mTransferFlags, NULL );  // 操作标志
						mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
						mReturn = mUrb -> UrbBulkOrInterruptTransfer.TransferBufferLength;  // 实际传输长度
						if ( ! NT_SUCCESS( mStatus ) ) mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_RESET_PIPE, mPipeInterUp );  // 出错则复位管道
					}
					else mStatus = STATUS_NO_SUCH_DEVICE ;  // 管道无效,设备无效
					break;
				case mPipeDataUp:  // CH375的数据块上传管道
					if ( mDeviceExtension -> mExtDataUpPipe != NULL ) {  // 管道有效
						mTransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;  // 传输标志
						UsbBuildInterruptOrBulkTransferRequest( mUrb, sizeof( struct _URB_BULK_OR_INTERRUPT_TRANSFER ),  // 构造USB请求
																mDeviceExtension -> mExtDataUpPipe,  // 管道的句柄
																mBuffer, NULL, mLength, mTransferFlags, NULL );  // 操作标志
						KeInitializeEvent( &mEvent, NotificationEvent, FALSE );  // 初始化IRP完成事件信号为无效
						KeClearEvent( & mDeviceExtension -> mExtUpCancelEvent );  // 清除取消事件信号
						mEventArray[0] = &mEvent;
						mEventArray[1] = & mDeviceExtension -> mExtUpCancelEvent;
						mIrp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_SUBMIT_URB, mDeviceExtension -> mExtNextLowerDevice,
															  NULL, 0, NULL, 0, TRUE, &mEvent, &mIoStatusBlock );  // 构造IRP提交URB
						if ( mIrp != NULL ) {  // IRP有效
							IoGetNextIrpStackLocation( mIrp ) -> Parameters.Others.Argument1 = mUrb;  // 将URB作为参数传递给下级设备
							mWaitStatus = STATUS_SUCCESS;
							InterlockedIncrement( & mDeviceExtension -> mExtIoCount );  // 操作计数增量,阻止中途停止或者移除设备
							mStatus = IoCallDriver( mDeviceExtension -> mExtNextLowerDevice, mIrp );  // 向下级设备发送IO请求
							if ( mStatus == STATUS_PENDING ) {  // 等待被悬挂的IO请求完成
								IoSetCancelRoutine( mIrp, mCancelCurrentUp );
								if ( mIrp -> Cancel ) KeSetEvent( & mDeviceExtension -> mExtUpCancelEvent, EVENT_INCREMENT, FALSE );
								if ( mDeviceExtension -> mExtDownTimeout < 0x80000000 ) {  // 需要检查超时
									mWaitTime.QuadPart = (LONGLONG)( mDeviceExtension -> mExtUpTimeout ) * -10000;  // 计算USB数据块上传管道的通讯超时
									mTimeout = &mWaitTime;
								}
								else mTimeout = NULL;  // 无需检查超时
								mWaitStatus = KeWaitForMultipleObjects( 2, mEventArray, WaitAny, Executive, KernelMode, FALSE, mTimeout, NULL );  // 挂起等待IRP完成
								IoSetCancelRoutine( mIrp, NULL );
								if ( mWaitStatus == STATUS_SUCCESS ) mStatus = mIoStatusBlock.Status;  // 操作成功的实际操作状态
								else {  /* 操作被取消或者超时 */
									mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_ABORT_PIPE, mPipeDataUp );  // 取消请求
									KeWaitForSingleObject( &mEvent, Executive, KernelMode, FALSE, NULL );  // 挂起等待IRP完成
									mStatus = mIoStatusBlock.Status;  // 取消后的操作状态
								}
							}
							InterlockedDecrement( & mDeviceExtension -> mExtIoCount );
							if ( mStatus == STATUS_CANCELLED || mUrb -> UrbBulkOrInterruptTransfer.Hdr.Status == USBD_STATUS_CANCELED ) {  // 被取消
								if ( mWaitStatus == STATUS_TIMEOUT ) {  // 因为超时而取消
									mStatus = STATUS_TIMEOUT;
									mReturn = mUrb -> UrbBulkOrInterruptTransfer.TransferBufferLength;  // 实际传输长度
								}
								else mStatus = STATUS_CANCELLED;  // 被用户取消
							}
							else {  // 不是被取消
								if ( mStatus == STATUS_TIMEOUT ) mStatus = STATUS_IO_TIMEOUT;  // 转换出错代码
								if ( NT_SUCCESS( mStatus ) ) mReturn = mUrb -> UrbBulkOrInterruptTransfer.TransferBufferLength;  // 实际传输长度
								else if ( mDeviceExtension -> mExtDeviceRemove == FALSE && mStatus != STATUS_CANCELLED && mUrb -> UrbBulkOrInterruptTransfer.Hdr.Status != USBD_STATUS_CANCELED )  // 设备尚未移除
									mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_RESET_PIPE, mPipeDataUp );  // 出错则复位管道
							}
						}
						else mStatus = STATUS_INSUFFICIENT_RESOURCES;
					}
					else mStatus = STATUS_NO_SUCH_DEVICE ;  // 管道无效,设备无效
					break;
				case mPipeDataDown:  // CH375的数据块下传管道
					if ( mDeviceExtension -> mExtDataDownPipe != NULL ) {  // 管道有效
						mTransferFlags = USBD_SHORT_TRANSFER_OK;  // 传输标志
						UsbBuildInterruptOrBulkTransferRequest( mUrb, sizeof( struct _URB_BULK_OR_INTERRUPT_TRANSFER ),  // 构造USB请求
																mDeviceExtension -> mExtDataDownPipe,  // 管道的句柄
																mBuffer, NULL, mLength, mTransferFlags, NULL );  // 操作标志
						KeInitializeEvent( &mEvent, NotificationEvent, FALSE );  // 初始化IRP完成事件信号为无效
						KeClearEvent( & mDeviceExtension -> mExtDownCancelEvent );  // 清除取消事件信号
						mEventArray[0] = &mEvent;
						mEventArray[1] = & mDeviceExtension -> mExtDownCancelEvent;
						mIrp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_SUBMIT_URB, mDeviceExtension -> mExtNextLowerDevice,
															  NULL, 0, NULL, 0, TRUE, &mEvent, &mIoStatusBlock );  // 构造IRP提交URB
						if ( mIrp != NULL ) {  // IRP有效
							IoGetNextIrpStackLocation( mIrp ) -> Parameters.Others.Argument1 = mUrb;  // 将URB作为参数传递给下级设备
							mWaitStatus = STATUS_SUCCESS;
							InterlockedIncrement( & mDeviceExtension -> mExtIoCount );  // 操作计数增量,阻止中途停止或者移除设备
							mStatus = IoCallDriver( mDeviceExtension -> mExtNextLowerDevice, mIrp );  // 向下级设备发送IO请求
							if ( mStatus == STATUS_PENDING ) {  // 等待被悬挂的IO请求完成
								IoSetCancelRoutine( mIrp, mCancelCurrentDown );
								if ( mIrp -> Cancel ) KeSetEvent( & mDeviceExtension -> mExtDownCancelEvent, EVENT_INCREMENT, FALSE );
								if ( mDeviceExtension -> mExtDownTimeout < 0x80000000 ) {  // 需要检查超时
									mWaitTime.QuadPart = (LONGLONG)( mDeviceExtension -> mExtDownTimeout ) * -10000;  // 计算USB数据块下传管道的通讯超时
									mTimeout = &mWaitTime;
								}
								else mTimeout = NULL;  // 无需检查超时
								mWaitStatus = KeWaitForMultipleObjects( 2, mEventArray, WaitAny, Executive, KernelMode, FALSE, mTimeout, NULL );  // 挂起等待IRP完成
								IoSetCancelRoutine( mIrp, NULL );
								if ( mWaitStatus == STATUS_SUCCESS ) mStatus = mIoStatusBlock.Status;  // 操作成功的实际操作状态
								else {  /* 操作被取消或者超时 */
									mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_ABORT_PIPE, mPipeDataDown );  // 取消请求
									KeWaitForSingleObject( &mEvent, Executive, KernelMode, FALSE, NULL );  // 挂起等待IRP完成
									mStatus = mIoStatusBlock.Status;  // 取消后的操作状态
								}
							}
							InterlockedDecrement( & mDeviceExtension -> mExtIoCount );
							if ( mStatus == STATUS_CANCELLED || mUrb -> UrbBulkOrInterruptTransfer.Hdr.Status == USBD_STATUS_CANCELED ) {  // 被取消
								if ( mWaitStatus == STATUS_TIMEOUT ) {  // 因为超时而取消
									mStatus = STATUS_TIMEOUT;
									mReturn = mUrb -> UrbBulkOrInterruptTransfer.TransferBufferLength;  // 实际传输长度
								}
								else mStatus = STATUS_CANCELLED;  // 被用户取消
							}
							else {  // 不是被取消
								if ( mStatus == STATUS_TIMEOUT ) mStatus = STATUS_IO_TIMEOUT;  // 转换出错代码
								if ( NT_SUCCESS( mStatus ) ) mReturn = mUrb -> UrbBulkOrInterruptTransfer.TransferBufferLength;  // 实际传输长度
								else if ( mDeviceExtension -> mExtDeviceRemove == FALSE && mStatus != STATUS_CANCELLED && mUrb -> UrbBulkOrInterruptTransfer.Hdr.Status != USBD_STATUS_CANCELED )  // 设备尚未移除
									mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_RESET_PIPE, mPipeDataDown );  // 出错则复位管道
							}
						}
						else mStatus = STATUS_INSUFFICIENT_RESOURCES;
					}
					else mStatus = STATUS_NO_SUCH_DEVICE ;  // 管道无效,设备无效
					break;
				case mFuncResetDevice:  // 复位USB设备
					InterlockedDecrement( & mDeviceExtension -> mExtIoCount );  // 操作计数减量,以便于关闭或者移除设备
					KeInitializeEvent( &mEvent, NotificationEvent, FALSE );  // 初始化IRP完成事件信号为无效
					mIrp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_RESET_PORT,  // 构造IRP复位端口
														  mDeviceExtension -> mExtNextLowerDevice,
														  NULL, 0, NULL, 0, TRUE, &mEvent, &mIoStatusBlock );
					mStatus = IoCallDriver( mDeviceExtension -> mExtNextLowerDevice, mIrp );  // 向下级设备发送IO请求,复位端口
					if ( mStatus == STATUS_PENDING ) {  // 等待被悬挂的IO请求完成
						KeWaitForSingleObject( &mEvent, Executive, KernelMode, FALSE, NULL );  // 挂起等待IRP完成
						mStatus = mIoStatusBlock.Status;  // 取完成状态
					}
					InterlockedIncrement( & mDeviceExtension -> mExtIoCount );  // 操作计数增量
					break;
				case mFuncResetPipe:  // 复位USB管道
					mStatus = mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_RESET_PIPE, *(PULONG)mBuffer );  // 在指定管道执行复位请求
					break;
				case mFuncAbortPipe:  // 取消USB管道的数据请求
					mStatus = mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_ABORT_PIPE, *(PULONG)mBuffer );  // 在指定管道执行取消请求
					break;
				case mFuncSetTimeout:  // 设置USB通讯超时
					mDeviceExtension -> mExtDownTimeout = *(PULONG)( (PUCHAR)mBuffer + 0 );  // 设置USB数据块下传管道的通讯超时,mS
					if ( mDeviceExtension -> mExtDownTimeout == 0 ) mDeviceExtension -> mExtDownTimeout = 1;
					mDeviceExtension -> mExtUpTimeout = *(PULONG)( (PUCHAR)mBuffer + 4 );  // 设置USB数据块上传管道的通讯超时,mS
					if ( mDeviceExtension -> mExtUpTimeout == 0 ) mDeviceExtension -> mExtUpTimeout = 1;
					break;
				default:  // 不支持的请求
					mStatus = STATUS_INVALID_PARAMETER;  // 返回错误
					break;
			}
			mWin32Command -> mStatus = mStatus;  // 返回操作状态
			mWin32Command -> mLength = mReturn;  // 实际传输长度
			mReturn += mWIN32_COMMAND_HEAD;  // 加上头部长度得返回数据的总长度
		}
		else {  // 失败
			if ( mUrb == NULL ) mStatus = STATUS_INSUFFICIENT_RESOURCES;  // 资源不够
			else mStatus = STATUS_BUFFER_TOO_SMALL;  // 缓冲区太小
		}
		if ( mUrb != NULL ) ExFreePool( mUrb );  // 释放内存
		if ( mStatus != STATUS_PENDING ) {  // 成功返回或者失败返回
			iIrp -> IoStatus.Status = mStatus;  // 返回状态
			iIrp -> IoStatus.Information = mReturn;  // 返回数据的长度
			IoCompleteRequest( iIrp, IO_CH375_INCREMENT );  // 完成请求,增加优先级
		}
	}
	else {  // 直接传送至下级设备处理
		IoSkipCurrentIrpStackLocation( iIrp );  // 直接传送当前栈
		mStatus = IoCallDriver( mDeviceExtension -> mExtNextLowerDevice, iIrp );  // 传送至下级设备
	}
	InterlockedDecrement( & mDeviceExtension -> mExtIoCount );  // 操作计数减量
	return( mStatus );
}

NTSTATUS	mRequestPipe(  // 在指定管道上执行请求
	PDEVICE_OBJECT	iDeviceObject,
	PURB			iUrb,
	USHORT			iFunction,
	ULONG			iPipe )
{
	NTSTATUS			mStatus;
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	iUrb -> UrbHeader.Length = sizeof( struct _URB_PIPE_REQUEST );
	iUrb -> UrbHeader.Function = iFunction;
	switch( iPipe ) {  // 指定管道
		case mPipeInterUp:  // CH375的中断数据上传管道
			iUrb -> UrbPipeRequest.PipeHandle = mDeviceExtension -> mExtInterUpPipe;
			break;
		case mPipeDataUp:  // CH375的数据块上传管道
			iUrb -> UrbPipeRequest.PipeHandle = mDeviceExtension -> mExtDataUpPipe;
			break;
		case mPipeDataDown:  // CH375的数据块下传管道
			iUrb -> UrbPipeRequest.PipeHandle = mDeviceExtension -> mExtDataDownPipe;
			break;
		default:  // 不支持
			iUrb -> UrbPipeRequest.PipeHandle = NULL;  // 管道无效
			break;
	}
	if ( iUrb -> UrbPipeRequest.PipeHandle == NULL ) mStatus = STATUS_NO_SUCH_DEVICE ;  // 管道无效
	else {
		mStatus = mUsbSubmitUrb( iDeviceObject, iUrb );  // 提交URB
		if ( ! NT_SUCCESS( mStatus ) ) mStatus = mUsbSubmitUrb( iDeviceObject, iUrb );  // 提交URB
	}
	return( mStatus );
}

VOID		mCancelCurrentUp(  // 取消当前上传IRP
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	KeSetEvent( & mDeviceExtension -> mExtUpCancelEvent, EVENT_INCREMENT, FALSE );  // 置USB数据块上传管道的取消事件
	IoReleaseCancelSpinLock( iIrp -> CancelIrql );
}

VOID		mCancelCurrentDown(  // 取消当前下传IRP
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	KeSetEvent( & mDeviceExtension -> mExtDownCancelEvent, EVENT_INCREMENT, FALSE );  // 置USB数据块下传管道的取消事件
	IoReleaseCancelSpinLock( iIrp -> CancelIrql );
}

NTSTATUS	mDispatchCleanup(  // 取消操作
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	ULONG				i;
	PURB				mUrb;
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	if ( mDeviceExtension -> mExtIoCount != 0 ) {  // 有未完成的操作请求
		KeSetEvent( & mDeviceExtension -> mExtDownCancelEvent, EVENT_INCREMENT, FALSE );  // 置USB数据块下传管道的取消事件
		KeSetEvent( & mDeviceExtension -> mExtUpCancelEvent, EVENT_INCREMENT, FALSE );  // 置USB数据块上传管道的取消事件
		for ( i = 0; i < 10; i ++ ) {  /* 取消未完成USB通讯 */
			LARGE_INTEGER	mTime;
			PURB			mUrb;
			if ( mDeviceExtension -> mExtIoCount == 0 ) break;  /* 操作完成 */
			mTime.QuadPart = 0 - 200000;
			KeDelayExecutionThread( KernelMode, FALSE, &mTime );  /* 延时20mS */
			if ( mDeviceExtension -> mExtIoCount == 0 ) break;  /* 操作完成 */
			if ( i > 5 ) {  /* 强制取消 */
				mUrb = ExAllocatePool( NonPagedPool, sizeof( URB ) );  // 分配内存作为URB请求块
				if (  mUrb != NULL ) {
					mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_ABORT_PIPE, mPipeDataDown );  // 在下传管道执行取消请求
					mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_ABORT_PIPE, mPipeDataUp );  // 在上传管道执行取消请求
					mRequestPipe( iDeviceObject, mUrb, URB_FUNCTION_ABORT_PIPE, mPipeInterUp );  // 取消请求
					ExFreePool( mUrb );  // 释放内存
				}
			}

⌨️ 快捷键说明

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