阅读:1359回复:1
谁有DriverEntry中对IRP_MJ_READ及IRP_MJ_WRITE处理的源程序
本人使用Cy7c68013A进行开发,其它例程都已经完成,控制传输找资料已经完成.
只是剩下 DriverObject->MajorFunction[IRP_MJ_WRITE] = Ezusb_Write; //写入数据 DriverObject->MajorFunction[IRP_MJ_READ] = Ezusb_Read; //读取数据 这两个例程没有完成,本人没有写过此类例程,不知如何下手,有知道的朋友告知一下相关的消息也行,谢谢了. NTSTATUS Ezusb_Read( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { 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; PVOID IoBuffer; // // 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; IoBuffer = Irp->AssociatedIrp.SystemBuffer; if(fileObject && fileObject->FsContext) { pipeInformation = fileObject->FsContext; if((UsbdPipeTypeBulk != pipeInformation->PipeType) && (UsbdPipeTypeInterrupt != pipeInformation->PipeType)) { ntStatus = STATUS_INVALID_HANDLE; goto BulkUsb_DispatchRead_Exit; } } else { ntStatus = STATUS_INVALID_HANDLE; goto BulkUsb_DispatchRead_Exit; } rwContext = (PBULKUSB_RW_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(BULKUSB_RW_CONTEXT)); if(rwContext == NULL) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto BulkUsb_DispatchRead_Exit; } if(Irp->MdlAddress) { totalLength = MmGetMdlByteCount(Irp->MdlAddress); } if(totalLength > BULKUSB_TEST_BOARD_TRANSFER_BUFFER_SIZE) { ntStatus = STATUS_INVALID_PARAMETER; ExFreePool(rwContext); goto BulkUsb_DispatchRead_Exit; } if(totalLength == 0) { ntStatus = STATUS_SUCCESS; ExFreePool(rwContext); goto BulkUsb_DispatchRead_Exit; } urbFlags = USBD_SHORT_TRANSFER_OK; virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress); if(read) { urbFlags |= USBD_TRANSFER_DIRECTION_IN; } else { urbFlags |= USBD_TRANSFER_DIRECTION_OUT; } // // 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) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; ExFreePool(rwContext); goto BulkUsb_DispatchRead_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) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; ExFreePool(rwContext); IoFreeMdl(mdl); goto BulkUsb_DispatchRead_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)Ezusb_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_IoIncrement(deviceExtension); ntStatus = IoCallDriver(deviceExtension->StackDeviceObject, Irp); if(!NT_SUCCESS(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)) { ULONG pipenum = *((PULONG) irpStack); /*ntStatus = UsbResetPipe(DeviceObject, pipeInformation);*/ ntStatus = UsbResetPipe(DeviceObject, pipenum); if(!NT_SUCCESS(ntStatus)) { //ntStatus = BulkUsb_ResetDevice(DeviceObject); } } else { } } // // we return STATUS_PENDING and not the status returned by the lower layer. // return STATUS_PENDING; BulkUsb_DispatchRead_Exit: Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return ntStatus; } 这是我找资料写的一个写例程.我用softIce进行调试时if(fileObject && fileObject->FsContext) 这里就没有往下执行,直接跳到 else { ntStatus = STATUS_INVALID_HANDLE; goto BulkUsb_DispatchRead_Exit; } 了,不知道为什么,我也只是从别的地方抄来的,肯定不对,请高手指正. |
|
沙发#
发布于:2007-07-24 09:42
怎么没有高手来解决我的问题咯,斑主呢,来帮忙解决一下咯.
|
|