?? ch375wdm.c
字號:
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 + -