The IoCallDriver with DISPATCH IRQL

Discussion in 'Windows Vista Drivers' started by Giuseppe, Dec 5, 2008.

  1. Giuseppe

    Giuseppe Guest

    Why the following code works only with IRQL = PASSIVE_LEVEL, but not with IRQL = DISPATCH_LEVEL. I helped to add what is lacking?

    Thank you


    --------------------------------------------------------------------------------

    typedef struct _COMPLETION_ROUTINE_CONTEXT { KEVENT event; IO_STATUS_BLOCK ioStatus; } COMPLETION_ROUTINE_CONTEXT;

    NTSTATUS CallUSBD_RequestComplete( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN COMPLETION_ROUTINE_CONTEXT *pev )
    {
    KeSetEvent( &(pev->event), 0, FALSE);
    RtlCopyMemory( &(pev->ioStatus), &(Irp->IoStatus), sizeof(pev->ioStatus) );
    return STATUS_MORE_PROCESSING_REQUIRED;
    }

    NTSTATUS CallUSBD( IN PDEVICE_OBJECT fdo,IN PURB Urb, IN PLARGE_INTEGER Timeout OPTIONAL )
    {
    NTSTATUS ntStatus, status = STATUS_SUCCESS;
    PDEVICE_EXTENSION pdx;
    PIRP irp;
    PIO_STACK_LOCATION nextStack;
    //KEVENT event;
    //IO_STATUS_BLOCK ioStatus;
    COMPLETION_ROUTINE_CONTEXT CompletionContext;

    pdx = fdo->DeviceExtension;

    KeInitializeEvent( &CompletionContext.event, NotificationEvent, FALSE);

    if ( KeGetCurrentIrql() <= APC_LEVEL )
    {
    irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_SUBMIT_URB, pdx->StackDeviceObject, NULL, 0, NULL, 0, TRUE, &CompletionContext.event, &CompletionContext.ioStatus );
    }
    else
    {
    irp = IoAllocateIrp( (CCHAR) (pdx->StackDeviceObject->StackSize + 1), FALSE );
    IoInitializeIrp( irp, irp->Size, (CCHAR) (pdx->StackDeviceObject->StackSize + 1) );
    }

    // Prepare for calling the USB driver stack
    nextStack = IoGetNextIrpStackLocation( irp );
    ASSERT( nextStack != NULL );

    if ( KeGetCurrentIrql() > APC_LEVEL )
    {
    nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
    nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    IoSetCompletionRoutine( irp, (PIO_COMPLETION_ROUTINE) CallUSBD_RequestComplete, (PVOID) &CompletionContext, TRUE, TRUE, TRUE );
    }

    // Set up the URB ptr to pass to the USB driver stack
    nextStack->Parameters.Others.Argument1 = Urb;

    ntStatus = IoCallDriver( pdx->StackDeviceObject, irp );

    if (ntStatus == STATUS_PENDING)
    {
    status = KeWaitForSingleObject( &CompletionContext.event, Suspended, KernelMode, FALSE, NULL );

    if( status == STATUS_TIMEOUT )
    { // we timed out - cancel the IRP
    IoCancelIrp( irp );
    KeWaitForSingleObject( &CompletionContext.event, Executive, KernelMode, FALSE, NULL );
    }

    }
    else
    {
    CompletionContext.ioStatus.Status = ntStatus;
    }

    ntStatus = CompletionContext.ioStatus.Status;

    if (!(USBD_SUCCESS(Urb->UrbHeader.Status)))
    pdx->LastFailedUrbStatus = Urb->UrbHeader.Status;

    if (NT_SUCCESS(ntStatus))
    {
    if (!(USBD_SUCCESS(Urb->UrbHeader.Status)))
    ntStatus = STATUS_UNSUCCESSFUL;
    }

    return ntStatus;
    }
     
    Giuseppe, Dec 5, 2008
    #1
    1. Advertisements

  2. Giuseppe

    Abei Guest

    You can't use KeWaitForSingleObject function with time equal NULL (that means
    for ever) when IRQL is Dispatch level.
     
    Abei, Dec 5, 2008
    #2
    1. Advertisements

  3. Giuseppe

    Tim Roberts Guest

    Why not the simpler:
    pev->ioStatus = Irp->IoStatus;
     
    Tim Roberts, Dec 9, 2008
    #3
  4. Why the following code works only with IRQL = PASSIVE_LEVEL, but not with IRQL =
    IoBuildDeviceIoControlRequest cannot work at DISPATCH
     
    Maxim S. Shatskih, Dec 12, 2008
    #4
  5. Giuseppe

    Giuseppe Guest

    Before calling IoBuildDeviceIoControlRequest (..) verify that IRQL is
    PASSIVE_LEVEL. Otherwise, use the IoAllocateIrp (..)
    See initial message for the full listing.

    IoBuildDeviceIoControlRequest cannot work at DISPATCH
     
    Giuseppe, Dec 12, 2008
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.