ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

NTSTATUS FreeBT_DispatchRead ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 23 of file fbtrwr.c.

{
    PMDL                    mdl;
    PURB                    urb;
    ULONG                   totalLength;
    ULONG                   stageLength;
    NTSTATUS                ntStatus;
    ULONG_PTR               virtualAddress;
    PFILE_OBJECT            fileObject;
    PDEVICE_EXTENSION       deviceExtension;
    PIO_STACK_LOCATION      irpStack;
    PIO_STACK_LOCATION      nextStack;
    PFREEBT_RW_CONTEXT      rwContext;
    //ULONG                   maxLength=0;

    urb = NULL;
    mdl = NULL;
    rwContext = NULL;
    totalLength = 0;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    fileObject = irpStack->FileObject;
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Entered\n"));

    if (deviceExtension->DeviceState != Working)
    {
        FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Invalid device state\n"));
        ntStatus = STATUS_INVALID_DEVICE_STATE;
        goto FreeBT_DispatchRead_Exit;

    }

    // Make sure that any selective suspend request has been completed.
    if (deviceExtension->SSEnable)
    {
        FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Waiting on the IdleReqPendEvent\n"));
        KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);

    }

    rwContext = (PFREEBT_RW_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(FREEBT_RW_CONTEXT));
    if (rwContext == NULL)
    {
        FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for rwContext\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto FreeBT_DispatchRead_Exit;

    }

    if (Irp->MdlAddress)
    {
        totalLength = MmGetMdlByteCount(Irp->MdlAddress);

    }

    FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Transfer data length = %d\n", totalLength));
    if (totalLength == 0)
    {
        ntStatus = STATUS_SUCCESS;
        ExFreePool(rwContext);
        goto FreeBT_DispatchRead_Exit;

    }

    virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress);
    if (totalLength > deviceExtension->DataInPipe.MaximumPacketSize)
    {
        stageLength = deviceExtension->DataInPipe.MaximumPacketSize;

    }

    else
    {
        stageLength = totalLength;

    }

    mdl = IoAllocateMdl((PVOID) virtualAddress, totalLength, FALSE, FALSE, NULL);
    if (mdl == NULL)
    {
        FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for mdl\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        ExFreePool(rwContext);
        goto FreeBT_DispatchRead_Exit;

    }

    // map the portion of user-buffer described by an mdl to another mdl
    IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) virtualAddress, stageLength);
    urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
    if (urb == NULL)
    {
        FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for urb\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        ExFreePool(rwContext);
        IoFreeMdl(mdl);
        goto FreeBT_DispatchRead_Exit;

    }

    UsbBuildInterruptOrBulkTransferRequest(
                            urb,
                            sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                            deviceExtension->DataInPipe.PipeHandle,
                            NULL,
                            mdl,
                            stageLength,
                            USBD_SHORT_TRANSFER_OK | USBD_TRANSFER_DIRECTION_IN,
                            NULL);

    // set FREEBT_RW_CONTEXT parameters.
    rwContext->Urb             = urb;
    rwContext->Mdl             = mdl;
    rwContext->Length          = totalLength - stageLength;
    rwContext->Numxfer         = 0;
    rwContext->VirtualAddress  = virtualAddress + stageLength;

    // 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)FreeBT_ReadCompletion,
                           rwContext,
                           TRUE,
                           TRUE,
                           TRUE);

    // We return STATUS_PENDING; call IoMarkIrpPending.
    IoMarkIrpPending(Irp);

    ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
    if (!NT_SUCCESS(ntStatus))
    {
        FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: 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 = FreeBT_ResetPipe(DeviceObject, deviceExtension->DataInPipe.PipeHandle);
            if(!NT_SUCCESS(ntStatus))
            {
                FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: FreeBT_ResetPipe failed\n"));
                ntStatus = FreeBT_ResetDevice(DeviceObject);

            }

        }

        else
        {
            FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: ntStatus is STATUS_CANCELLED or STATUS_DEVICE_NOT_CONNECTED\n"));

        }

    }

    FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead::"));
    FreeBT_IoIncrement(deviceExtension);

    FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: URB sent to lower driver, IRP is pending\n"));

    // we return STATUS_PENDING and not the status returned by the lower layer.
    return STATUS_PENDING;

FreeBT_DispatchRead_Exit:
    Irp->IoStatus.Status = ntStatus;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Leaving\n"));

    return ntStatus;

}

Generated on Fri May 25 2012 05:19:40 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.