阅读:1821回复:15
我只想知道,这个参数在那里??---如何知道设备传回了多少数据??(回答对者,只要我能理解+100分)usb芯片内将要传回电脑的数据不固定,但小于32个字节。 现在我发一个读请求,那么怎么知道usb设备送回多少数据呢??是否主机回一直轮训,直到收到下面的“size"大小的数据才停止?? 还是如果一提交这个urb后,如果收不到size大小的数据,他马上返回一个错误状态,然后我可以从什么地方知道他到底收到了多少数据?? URB urb; UsbBuildInterruptOrBulkTransferRequest (&urb, sizeof(_URB_BULK_OR_INTERRUPT_TRANSFER), pipe, Buffer, NULL, size, USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, NULL); status = SendAwaitUrb(fdo, &urb);//是一个发送irp的自定义函数 能回答者,送一百分!!! [编辑 - 8/11/04 by flymonkey] |
|
最新喜欢:jinghu... |
沙发#
发布于:2004-08-10 12:04
在创建你的URB时,你的size指定你要读的字节长度,你要设置一个完成例程,标明的IoMarkIrpPending(IRP),然后返回STATUS_PENDING,在应用程序端,你用一个OVERLAPPED结构来异步读取返回来的数据。
|
|
|
板凳#
发布于:2004-08-10 12:41
哦,谢谢,我还是不很懂,能说说具体在那个地方吗??我不需要做应该程序,做的是网卡,需要在驱动内部进行处理。
有代码更好,谢谢!! 我是说,设备将要传回主机的数据是不固定的,发出一个携带urb的irp来读,有时候读到1个,有时候10个,size 我设置为32,并允许读上来比他少的数据。那么,从什么地方能得到读取的字节数呢??(比如设备返回7个字节,那我从什么地方能知道他返回了7个呢?) 谢谢,我先加50分。 [编辑 - 8/10/04 by flymonkey] |
|
地板#
发布于:2004-08-10 13:20
这是D12的读写的例子,你好好看一下完成例程。
NTSTATUS BulkUsb_DispatchReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: Dispatch routine for read and write. This routine creates a BULKUSB_RW_CONTEXT for a read/write. This read/write is performed in stages of BULKUSB_MAX_TRANSFER_SIZE. once a stage of transfer is complete, then the irp is circulated again, until the requested length of tranfer is performed. Arguments: DeviceObject - pointer to device object Irp - I/O request packet Return Value: NT status value --*/ { PMDL mdl; PURB urb; ULONG totalLength; ULONG stageLength; ULONG urbFlags; BOOLEAN read; NTSTATUS ntStatus; ULONG_PTR virtualAddress; PFILE_OBJECT fileObject; PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; PIO_STACK_LOCATION nextStack; PBULKUSB_RW_CONTEXT rwContext; PUSBD_PIPE_INFORMATION pipeInformation; // // initialize variables // urb = NULL; mdl = NULL; rwContext = NULL; totalLength = 0; irpStack = IoGetCurrentIrpStackLocation(Irp); fileObject = irpStack->FileObject; read = (irpStack->MajorFunction == IRP_MJ_READ) ? TRUE : FALSE; deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; BulkUsb_DbgPrint(3, ("BulkUsb_DispatchReadWrite - begins\n")); if(deviceExtension->DeviceState != Working) { BulkUsb_DbgPrint(1, ("Invalid device state\n")); ntStatus = STATUS_INVALID_DEVICE_STATE; goto BulkUsb_DispatchReadWrite_Exit; } // // It is true that the client driver cancelled the selective suspend // request in the dispatch routine for create Irps. // But there is no guarantee that it has indeed completed. // so wait on the NoIdleReqPendEvent and proceed only if this event // is signalled. // BulkUsb_DbgPrint(3, ("Waiting on the IdleReqPendEvent\n")); // // make sure that the selective suspend request has been completed. // if(deviceExtension->SSEnable) { KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, Executive, KernelMode, FALSE, NULL); } if(fileObject && fileObject->FsContext) { pipeInformation = fileObject->FsContext; if((UsbdPipeTypeInterrupt!=pipeInformation->PipeType)&&(UsbdPipeTypeBulk!=pipeInformation->PipeType)) { BulkUsb_DbgPrint(1, ("Usbd pipe type is not bulk and not interrupt\n")); ntStatus = STATUS_INVALID_HANDLE; goto BulkUsb_DispatchReadWrite_Exit; } } else { BulkUsb_DbgPrint(1, ("Invalid handle\n")); ntStatus = STATUS_INVALID_HANDLE; goto BulkUsb_DispatchReadWrite_Exit; } rwContext = (PBULKUSB_RW_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(BULKUSB_RW_CONTEXT)); if(rwContext == NULL) { BulkUsb_DbgPrint(1, ("Failed to alloc mem for rwContext\n")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto BulkUsb_DispatchReadWrite_Exit; } if(Irp->MdlAddress) { totalLength = MmGetMdlByteCount(Irp->MdlAddress); } if(totalLength > BULKUSB_TEST_BOARD_TRANSFER_BUFFER_SIZE) { BulkUsb_DbgPrint(1, ("Transfer length > circular buffer\n")); ntStatus = STATUS_INVALID_PARAMETER; ExFreePool(rwContext); goto BulkUsb_DispatchReadWrite_Exit; } if(totalLength == 0) { BulkUsb_DbgPrint(1, ("Transfer data length = 0\n")); ntStatus = STATUS_SUCCESS; ExFreePool(rwContext); goto BulkUsb_DispatchReadWrite_Exit; } urbFlags = USBD_SHORT_TRANSFER_OK; virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress); if(read) { urbFlags |= USBD_TRANSFER_DIRECTION_IN; BulkUsb_DbgPrint(3, ("Read operation\n")); } else { urbFlags |= USBD_TRANSFER_DIRECTION_OUT; BulkUsb_DbgPrint(3, ("Write operation\n")); } // // the transfer request is for totalLength. // we can perform a max of BULKUSB_MAX_TRANSFER_SIZE // in each stage. // if(totalLength > BULKUSB_MAX_TRANSFER_SIZE) { stageLength = BULKUSB_MAX_TRANSFER_SIZE; } else { stageLength = totalLength; } mdl = IoAllocateMdl((PVOID) virtualAddress, totalLength, FALSE, FALSE, NULL); if(mdl == NULL) { BulkUsb_DbgPrint(1, ("Failed to alloc mem for mdl\n")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; ExFreePool(rwContext); goto BulkUsb_DispatchReadWrite_Exit; } // // map the portion of user-buffer described by an mdl to another mdl // IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) virtualAddress, stageLength); urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)); if(urb == NULL) { BulkUsb_DbgPrint(1, ("Failed to alloc mem for urb\n")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; ExFreePool(rwContext); IoFreeMdl(mdl); goto BulkUsb_DispatchReadWrite_Exit; } UsbBuildInterruptOrBulkTransferRequest( urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), pipeInformation->PipeHandle, NULL, mdl, stageLength, urbFlags, NULL); // // set BULKUSB_RW_CONTEXT parameters. // rwContext->Urb = urb; rwContext->Mdl = mdl; rwContext->Length = totalLength - stageLength; rwContext->Numxfer = 0; rwContext->VirtualAddress = virtualAddress + stageLength; rwContext->DeviceExtension = deviceExtension; // // use the original read/write irp as an internal device control irp // nextStack = IoGetNextIrpStackLocation(Irp); nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; nextStack->Parameters.Others.Argument1 = (PVOID) urb; nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)BulkUsb_ReadWriteCompletion, rwContext, TRUE, TRUE, TRUE); // // since we return STATUS_PENDING call IoMarkIrpPending. // This is the boiler plate code. // This may cause extra overhead of an APC for the Irp completion // but this is the correct thing to do. // IoMarkIrpPending(Irp); BulkUsb_DbgPrint(3, ("BulkUsb_DispatchReadWrite::")); BulkUsb_IoIncrement(deviceExtension); ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); if(!NT_SUCCESS(ntStatus)) { BulkUsb_DbgPrint(1, ("IoCallDriver fails with status %X\n", ntStatus)); // // if the device was yanked out, then the pipeInformation // field is invalid. // similarly if the request was cancelled, then we need not // invoked reset pipe/device. // if((ntStatus != STATUS_CANCELLED) && (ntStatus != STATUS_DEVICE_NOT_CONNECTED)) { ntStatus = BulkUsb_ResetPipe(DeviceObject, pipeInformation); if(!NT_SUCCESS(ntStatus)) { BulkUsb_DbgPrint(1, ("BulkUsb_ResetPipe failed\n")); ntStatus = BulkUsb_ResetDevice(DeviceObject); } } else { BulkUsb_DbgPrint(3, ("ntStatus is STATUS_CANCELLED or " "STATUS_DEVICE_NOT_CONNECTED\n")); } } // // we return STATUS_PENDING and not the status returned by the lower layer. // return STATUS_PENDING; BulkUsb_DispatchReadWrite_Exit: Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); BulkUsb_DbgPrint(3, ("BulkUsb_DispatchReadWrite - ends\n")); return ntStatus; } NTSTATUS BulkUsb_ReadWriteCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: This is the completion routine for reads/writes If the irp completes with success, we check if we need to recirculate this irp for another stage of transfer. In this case return STATUS_MORE_PROCESSING_REQUIRED. if the irp completes in error, free all memory allocs and return the status. Arguments: DeviceObject - pointer to device object Irp - I/O request packet Context - context passed to the completion routine. Return Value: NT status value --*/ { ULONG stageLength; NTSTATUS ntStatus; PIO_STACK_LOCATION nextStack; PBULKUSB_RW_CONTEXT rwContext; // // initialize variables // rwContext = (PBULKUSB_RW_CONTEXT) Context; ntStatus = Irp->IoStatus.Status; UNREFERENCED_PARAMETER(DeviceObject); BulkUsb_DbgPrint(3, ("BulkUsb_ReadWriteCompletion - begins\n")); // // successfully performed a stageLength of transfer. // check if we need to recirculate the irp. // if(NT_SUCCESS(ntStatus)) { if(rwContext) { rwContext->Numxfer += rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength; if(rwContext->Length) { // // another stage transfer // BulkUsb_DbgPrint(3, ("Another stage transfer...\n")); if(rwContext->Length > BULKUSB_MAX_TRANSFER_SIZE) { stageLength = BULKUSB_MAX_TRANSFER_SIZE; } else { stageLength = rwContext->Length; } IoBuildPartialMdl(Irp->MdlAddress, rwContext->Mdl, (PVOID) rwContext->VirtualAddress, stageLength); // // reinitialize the urb // rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = stageLength; rwContext->VirtualAddress += stageLength; rwContext->Length -= stageLength; nextStack = IoGetNextIrpStackLocation(Irp); nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; nextStack->Parameters.Others.Argument1 = rwContext->Urb; nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp, BulkUsb_ReadWriteCompletion, rwContext, TRUE, TRUE, TRUE); IoCallDriver(rwContext->DeviceExtension->TopOfStackDeviceObject, Irp); return STATUS_MORE_PROCESSING_REQUIRED; } else { // // this is the last transfer // Irp->IoStatus.Information = rwContext->Numxfer; } } } else { BulkUsb_DbgPrint(1, ("ReadWriteCompletion - failed with status = %X\n", ntStatus)); } if(rwContext) { // // dump rwContext // BulkUsb_DbgPrint(3, ("rwContext->Urb = %X\n", rwContext->Urb)); BulkUsb_DbgPrint(3, ("rwContext->Mdl = %X\n", rwContext->Mdl)); BulkUsb_DbgPrint(3, ("rwContext->Length = %d\n", rwContext->Length)); BulkUsb_DbgPrint(3, ("rwContext->Numxfer = %d\n", rwContext->Numxfer)); BulkUsb_DbgPrint(3, ("rwContext->VirtualAddress = %X\n", rwContext->VirtualAddress)); BulkUsb_DbgPrint(3, ("rwContext->DeviceExtension = %X\n", rwContext->DeviceExtension)); BulkUsb_DbgPrint(3, ("BulkUsb_ReadWriteCompletion::")); BulkUsb_IoDecrement(rwContext->DeviceExtension); ExFreePool(rwContext->Urb); IoFreeMdl(rwContext->Mdl); ExFreePool(rwContext); } BulkUsb_DbgPrint(3, ("BulkUsb_ReadWriteCompletion - ends\n")); return ntStatus; } |
|
|
地下室#
发布于:2004-08-10 13:27
啊,好兄弟,你真是我的救星,我下去看看了,谢谢谢谢!!!
分全给你。。 |
|
5楼#
发布于:2004-08-10 13:35
为什么刚才还能给分,现在给不了了,一进来就是“你未登陆论坛”
我登陆了,但只要一进usb专栏就又是“你未登陆论坛” |
|
6楼#
发布于:2004-08-10 14:07
哎,我刚才看了下,还是没涉及到根本啊,这个程序已经知道了将要传回的数据大小。。。。。不是未知的,是已知的。。
|
|
7楼#
发布于:2004-08-10 14:39
其实你要求某一管道传输多少字节长度的数据,device端可以输送小于或等于你要求的长度。如果完成例程成功,它返回的值也是可以小于或等于你要求的长度。USB设备端,如果EP2长为64BYTE,但我也可以发送34个字节的数据呀,并非每次都要求64BYTE。
|
|
|
8楼#
发布于:2004-08-10 15:00
它返回的值也是可以小于或等于你要求的长度
----------请问,这个返回值在什么地方??在你给的程序中的那个地方啊?? |
|
9楼#
发布于:2004-08-10 17:31
真是急死我了,只要回答的正确(命中要害),那么我另开新贴送分,不多了!!
帮帮我把,斑竹呢??? |
|
10楼#
发布于:2004-08-10 19:03
用户被禁言,该主题自动屏蔽! |
|
11楼#
发布于:2004-08-10 21:34
这个参数在那儿呢??是不是在irp->Parameters->???的某个地方,叫什么呢?
|
|
12楼#
发布于:2004-08-10 21:37
这个参数在那儿呢??是不是在irp的stack->Parameters->???的某个地方,叫什么呢?能说说吗??
|
|
13楼#
发布于:2004-08-11 00:46
大家帮个忙啊,谢谢!!
|
|
14楼#
发布于:2004-08-11 02:41
哈哈哈,我笑啊,我终于知道了!!!
原来在提交了一个urb后,在次读取这个urb的bufferlength域,就可以读到改变后的接收数据量,原来我还以为这个是不变的呢,原来是会改变的。哈哈 还有,读取的时候如果允许读取量少于应读量,那么在读取的数据量小于应读量的情况下,urb结构中的USBD_STATUS状态会设置一个错误,但是这个我们可以不用去管他。。因为我们本来就允许这个错误存在。 多靠了lejianz的那个例子,看来我的分送的值!!!!!! 谢谢谢谢!! |
|
15楼#
发布于:2004-08-11 08:52
应该把这个收为精品帖
|
|