IRP_MJ_CLEANUP in Windows XP

Hi,

I have a driver that as part of an IOCTL locks down user pages in memory which
are unlocked again when a) the applications send it a request to that effect or
b) the application goes away. b) is taken care of in the routine handling
IRP_MJ_CLEANUP.

On Windows XP, when the application crashes (and hence never gets around to
sending my driver the "Unlock-the-Memory-IOCTL"), the cleanup routine is never
called. So, my application crashes, and once I click away the "send this bug
report to microsoft" dialog, the system goes blue screen with "driver still has
locked pages in process".

Does anyone know why XP won't call my cleanup routine when the application dies?

Thanks,

Burk.

Burkhard Daniel
Software Technologies Group, Inc.
xxxxx@stg.com * http://www.stg.com
fon: +49-179-5319489 fax: +49-179-335319489

Burkhard Daniel wrote:

I have a driver that as part of an IOCTL locks down user pages in memory which
are unlocked again when a) the applications send it a request to that effect or
b) the application goes away. b) is taken care of in the routine handling
IRP_MJ_CLEANUP.

On Windows XP, when the application crashes (and hence never gets around to
sending my driver the “Unlock-the-Memory-IOCTL”), the cleanup routine is never
called. So, my application crashes, and once I click away the “send this bug
report to microsoft” dialog, the system goes blue screen with “driver still has
locked pages in process”.

Does anyone know why XP won’t call my cleanup routine when the application dies?

You will also need a cancel routine for your IOCTL. Beware the race
conditions between the normal completion path, the IRP_MJ_CLEANUP path,
and the cancel path, though.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Now teaming with John Hyde for USB Device Engineering Seminars
Check out our schedule at http://www.oneysoft.com

Walter Oney wrote:

Burkhard Daniel wrote:

>I have a driver that as part of an IOCTL locks down user pages in memory which
>are unlocked again when a) the applications send it a request to that effect or
>b) the application goes away. b) is taken care of in the routine handling
>IRP_MJ_CLEANUP.
>
>On Windows XP, when the application crashes (and hence never gets around to
>sending my driver the "Unlock-the-Memory-IOCTL"), the cleanup routine is never
>called. So, my application crashes, and once I click away the "send this bug
>report to microsoft" dialog, the system goes blue screen with "driver still has
>locked pages in process".
>
>Does anyone know why XP won't call my cleanup routine when the application dies?

You will also need a cancel routine for your IOCTL. Beware the race
conditions between the normal completion path, the IRP_MJ_CLEANUP path,
and the cancel path, though.

Thanks for your reply.

The IOCTL isn't pending though. I have one IOCTL to "turn on" processing in the
driver which requires a locked-down memory pool, and another to turn it off.

So, I have application memory locked into kernel space even without having any
IRPs pending.

I need to get that cleanup no matter what.

Burk.

Burkhard Daniel
Software Technologies Group, Inc.
xxxxx@stg.com * http://www.stg.com
fon: +49-179-5319489 fax: +49-179-335319489

Burkhard Daniel wrote:

So, I have application memory locked into kernel space even without having any
IRPs pending.

Ah. I suggest you not do that then, for the reason you’ve discovered. In
a real pinch, I suppose you could some PsXxx routine or another to
discover when your process goes away, but it would fit the driver
architecture better to design your driver so that an IRP is always
outstanding while the buffer is locked.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Now teaming with John Hyde for USB Device Engineering Seminars
Check out our schedule at http://www.oneysoft.com

If you handle the CREATE and CLOSE irps, you can still do this. The method is not obvious, but it is possible:

Handle CREATE/CLOSE irps.

  1. In the handler, make sure the CREATE won’t fail.
    Get exclusive access.
    Verify proper required access ( irpStack->Parameters.Create.SecurityContext == PIO_SECURITY_CONTEXT ).
    Allocate all resources.
    Verify irpStack->FileObject is non-NULL
    (may be NULL from kernel, or if FS is above, other workarounds exist there)
  2. If still ok, forward the irp synchronously.
  3. If the lower driver(s) succeeded the CREATE/CLOSE:
    If close, and fileObject was used to lock memory, unlock that memory now (it’s in the list).
    Add (create) or remove (close) irpStack->FileObject in list of “allowed” object to lock memory.
    DANGER: Failure is not allowed at this point, since lower drivers
    won’t get CLOSE if you now fail what they succeeded.
  4. Release any resources that are no longer required
  5. Release exclusive access.

Then, when you receive the IOCTL that requires that you lock memory:

  1. Get exclusive access.
  2. Verify that the irpStack->FileObject is in the list of “allowed” objects to lock memory.
  3. Keep track of what memory was locked in that list to allow cleanup.
  4. Release exclusive access.

The caveat is that your application will be required to keep the handle open to the driver for the entire time that the memory is locked. However, should your application terminate unexpectedly, the handle will still be closed, initiating the CLOSE irp, thereby free’ing the memory that was locked.

Comments from people who use this method are greatly appreciated.

I hope this helps,
.

-----Original Message-----
From: Walter Oney [mailto:xxxxx@oneysoft.com]
Sent: Tuesday, February 11, 2003 10:13 AM

Burkhard Daniel wrote:

So, I have application memory locked into kernel space even without having any
IRPs pending.

Ah. I suggest you not do that then, for the reason you’ve discovered. In
a real pinch, I suppose you could some PsXxx routine or another to
discover when your process goes away, but it would fit the driver
architecture better to design your driver so that an IRP is always
outstanding while the buffer is locked.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Now teaming with John Hyde for USB Device Engineering Seminars
Check out our schedule at http://www.oneysoft.com

Remember that a cleanup will be sent to the driver only when the last handle
to the object is closed in user mode. Typically there is only one handle to
an object but if you have duplicated the handle into another process the
cleanup will not be issued until the second process closes its handle. That
might be a reason.

You should not lock down memory wihtout a pending IRP. If you had a pending
IRP and set a cancel routine on it, your cancel routine will get called.


Nar Ganapathy
Windows Core OS group
This posting is provided “AS IS” with no warranties, and confers no rights.

“Walter Oney” wrote in message news:xxxxx@ntdev…
>
> Burkhard Daniel wrote:
> > I have a driver that as part of an IOCTL locks down user pages in memory
which
> > are unlocked again when a) the applications send it a request to that
effect or
> > b) the application goes away. b) is taken care of in the routine
handling
> > IRP_MJ_CLEANUP.
> >
> > On Windows XP, when the application crashes (and hence never gets around
to
> > sending my driver the “Unlock-the-Memory-IOCTL”), the cleanup routine is
never
> > called. So, my application crashes, and once I click away the “send this
bug
> > report to microsoft” dialog, the system goes blue screen with “driver
still has
> > locked pages in process”.
> >
> > Does anyone know why XP won’t call my cleanup routine when the
application dies?
>
> You will also need a cancel routine for your IOCTL. Beware the race
> conditions between the normal completion path, the IRP_MJ_CLEANUP path,
> and the cancel path, though.
>
> –
> Walter Oney, Consulting and Training
> Basic and Advanced Driver Programming Seminars
> Now teaming with John Hyde for USB Device Engineering Seminars
> Check out our schedule at http://www.oneysoft.com
>
>