[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Can't send newly created IRP to lower device driver in serial filter

Posted on 2004-08-25
16
Medium Priority
?
527 Views
Last Modified: 2013-12-03
My Win2K/XP serial filter driver snoops on the PPP negotiation between Windows and a modem and needs to generate an IRP_MJ_WRITE request from scratch and pass it down to the lower driver. However, it seems I'm missing an important step since IoCallDriver fails.

Here's my latest code. I am getting a STATUS_UNSUCCESSFUL from IoCallDriver. I took a look at passed down IRP_MJ_WRITE requests that the driver forwards to the next lower driver and have taken a look at the related IRP and IO_STACK_LOCATION structures, hoping to find an answer to my problem. However, the structures are similar to what mine look like. The only major difference I've been seeing is in the Flags member of the IRP structure: I have seen a value of 0x40000200 on IRP_MJ_WRITE requests, which means IRP_WRITE_OPERATION (0x200) and something else that I haven't been able to track down (the 0x40000000).

I'm about to go insane with this. Top few lines just pass the current request down without doing anything with it (and it works fine). Please note that this code is all part of the master dispatch handler of my driver. Also note that pbFakeWrite has been allocated from NonPagedPool.

---cut here---
(...)
// Pass request down without additional processing
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if(!NT_SUCCESS(status))
{
    ExFreePool(pbFakeWrite);
    return CompleteRequest(Irp, status, 0);
}
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

// my extra code to send a custom IRP_MJ_WRITE to the lower driver
if(pbFakeWrite != NULL)
{
    NTSTATUS status2 = STATUS_SUCCESS;
    PIRP pNewIrp = NULL;
    PIO_STACK_LOCATION pStack = NULL;
    LARGE_INTEGER startingOffset;
    startingOffset.QuadPart = 0;
    pNewIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE, pdx->LowerDeviceObject, pbFakeWrite, ulFakeWriteLen, &startingOffset, NULL);
    if(pNewIrp == NULL)
    {
        ExFreePool(pbFakeWrite);
        status2 = STATUS_INSUFFICIENT_RESOURCES;
        return status2;
    }
    pNewIrp->Flags |= IRP_WRITE_OPERATION; // not sure if that is needed
    status2 = IoAcquireRemoveLock(&pdx->RemoveLock, pNewIrp);
    if(!NT_SUCCESS(status2))
    {
        IoFreeIrp(pNewIrp);
        ExFreePool(pbFakeWrite);
        return status2;
    }
    pStack = IoGetNextIrpStackLocation(pNewIrp); // for debugging purposes
    KdPrint(("pStack->Parameters.Write: %d\n", pStack->Parameters.Write.Length));
    IoSetCompletionRoutine(pNewIrp, (PIO_COMPLETION_ROUTINE)CompletionRoutine, pdx, TRUE, TRUE, TRUE);
    status2 = IoCallDriver(pdx->LowerDeviceObject, pNewIrp);
    if(!NT_SUCCESS(status2))
    {
        KdPrint(("IoCallDriver failed (%08X)\n", status2));
    }
}
(...)
---cut here---
0
Comment
Question by:bbousquet
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 2
  • +1
16 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 11895851
What is the status code?
0
 
LVL 86

Expert Comment

by:jkr
ID: 11895855
>>I am getting a STATUS_UNSUCCESSFUL from IoCallDriver

Disregard my last comment :o)
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 11896477

Extending jkr's question a little bit..
Have you checked the Status value returned in the IO_STATUS block of your new IRP after you get the error ?
There is a chance that you'll find a "better" error code there.

Btw I'm just curious, is there a specific reason why you picked IoBuildAsynchronousFsdRequest to allocate the IRP ?
I am not saynig there is something wrong with it.. but I used to use the "old" IoBuildDeviceIoControlRequest() call



0
Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

 
LVL 2

Author Comment

by:bbousquet
ID: 11896588
I'm at DISPATCH_LEVEL so I can't wait on an event (well, unless it's a zero wait, which kind of defeats the purpose of it all). It was suggested to me that IoBuildAsynchronousFsdRequest would be a better choice than IoAllocateIrp since it takes care of the buffering method used by the lower driver.

As for the IO_STATUS_BLOCK, I'll take another look at it and post my findings, if any.
0
 
LVL 2

Author Comment

by:bbousquet
ID: 11896631
Just checked: the IO_STATUS_BLOCK contains the same error code (0xc0000001, STATUS_UNSUCCESSFUL) returned by IoCallDriver.
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 11897235

>> Just checked: the IO_STATUS_BLOCK contains the same error code (0xc0000001, STATUS_UNSUCCESSFUL) returned by IoCallDriver.
     
      Did you pass in a valid address of an IO_STATUS_BLOCK to IoBuildAsynchronousFsdRequest() ?
      Looks like you are passing NULL instead .

>> pNewIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE, pdx->LowerDeviceObject, pbFakeWrite, ulFakeWriteLen, &startingOffset, NULL);
0
 
LVL 2

Author Comment

by:bbousquet
ID: 11897450
I just tried it (again) and whether or not I am passing an IO_STATUS_BLOCK pointer, it doesn't make any difference.
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 11897714

okay.. one last thing and I quit :)

Its been a while and sorry if I'm worng.
Is it buffered IO or Direct IO ?
I guess you should use MDL's to pass a buffer to a lower layer driver if it supports DirectIO.
I am talking about your pbFakeWrite buffer.
0
 
LVL 2

Author Comment

by:bbousquet
ID: 11897835
From what I understand, this is the main advantage of using IoBuildAsynchronousFsdRequest, as it automatically handles the buffering mode. I just need to do the proper cleanup in my completion routine.
0
 
LVL 2

Author Comment

by:bbousquet
ID: 11933511
I needed to fill the FileObject member of the IRP. This seems to work now. Question can be deleted.
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 11933538

Hwoo!! I thought all that happens automatically when you build the irp.
Btw, how did you figure that out ?
0
 
LVL 2

Author Comment

by:bbousquet
ID: 11933582
Everything else seems to be done automatically, but from what I was able to learn, the FileObject member is used to keep track of some kind of context data. I was just trying semi-random things and ended up noticing that mine was NULL. Since my write request needs to be seen as a system generated one, I just copied the FileObject from the last IRP_MJ_WRITE into my IRP. Now IoCallDriver no longer fails...
0
 
LVL 8

Expert Comment

by:mxjijo
ID: 11933608

Interesting.. anyway.. nice that its working..
Goog luck. :)
~j
0
 
LVL 2

Author Comment

by:bbousquet
ID: 12137954
This question can be closed, as I stumbled upon the answer myself.
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 12446612
PAQed, with points refunded (500)

modulo
Community Support Moderator
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows a few slightly more advanced techniques for Windows 7 gadget programming, including how to save and restore user settings for your gadget and how to populate the "details" panel that is displayed in the Windows 7 gadget gallery.  …
This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question