阅读:1633回复:6
[请教]Windows下USB BULK 工作机制
Windows 是如何检测到USB口有数据从而生成Dispatch IRP?
现在正在做USB转串口驱动,是采用DS生成框架后改的,现在我的驱动程序可以发数据,但收不了数据,怎么样才能知道USB口有数据到达? |
|
最新喜欢:julyja... |
沙发#
发布于:2008-11-14 12:57
???
|
|
板凳#
发布于:2008-11-14 13:44
用户被禁言,该主题自动屏蔽! |
|
地板#
发布于:2008-11-14 18:41
我有几个疑问:
1. IRP_MJ_READ, IRP_MJ_WRITE等例程应该是操作系统或类驱动程序来调用的了,现在我的IRP_MJ_WRITE例程会被调用,但IRP_MJ_READ,没有反应。这些例程是如何被调用的? 2. 如果自己去创建IRP来接收数据,Irp->MdlAddress怎么得到? 我现在是在WriteDispatch后去创建IRP,自己调用ReadDispatch来收数据,但程序运行到IoCallDriver就蓝屏。下面是我的部分代码,请帮忙分析一下,谢谢! NTSTATUS USBSerialWriteDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIRP readIrp; KEVENT readEvent; PMDL readMdl; IO_STATUS_BLOCK ioStatus; PUSBSERIAL_DEVICE_EXTENSION eviceExtension; NTSTATUS status; PUCHAR readBuffer; USBSerialDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"=> IRP 0x%p", Irp); deviceExtension = (PUSBSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; status = USBSerialCheckIoLock(&deviceExtension->IoLock, Irp); if (!NT_SUCCESS(status) || (status == STATUS_PENDING)) { USBSerialDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"<= IRP 0x%p STATUS 0x%08X", Irp, status); return status; } ;;; status = USBSerialBulkOutIo( DeviceObject, Irp, &deviceExtension->InterfaceInformation->Pipes[0] ); if (NT_SUCCESS(status)) { KeInitializeEvent(&readEvent, NotificationEvent, FALSE); readIrp = IoBuildDeviceIoControlRequest( IRP_MJ_READ, deviceExtension->LowerDeviceObject, NULL, 0, NULL/ *OutputBuffer* /, 0/ *OutputBufferLength* /, TRUE, &readEvent, &ioStatus ); if (readIrp != NULL) { readBuffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USBSERIAL_POOL_TAG); if (writeBuffer != NULL) { readMdl = IoAllocateMdl(writeBuffer, sizeof(writeBuffer), FALSE, FALSE, NULL); // 可以这样吗? if (readMdl != NULL) { readIrp->MdlAddress = readMdl; // ??? USBSerialReadDispatch(DeviceObject,readIrp); } //IoFreeIrp(readIrp); ExFreePool(writeBuffer); } } USBSerialDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"<= IRP 0x%p STATUS 0x%08X", Irp, status); return status; } NTSTATUS USBSerialReadDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PUSBSERIAL_DEVICE_EXTENSION deviceExtension; NTSTATUS status; ULONG readLength; PUCHAR readBuffer; USBSerialDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"=> IRP 0x%p", Irp); deviceExtension = (PUSBSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; status = USBSerialCheckIoLock(&deviceExtension->IoLock, Irp); if (!NT_SUCCESS(status) || (status == STATUS_PENDING)) { USBSerialDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"<= IRP 0x%p STATUS 0x%08X", Irp, status); return status; } ... status = USBSerialBulkInIo( DeviceObject, Irp, &deviceExtension->InterfaceInformation->Pipes[1] ); USBSerialDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"<= IRP 0x%p STATUS 0x%08X", Irp, status); return status; } NTSTATUS USBSerialBulkInIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PUSBD_PIPE_INFORMATION PipeInformation ) { PUSBSERIAL_DEVICE_EXTENSION DeviceExtension; PUSBSERIAL_IO_CONTEXT ioContext; NTSTATUS status; PUCHAR virtualAddress; ULONG totalLength; ULONG transferLength; PMDL mdl; PURB urb; PIO_STACK_LOCATION irpStack; USBSerialDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"=> IRP 0x%p", Irp); DeviceExtension = (PUSBSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // we will use do{}while(FALSE); structure // for resources cleanup status = STATUS_SUCCESS; ioContext = NULL; mdl = NULL; do { Irp->IoStatus.Information = 0; // allocate io context to pass to completion routine ioContext = (PUSBSERIAL_IO_CONTEXT)ExAllocatePoolWithTag( NonPagedPool, sizeof(USBSERIAL_IO_CONTEXT), USBSERIAL_POOL_TAG ); ... IoSetCompletionRoutine( Irp, USBSerialBulkInIoCompletionRoutine, ioContext, TRUE, TRUE, TRUE ); IoMarkIrpPending(Irp); status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); // 运行到这里就蓝屏了 } ... } while (FALSE); if (status != STATUS_PENDING) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); USBSerialDecrementIoCount(&DeviceExtension->IoLock); } USBSerialDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"<= IRP 0x%p STATUS 0x%08X", Irp, status); return status; } |
|
地下室#
发布于:2008-11-16 12:34
1.当应用程序调用ReadFile 时候就会发出IRP_MJ_READ包,也就会触发驱动程序的ReadDisptach,当调用WriteFile函数的时候会发出IRP_MJ_WRITE包,所以这两个例程都是由应用程序调用api函数的时候触发的。
2.你的程序的这种做法应该是错误的,建议你看看DDK自带的bulk例程 呵呵,我也是才学,不正确的地方还请各位大虾指正 |
|
5楼#
发布于:2008-11-18 20:09
Irp->MdlAddress如何得到?
|
|
6楼#
发布于:2008-11-21 14:43
用户被禁言,该主题自动屏蔽! |
|