📄 ch375wdm.c
字号:
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 + -