oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
阅读:1359回复:1

谁有DriverEntry中对IRP_MJ_READ及IRP_MJ_WRITE处理的源程序

楼主#
更多 发布于:2007-07-23 16:32
本人使用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;
    }
了,不知道为什么,我也只是从别的地方抄来的,肯定不对,请高手指正.

oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-07-24 09:42
怎么没有高手来解决我的问题咯,斑主呢,来帮忙解决一下咯.
游客

返回顶部