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

📄 ch375wdm.c

📁 这是USB接口芯片CH372上位机和下位机的测试程序
💻 C
📖 第 1 页 / 共 3 页
字号:
			mCompletion = 1;  // 操作已经完成
			break;
		case IRP_MN_QUERY_STOP_DEVICE:  // 将要停止设备
			if ( mDeviceExtension -> mExtIoCount != 0 ) {  // 当前正在操作
				mStatus = STATUS_UNSUCCESSFUL;  // 无法停止,操作失败
				iIrp -> IoStatus.Information = 0;
				mCompletion = 1;  // 强制操作完成
			}
			else mDeviceExtension -> mExtDeviceStart = FALSE;  // 清除设备启动标志
			break;
		case IRP_MN_CANCEL_STOP_DEVICE:  // 取消停止设备
			mDeviceExtension -> mExtDeviceStart = TRUE;  // 恢复设备启动标志
			break;
		case IRP_MN_STOP_DEVICE:  // 停止设备
			mDeviceExtension -> mExtDeviceStart = FALSE;  // 清除设备启动标志
			mDeactiveConfig( iDeviceObject, iIrp );  // 去除配置
			break;
		case IRP_MN_QUERY_REMOVE_DEVICE:  // 将要移除设备
			if ( mDeviceExtension -> mExtDeviceOpen != 0 ||  // 打开计数不为0则尚未关闭
				 mDeviceExtension -> mExtIoCount != 0 ) {  // 或者当前正在操作
				mStatus = STATUS_UNSUCCESSFUL;  // 无法移除,操作失败
				iIrp -> IoStatus.Information = 0;
				mCompletion = 1;  // 强制操作完成
			}
			else {  // 尚未打开且设备空闲
				mDeviceExtension -> mExtDeviceRemove = TRUE;  // 置设备移除标志
				IoSetDeviceInterfaceState( & mDeviceExtension -> mExtDeviceName, FALSE );  // 禁用设备接口
			}
			break;
		case IRP_MN_CANCEL_REMOVE_DEVICE:  // 取消移除设备
			mDeviceExtension -> mExtDeviceRemove = FALSE;  // 清设备移除标志
			IoSetDeviceInterfaceState( & mDeviceExtension -> mExtDeviceName, TRUE );  // 恢复设备接口
			break;
		case IRP_MN_SURPRISE_REMOVAL:  // 意外地移除设备
			mDeviceExtension -> mExtDeviceRemove = TRUE;  // 置设备移除标志
			IoSetDeviceInterfaceState( & mDeviceExtension -> mExtDeviceName, FALSE );  // 禁用设备接口
			break;
		case IRP_MN_REMOVE_DEVICE:  // 移除设备
			mDeviceExtension -> mExtDeviceRemove = TRUE;  // 置设备移除标志
			IoSetDeviceInterfaceState( & mDeviceExtension -> mExtDeviceName, FALSE );  // 禁用设备接口
			mDeviceExtension -> mExtDeviceStart = FALSE;  // 清除设备启动标志
			mRequestPipe( iDeviceObject, URB_FUNCTION_ABORT_PIPE, mPipeAuxDown );  // 在辅助下传管道执行取消请求
			mRequestPipe( iDeviceObject, URB_FUNCTION_ABORT_PIPE, mPipeDataDown );  // 在下传管道执行取消请求
			mRequestPipe( iDeviceObject, URB_FUNCTION_ABORT_PIPE, mPipeDataUp );  // 在上传管道执行取消请求
			mDeactiveConfig( iDeviceObject, iIrp );  // 去除配置
			mRemoveDevice( iDeviceObject );  // 移除设备操作
			break;
		default:
			break;
	}
	if ( mCompletion == 0 ) {  // 操作尚未完成则继续下传
		IoSkipCurrentIrpStackLocation( iIrp );  // 直接传送当前栈
		mStatus = IoCallDriver( mNextDeviceObject, iIrp );  // 传送至下级设备
	}
	else if ( mCompletion == 1 ) {  // 操作已经完成
		iIrp -> IoStatus.Status = mStatus;  // 置完成状态
		IoCompleteRequest( iIrp, IO_NO_INCREMENT );  // 完成当前IRP
	}
	return( mStatus );
}

NTSTATUS	mWaitCompletion(  // 等待IRP操作完成
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	KEVENT				mEvent;
	NTSTATUS			mStatus;
	mPDEVICE_EXTENSION	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	KeInitializeEvent( &mEvent, NotificationEvent, FALSE );  // 初始化IRP完成事件为无效
	IoCopyCurrentIrpStackLocationToNext( iIrp );  // 复制当前栈单元
	IoSetCompletionRoutine( iIrp, mCompletionRoutine, &mEvent, TRUE, TRUE, TRUE );  // 设置设定完成例程
	mStatus = IoCallDriver( mDeviceExtension -> mExtNextLowerDevice, iIrp );  // 传送至下级设备
	if ( mStatus == STATUS_PENDING ) {  // 等待被悬挂的IO请求完成
		KeWaitForSingleObject( &mEvent, Executive, KernelMode, FALSE, NULL );  // 挂起等待IRP完成
		mStatus = iIrp -> IoStatus.Status;  // 取完成状态
	}
	return( mStatus );  // 返回状态
}

NTSTATUS	mCompletionRoutine(  // 操作完成例程
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp,
	PVOID			iContext )  // 输入参数,完成事件
{
	KeSetEvent( (PKEVENT)iContext, IO_NO_INCREMENT, FALSE );  // 置操作完成事件
	return( STATUS_MORE_PROCESSING_REQUIRED );  // 阻止继续处理当前IRP
}

NTSTATUS	mActiveConfig(  // 激活配置
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	ULONG							i;
	PURB							mUrb;
	NTSTATUS						mStatus;
	PUSB_CONFIGURATION_DESCRIPTOR	mConfigDescriptor;
	PUSB_INTERFACE_DESCRIPTOR		mInterfaceDescriptor;
	USBD_INTERFACE_LIST_ENTRY		mInterfaceList[2];
	PUSBD_INTERFACE_INFORMATION		mInterface;
	PUSBD_PIPE_INFORMATION			mPipe;
	mPDEVICE_EXTENSION				mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	mStatus = STATUS_INSUFFICIENT_RESOURCES;  // 预置操作失败
	mDeviceExtension -> mExtInterUpPipe = NULL;
	mDeviceExtension -> mExtAuxDownPipe = NULL;
	mDeviceExtension -> mExtDataUpPipe = NULL;
	mDeviceExtension -> mExtDataDownPipe = NULL;
	mConfigDescriptor = ExAllocatePool( NonPagedPool,  // 分配内存作为配置描述符区域和URB请求块
										256 + sizeof( URB ) );
	if ( mConfigDescriptor != NULL ) {  // 分配了内存
		mUrb = (PURB) ( (PUCHAR)mConfigDescriptor + 256 );  // 指向URB请求块,前256字节保留给配置描述符
		UsbBuildGetDescriptorRequest( mUrb, sizeof( struct _URB_CONTROL_DESCRIPTOR_REQUEST ),  // 构造获取配置描述符的URB
									  USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, mConfigDescriptor, NULL,  // 缓冲区
									  sizeof( USB_CONFIGURATION_DESCRIPTOR ), NULL );  // 配置描述符长度
		mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
		if ( NT_SUCCESS( mStatus ) ) {  // 获取了配置描述符
			UsbBuildGetDescriptorRequest( mUrb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST ),  // 构造获取配置描述符的URB
										  USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, mConfigDescriptor, NULL,  // 缓冲区
										  (ULONG)( mConfigDescriptor -> wTotalLength ), NULL );  // 配置描述符和配置信息的总长度
			mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
			if ( NT_SUCCESS( mStatus ) && mConfigDescriptor -> bNumInterfaces == 0 )  // 获取了配置描述符但是不完整
				mStatus = STATUS_DEVICE_DATA_ERROR;  // 接口描述符无效
			if ( NT_SUCCESS( mStatus ) ) {  // 获取了配置描述符且接口描述符有效
				mInterfaceDescriptor = USBD_ParseConfigurationDescriptorEx( mConfigDescriptor, mConfigDescriptor, -1, -1, -1, -1, -1 );
				mInterfaceList[0].InterfaceDescriptor = mInterfaceDescriptor;
				mInterfaceList[0].Interface = NULL;
				mInterfaceList[1].InterfaceDescriptor = NULL;
				mInterfaceList[1].Interface = NULL;
				mUrb = USBD_CreateConfigurationRequestEx( mConfigDescriptor, mInterfaceList );  // 构造配置请求的URB
				if ( mUrb != NULL ) {  // 生成了URB
					mInterface = & mUrb -> UrbSelectConfiguration.Interface;  // 当前接口的信息
					for ( i = 0; i < mInterface -> NumberOfPipes; ++i ) {  // 检查所有端点/管道
						mPipe = & mInterface -> Pipes[ i ];  // 指向管道
						if ( mPipe -> MaximumTransferSize > mMAX_BUFFER_LENGTH ) mPipe -> MaximumTransferSize = mMAX_BUFFER_LENGTH;
					}
					mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
					if ( NT_SUCCESS( mStatus ) ) {  // 配置CH375芯片完成
						mInterface = & mUrb -> UrbSelectConfiguration.Interface;  // 当前接口的信息
						for ( i = 0; i < mInterface -> NumberOfPipes; ++i ) {  // 检查所有端点/管道
							mPipe = & mInterface -> Pipes[ i ];  // 指向管道
							if ( mPipe -> MaximumTransferSize > mMAX_BUFFER_LENGTH ) mPipe -> MaximumTransferSize = mMAX_BUFFER_LENGTH;
							switch( mPipe -> EndpointAddress ) {  // 比较端点地址,以确定管道功能
								case 0x81: mDeviceExtension -> mExtInterUpPipe = mPipe -> PipeHandle; break;  // 保存中断数据上传管道的句柄
								case 0x01: mDeviceExtension -> mExtAuxDownPipe = mPipe -> PipeHandle; break;  // 保存辅助数据下传管道的句柄
								case 0x82: mDeviceExtension -> mExtDataUpPipe = mPipe -> PipeHandle; break;  // 保存数据块上传管道的句柄
								case 0x02: mDeviceExtension -> mExtDataDownPipe = mPipe -> PipeHandle; break;  // 保存数据块下传管道的句柄
							}
						}
					}
					ExFreePool( mUrb );  // 释放URB内存
				}
				else mStatus = STATUS_INSUFFICIENT_RESOURCES;  // 无法构造URB
			}
		}
		ExFreePool( mConfigDescriptor );  // 释放配置描述符内存
	}
	return( mStatus );  // 返回状态
}

NTSTATUS	mDeactiveConfig(  // 去除配置
	PDEVICE_OBJECT	iDeviceObject,
	PIRP			iIrp )
{
	ULONG				mPortStatus;
	PURB				mUrb;
	mPDEVICE_EXTENSION	mDeviceExtension;
	NTSTATUS			mStatus = STATUS_INSUFFICIENT_RESOURCES;  // 预置操作失败
	mUrb = ExAllocatePool( NonPagedPool, sizeof( URB ) );  // 分配USB请求块
	if ( mUrb != NULL ) {  // 分配了USB请求块
		UsbBuildSelectConfigurationRequest( mUrb, sizeof( struct _URB_SELECT_CONFIGURATION ), NULL );  // 构造URB请求配置
		mStatus = mUsbSubmitUrb( iDeviceObject, mUrb );  // 提交URB
		ExFreePool( mUrb );  // 释放URB
		mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
		mDeviceExtension -> mExtInterUpPipe = NULL;
		mDeviceExtension -> mExtAuxDownPipe = NULL;
		mDeviceExtension -> mExtDataUpPipe = NULL;
		mDeviceExtension -> mExtDataDownPipe = NULL;
	}
	return( mStatus );  // 返回状态
}

NTSTATUS	mUsbSubmitUrb(  // 提交URB请求
	PDEVICE_OBJECT	iDeviceObject,
	PURB			iUrb )
{
	PIRP				mIrp;
	KEVENT				mEvent;
	mPDEVICE_EXTENSION	mDeviceExtension;
	IO_STATUS_BLOCK		mIoStatusBlock;
	NTSTATUS			mStatus = STATUS_INSUFFICIENT_RESOURCES;  // 预置操作失败
	mDeviceExtension = iDeviceObject -> DeviceExtension;  // 设备扩展
	InterlockedIncrement( & mDeviceExtension -> mExtIoCount );  // 操作计数增量,阻止中途停止或者移除设备
	KeInitializeEvent( &mEvent, NotificationEvent, FALSE );  // 初始化IRP完成事件信号为无效
	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 = iUrb;  // 将URB作为参数传递给下级设备
		mStatus = IoCallDriver( mDeviceExtension -> mExtNextLowerDevice, mIrp );  // 向下级设备发送IO请求
		if ( mStatus == STATUS_PENDING ) {  // 等待被悬挂的IO请求完成
			KeWaitForSingleObject( &mEvent, Executive, KernelMode, FALSE, NULL );  // 挂起等待IRP完成
			mStatus = mIoStatusBlock.Status;  // 取完成状态
		}
		if ( mStatus == STATUS_TIMEOUT ) mStatus = STATUS_IO_TIMEOUT;  // 转换出错代码
	}
	InterlockedDecrement( & mDeviceExtension -> mExtIoCount );  // 操作计数减量
	return( mStatus );  // 返回状态
}


// end

⌨️ 快捷键说明

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