dispatch and completion routine in filter

Discussion in 'Windows Vista Drivers' started by Jürgen Wischer, Nov 2, 2004.

  1. Hello,

    I wrote a dispatch routine for MJ_WRITE which splits the Systembuffer
    (IRP) into several characters and creates a new IRP for each.

    When I return STATUS_SUCCESS in the completion routine the pc reboots
    immediately without showing a blue screen.
    Returning STATUS_MORE_PROCESSING_REQUIRED and sending only one character
    to the filter is leading to a closed loop output of the incoming char.
    But there is no following blue screen or reboot.

    Perhaps somebody can help me....

    thanks,
    Jürgen

    my dispatch routine:

    NTSTATUS DispatchWrite(IN PDEVICE_OBJECT fido, IN PIRP Irp)
    {

    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

    NTSTATUS status;
    status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
    if (!NT_SUCCESS(status))
    return CompleteRequest(Irp, status, 0);



    pdx->buffer = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
    pdx->nbytes = stack->Parameters.Write.Length;


    NTSTATUS status2 = STATUS_SUCCESS;
    PIRP pNewIrp;
    PIO_STACK_LOCATION pStack;
    PVOID pbFakeWrite;

    for(int i=0;i < pdx->nbytes; i++)
    {
    status2 = STATUS_SUCCESS;
    pNewIrp = NULL;


    pNewIrp = IoAllocateIrp(pdx->LowerDeviceObject->StackSize, false);

    if (pNewIrp)
    {

    pbFakeWrite = ExAllocatePool( NonPagedPool, 1);

    RtlCopyMemory(pbFakeWrite, &pdx->buffer, 1);

    pStack = IoGetNextIrpStackLocation(pNewIrp);
    pStack->MajorFunction = IRP_MJ_WRITE;
    pStack->DeviceObject = pdx->LowerDeviceObject ;
    pStack->Parameters.Write.Length = 1;

    pNewIrp->AssociatedIrp.SystemBuffer = pbFakeWrite;

    IoSetCompletionRoutine(pNewIrp,
    (PIO_COMPLETION_ROUTINE)CompletionRoutine,
    pdx, TRUE, TRUE, TRUE);

    status2 = IoCallDriver(pdx->LowerDeviceObject, pNewIrp);

    IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

    }
    }

    CompleteRequest(Irp, status, 0);
    return status;
    }


    ###################################


    my completion routine:


    NTSTATUS CompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID
    Context)
    {

    if (Irp->PendingReturned)
    IoMarkIrpPending(Irp);

    IoReleaseRemoveLock(&((PDEVICE_EXTENSION)Context)->RemoveLock, Irp);

    return STATUS_SUCCESS;
    }
     
    Jürgen Wischer, Nov 2, 2004
    #1
    1. Advertisements

  2. Jürgen Wischer

    Calvin Guan Guest

    comments inline
    Seems to me a strange design.
    You don't need to set the DevObj, IoCallDriver will do so.


    Make sure you correctly propagate the DO_XXX flags when attaching to the
    lower.
    Seems to me you're releasing the lock within the loop but you only acquire
    the lock once when entering the dispatch routine??
    You must NOT mark irp pending here since you don't have a valid stack.
    You must acquire the lock for each invocation of IoCallDriver in order to
    match up.
    You need to return SMPR and de-allocate the IRP.
    Connect a debugger to the target machine.
     
    Calvin Guan, Nov 2, 2004
    #2
    1. Advertisements

  3. Thanks for your answer! I corrected my mistakes. But there is still the
    problem with the closed loop. When I send one character to the filter
    the output device repeats it without any break.

    It seems to me that the IRP is not de-allocated.



    My new completion routine looks like this:


    if(Irp->AssociatedIrp.SystemBuffer != NULL)
    {
    ExFreePool(Irp->AssociatedIrp.SystemBuffer);
    }

    IoFreeIrp(Irp);

    IoReleaseRemoveLock(&((PDEVICE_EXTENSION)Context)->RemoveLock, Irp);

    return STATUS_MORE_PROCESSING_REQUIRED;




    It is strange but this is the only way I can do it.

    In <> I asked if this will be possible.
     
    Jürgen Wischer, Nov 3, 2004
    #3
  4. Jürgen Wischer

    Calvin Guan Guest

    Thanks for your answer!
    no problem.
    What do you mean by 'repeats it without any break'? Does the lower complete
    ever complete a single request?
    Do you imply the completion routine wasn't get call? I would use a debugger
    to set a BP in the completion routine. If the BP never fire, then the lower
    is not likely completing the IRP.

    HTH,
    Calvin
     
    Calvin Guan, Nov 3, 2004
    #4
  5. What do you mean by 'repeats it without any break'? Does the lower complete
    The completion routine is called but the character I have send to the
    serial upper filter is issued in a closed loop. e.g. I enter "k" in a
    terminal window and I get "kkkkkkkkkkkkkkkkkkk..." never-ending as the
    device output.

    When I have a look at the debugger output it looks like this:

    dispatch function is called for about 50 times
    after this alternately "complete request" and "completion routine" about
    50 times


    Jürgen
     
    Jürgen Wischer, Nov 4, 2004
    #5
  6. Jürgen Wischer

    Mark Roddy Guest

    Offhand I'd say you were sending the received byte to yourself. Could you walk
    through (again perhaps) exactly where your driver is located in the device
    stack, and what the data flow is through your driver?
    --

    =====================
    Mark Roddy DDK MVP
    Windows 2003/XP/2000 Consulting
    Hollis Technology Solutions 603-321-1032
    www.hollistech.com
     
    Mark Roddy, Nov 4, 2004
    #6
  7. Offhand I'd say you were sending the received byte to yourself. Could you walk
    My filter is the first element in the device stack. The filter skips all
    IRPs except the MJ_WRITE to lower devices. For this I wrote the
    dispatch and completion routine which you can see on the top of the thread.
    It's a filter for a serial port. When I am measuring at the output port
    I can see that the device is sending the character I have entered but
    never-ending... so it is the same as in the terminal window.
     
    Jürgen Wischer, Nov 5, 2004
    #7
    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.