阅读:1440回复:3
为什么驱动调用总线驱动,总是发不了数据?
是这样的,我要写的U盘驱动,调用USBD,
发送struct _URB_CONTROL_DESCRIPTOR_REQUEST 这样的请求,都可以用bushound看的到,但是构造struct _URB_BULK_OR_INTERRUPT_TRANSFER这样的urb,发送过去,在bushound里面就可看不到总县有什么动作。 上次问,有人说,要实现sisi协议,一想不对,协议是建立在上层驱动上面的,现在连数据都没法发给设备,怎么实现啊~~ 读写的代码如下: typedef struct _RWCONTEXT //读写的线程环境; { struct _URB urb; //共享的urb; ULONG_PTR va; //mdl的开始地址; ULONG length; //要传输的长度; PMDL mdl; //指向当前的mdl; ULONG numxfer; //已经传送的字节数; } RWCONTEXT, *PRWCONTEXT; //----------------------- typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT fdo; //当前的功能对象 PDEVICE_OBJECT NextDev; //下层驱动对象 PUSB_DEVICE_DESCRIPTOR pDevDp; //设备描述指针 PUSB_CONFIGURATION_DESCRIPTOR pCfgDp; //设备配制指针 USBD_CONFIGURATION_HANDLE hCfg; //配制句柄 USBD_INTERFACE_HANDLE hCurInf; //当前用的接口句柄 USBD_PIPE_INFORMATION PipeReadInfo; //读的管道句柄 USBD_PIPE_INFORMATION PipeWriteInfo;//写的管道句柄 int iInfNum; //接口数,为1 int iCurPipeNum; //管道数,为2 LANGID langid; //语言ID } DEVICE_EXTENSION, *PDEVICE_EXTENSION; //------------------------------------------- //-------------------------------------------------------- NTSTATUS UsbRead(IN PDEVICE_OBJECT DevObj,IN PIRP Irp) { PDEVICE_EXTENSION dx; dx = (PDEVICE_EXTENSION)DevObj->DeviceExtension; CurIrql = KeGetCurrentIrql(); return ReadWrite(DevObj,Irp,TRUE,dx->PipeReadInfo.PipeHandle); } //---------------------------------------------------------- NTSTATUS UsbWrite(IN PDEVICE_OBJECT DevObj,IN PIRP Irp) { PDEVICE_EXTENSION dx; dx = (PDEVICE_EXTENSION)DevObj->DeviceExtension; CurIrql = KeGetCurrentIrql(); return ReadWrite(DevObj,Irp,FALSE,dx->PipeWriteInfo.PipeHandle); } //------------------------------------------------------ NTSTATUS OnReadWriteComplete(PDEVICE_OBJECT DevObj,PIRP Irp,PRWCONTEXT ctx) { PDEVICE_EXTENSION dx = DevObj->DeviceExtension; NTSTATUS status = STATUS_SUCCESS; ULONG seglen; PIO_STACK_LOCATION stack; CurIrql = KeGetCurrentIrql(); ctx->numxfer+=ctx->urb.UrbBulkOrInterruptTransfer.TransferBufferLength; status = Irp->IoStatus.Status; if(NT_SUCCESS(status)&&ctx->length) { seglen = ctx->length; if(seglen > USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE) seglen = (ULONG_PTR)PAGE_ALIGN(ctx->va)+PAGE_SIZE-ctx->va; IoBuildPartialMdl(Irp->MdlAddress,ctx->mdl,(PVOID)ctx->va,seglen); ctx->urb.UrbBulkOrInterruptTransfer.TransferBufferLength = seglen; stack = IoGetNextIrpStackLocation(Irp); stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; stack->Parameters.Others.Argument1 = (PVOID)(PURB)ctx; stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp,(PIO_COMPLETION_ROUTINE)OnReadWriteComplete, (PVOID)ctx, TRUE,TRUE,TRUE); ctx->va+=seglen; ctx->length-=seglen; IoCallDriver(dx->NextDev,Irp); return STATUS_MORE_PROCESSING_REQUIRED; } if(NT_SUCCESS(status)) Irp->IoStatus.Information = ctx->numxfer; ExFreePool(ctx->mdl); ExFreePool(ctx); return status; } //------------------------------------------------------------ NTSTATUS ReadWrite(IN PDEVICE_OBJECT DevObj,IN PIRP Irp,BOOLEAN read,USBD_PIPE_HANDLE hPipe) { PDEVICE_EXTENSION dx = DevObj->DeviceExtension; PRWCONTEXT ctx = NULL; ULONG length = 0; ULONG_PTR va = 0; ULONG urbflag = 0; ULONG seglen = 0; PMDL mdl = NULL; NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp); CurIrql = KeGetCurrentIrql(); ctx = (PRWCONTEXT)ExAllocatePool(NonPagedPool,sizeof(RWCONTEXT)); RtlZeroMemory(ctx,sizeof(RWCONTEXT)); length = Irp->MdlAddress?MmGetMdlByteCount(Irp->MdlAddress):0; if(!length) { return CompleteIrp(Irp,STATUS_SUCCESS,0); } va = (ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress); if(read) { urbflag = USBD_TRANSFER_DIRECTION_IN; } else { urbflag = USBD_TRANSFER_DIRECTION_OUT; } seglen = length; if(seglen > USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE) { seglen = (ULONG_PTR)PAGE_ALIGN(va)+PAGE_SIZE-va; } mdl = IoAllocateMdl((PVOID)va,PAGE_SIZE,FALSE,FALSE,NULL); IoBuildPartialMdl(Irp->MdlAddress,mdl,(PVOID)va,seglen); UsbBuildInterruptOrBulkTransferRequest(&ctx->urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), hPipe, NULL, mdl, seglen, urbflag, NULL); ctx->va = va+seglen; //虚拟地址 ctx->length = length-seglen; //余下的字节数 ctx->mdl = mdl; ctx->numxfer = 0; stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; stack->Parameters.Others.Argument1 = (PURB)ctx; stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)OnReadWriteComplete, (PVOID)ctx, TRUE, TRUE, TRUE); IoMarkIrpPending(Irp); status = IoCallDriver(dx->NextDev,Irp); return STATUS_PENDING; } 都是找bulkonly改的,不知道怎么也有问题,还是有什么其他的问题没有考虑到呢?那位大哥有这方面的经验,指点指点我啊 谢谢 解决了我回另外加分的~~~ |
|
最新喜欢:HuYugu... |
沙发#
发布于:2005-05-11 20:05
呵呵,是哪里出了问题呢?
|
|
板凳#
发布于:2005-05-02 09:43
弄好了
|
|
地板#
发布于:2005-05-01 11:12
顶一下
|
|