阅读:1327回复:5
怎样异步调用USB的DeviceIoControl输入?
CreateFile以异步方式建立。
有输入数据的话,就可以读出。但没有的话就停下来一直等,其它的通讯则无法完成。通过查看驱动输出的信息,在SubmitUrb()后的t << "Submit Over\n";已经出现,说明已经执行了return STATUS_PENDING;但我的应用程序还在等待,不知为何。 应用程序: BOOL CUDK_XP_DEVICE::Endpoint1ListenPipes(UINT Length, void *pBuffer) { ULONG nOutput; // Count written to bufOutput // Call device IO Control interface (THERMOMETER_READ_DATA) in driver if (!DeviceIoControl(hDevice, D12_DRIVER_READ, pBuffer, Length, pBuffer, Length, &nOutput, NULL) ) { AfxMessageBox("ERROR: DeviceIoControl returns %d \n", GetLastError()); return 0; } TRACE("The DRIVER_READ counter is %d .\n", nOutput); return 1; } 驱动程序: NTSTATUS D12_DriverDevice::D12_DRIVER_READ_Handler(KIrp I) { NTSTATUS status = STATUS_SUCCESS; t << "Entering D12_DriverDevice::D12_DRIVER_READ_Handler, " << I << EOL; // TODO: Verify that the input parameters are correct // If not, return STATUS_INVALID_PARAMETER // TODO: Handle the the D12_DRIVER_READ request, or // defer the processing of the IRP (i.e. by queuing) and set // status to STATUS_PENDING. // TODO: Assuming that the request was handled here. Set I.Information // to indicate how much data to copy back to the user. I.Information() = 0; m_pUrb1In = m_Endpoint1In.BuildInterruptTransfer( (unsigned char *)I.IoctlBuffer(), // transfer buffer I.IoctlInputBufferSize(), // transfer buffer size TRUE, // Short Ok NULL, // link urb m_pUrb1In // new urb ); if ( m_pUrb1In == NULL ) { return STATUS_INSUFFICIENT_RESOURCES;; } PVOID CI = InterlockedCompareExchangePointer( (PVOID*)&CurrentIrp(), PVOID( PIRP(I)), NULL); // Allow only one request at a time if ( CI != NULL ) return STATUS_DEVICE_BUSY; CancelSpinLock::Acquire(); if ( I.WasCanceled() ) { CurrentIrp() = NULL; CancelSpinLock::Release(); return STATUS_CANCELLED; } I.SetCancelRoutine( LinkTo(Cancel) ); CancelSpinLock::Release(); I.MarkPending(); t << "Submit URB\n"; // submit the URB to USBD IncrementOutstandingRequestCount(); m_Endpoint1In.SubmitUrb(m_kIrp, m_pUrb1In, LinkTo(ReadCounterComplete),this); t << "Submit Over\n"; return STATUS_PENDING; } NTSTATUS D12_DriverDevice::ReadCounterComplete(KIrp I) { t << "Read Completion routine\n"; KIrp Current( CurrentIrp() ); if ( Current == NULL ) { DecrementOutstandingRequestCount(); return STATUS_MORE_PROCESSING_REQUIRED; } CancelSpinLock::Acquire(); if ( Current.WasCanceled() ) { CancelSpinLock::Release(); DecrementOutstandingRequestCount(); return STATUS_MORE_PROCESSING_REQUIRED; } else { Current.SetCancelRoutine(NULL); CancelSpinLock::Release(); CurrentIrp() = NULL; } if ( I.Status() != STATUS_SUCCESS ) { NTSTATUS status = I.Status(); Current.PnpComplete(this, status); DecrementOutstandingRequestCount(); return STATUS_MORE_PROCESSING_REQUIRED; } // find the buffer pointer in the URB PUCHAR buffer = (PUCHAR)m_pUrb1In->UrbBulkOrInterruptTransfer.TransferBuffer; // Dump the buffer t << "Urb data[0]: " << buffer[0] << "\n"; // Data from the IRP read is stored in the ioctl buffer associated with this // IRP: PUCHAR(Current.IoctlBuffer()); // IrpBuffer[0] = buffer[0]; Current.Information() = 1; Current.PnpComplete(this, STATUS_SUCCESS); DecrementOutstandingRequestCount(); return STATUS_MORE_PROCESSING_REQUIRED; } |
|
沙发#
发布于:2004-02-19 17:15
你的deviceiocontrol是以同步方式调用的,改为异步试试。
我也遇到了类似的问题,createfile和deviceiocontrol都改为了异步方式,但还是进入deviceiocontrol不返回,用softice跟了一下,调用deviceiocontrol的时候没有进入驱动的相应的handler。 各位大侠,这是什么原因呢? |
|
板凳#
发布于:2004-02-19 21:05
应用程序deviceiocontrol的最后一参数改为了事件后,搞定。
shuzhibuaa可参考我的代码。 但我的输入与输出却不能同时调用,不知为何。 |
|
地板#
发布于:2004-02-19 22:42
我的deviceiocontrol改为异步怎么不行呢?zhuge36,你其他地方改了吗(比如驱动程序里)?把你修改后的代码贴出来看看好吗?
|
|
地下室#
发布于:2004-02-20 09:53
可以参考《Windows 2000/xp WDM设备驱动程序开发》第五章。
驱动程序要做一定修改。 |
|
5楼#
发布于:2004-02-20 18:22
zhuge36:
我在应用程序这里碰到了一点问题,看了你们的贴子,做了一点改动,但是还是有问题,你能不能帮我看一看,在下面的地址: http://www.driverdevelop.com/forum/html_60995.html?1077272424 多谢了。 |
|
|