Fatal bug in DDK sample?

Fatal bug in DDK sample?

Post by nir140 » Wed, 27 Oct 2004 18:41:43


Hello,

I am writing my first driver and have come across what seems to be a
fatal bug in a DDK sample.
I would appreciate your opinion and if it is indeed a bug, an advice on
how to work around it.
Also this may have some general importance since the DDK directly
recommends developers to base their code on the DDK samples.

My driver is a filter driver and the problematic DDK sample is:
\WINDDK\3790\src\general\toaster\filter\filter.c
Please take a look at the relevant functions there if you feel my
description is confusing.

The DDK sample filter driver creates a special named device for
applications to control the driver directly.
The special-device is created in function FilterCreateControlObject().
The remark there says "Create a named device object so that applications
or drivers can directly talk to us without going through the entire stack."

The special-device is created when the first PNP device (that
corresponds to the driver stack) starts and is destroyed when the last
PNP device is removed.
A pointer to the special-device object is kept in a global variable.
The global pointer is reset to NULL when the special-device is destroyed.

A single function FilterDispatchIo() handles IRPs (IRP_MJ_CREATE,
IRP_MJ_CLOSE, IRP_MJ_CLEANUP, IRP_MJ_DEVICE_CONTROL) to all of the
driver's devices.
The function needs to decide if the IRP was sent to a PNP device or to
the special-device.
For that purpose the function compares the argument device object
pointer to the global pointer of the special-device.
If they don't match it assumes it is an IRP sent to the PNP device stack
and switches to handle it on.
If they match it assumes it is an IRP sent to the special-device.

This is it.

The scenario that breaks the driver:
1. A first PNP device starts
2. The special-device is created.
3. A user mode app opens a handle and sends IRPs to the special-device
to control the driver.
4. The PNP device is unplugged.
5. The driver receives an IRP to remove the PNP device and also deletes
the special-device and resets the global pointer to NULL.
6. A new IRP is received for the special-device which has been sent by
the User mode APP to control the driver.
7. The driver compares the argument device object pointer to the global
pointer for the special-device. They don match since the global
pointer is NULL.
8. The driver thinks it is an IRP for the PNP device and tries to
forward it down the driver stack.
9. BOOM!

This is not a theoretical scenario.
I have a 100% repro.

I will appreciate your opinion.
Thanks,
Nir
 
 
 

Fatal bug in DDK sample?

Post by Calvin Gua » Wed, 27 Oct 2004 21:15:54


[OT] I would suggest you write every single line of code for your driver
whenever possible. In this way, you know exactly who does what to whom,
when. You won't be overlooking something that others have done in the
sample. You will learn much more than expected. I read sample code only for
detail implementation reference purpose but still, I will not cut ' paste
code from others unless I'm not interested in it at all.


It seems a bug to me. To tell ControlObject from FilterObject, I setup a
DeviceType field in my DevExt, they are initialized to when the DO was
created.

--
Calvin Guan SW Engineer/Radeon NT Driver
ATI Technologies Inc. Markham ON,Canada
www.ati.com

 
 
 

Fatal bug in DDK sample?

Post by Eliyas Yak » Wed, 27 Oct 2004 22:49:06

I will fix the sample so that it doesn't crash and fail further I/O on a
deleted device. But the ideal solution is to make sure the app closes the
handle when the pnp device is removed by registering for pnp device change
notification on the interface exposed by the pnp device stack. The whole
point of deleting the control device is so that the driver can unload when
the last instance of the device is removed. If you keep the handle open, the
filter will driver will be stuck in memory forever.

--
 
 
 

Fatal bug in DDK sample?

Post by Calvin Gua » Wed, 27 Oct 2004 23:26:56


the

IIRC, if a console app is not able to receive notification. Dealing with
such situation is pain in the butt. That's why I try to do everything with
WMI in my filter driver.

--
Calvin Guan Software Engineer/Radeon NT Drivers
ATI Technologies Inc. Markham ON, Canada
www.ati.com
 
 
 

Fatal bug in DDK sample?

Post by UGF2ZWwgQS » Thu, 28 Oct 2004 00:11:03


Console apps can create a hidden window.

But how an IRP can reach the driver after all device objects are deleted?
Will i/o manager simply fail IoCallDriver directed to invalid DEVICE_OBJECT?

--PA
 
 
 

Fatal bug in DDK sample?

Post by Calvin Gua » Thu, 28 Oct 2004 01:46:16


Nice trick, thanks.

IoDeleteDevice will not delete the object itself if there's outstanding
handle/pointer count. ObDereferenceObject will do if counter reaches zero.

DEVICE_OBJECT?
Based on observation, I/O manager doesn't seem doing that.

--
Calvin Guan Software Engineer/Radeon NT Drivers
ATI Technologies Inc. Markham ON, Canada
www.ati.com
 
 
 

Fatal bug in DDK sample?

Post by nir140 » Thu, 28 Oct 2004 05:20:31


I think using working samples and code is a powerful technic:
1. It saves a lot of time
2. It is a great opportunity to learn from other people's way of thinking.
3. It is fun trying to find bugs in other people's logic :)
4. Working code usually includes hundreds of man hours of debugging and
testing. It is a shame to throw that away.


Thanks! I switched to determining the device type by a special type
field and it works.

Nir
 
 
 

Fatal bug in DDK sample?

Post by Doron Hola » Thu, 28 Oct 2004 11:40:25

i agree w/calvin. creating a common header for both types of extensions and
keying off of a type field in the common extension is the easiest and most
maintainable way to go.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
 
 
 

Fatal bug in DDK sample?

Post by Alexander » Thu, 28 Oct 2004 12:43:10

I must say that having per-driver function table was very big oversight of
original NT design. I wonder if it's possible to retrofit the DEVICE_OBJECT
with per-DO function table. Of course, I could have a table pointer in
DevExt, but I'd rather had it in DevObj, to allow the OS directly use it,
instead of me making second indirection through my function table.
 
 
 

Fatal bug in DDK sample?

Post by Maxim S. S » Fri, 29 Oct 2004 03:10:48

> IIRC, if a console app is not able to receive notification.

Nothing prevents you from creating invisible windows in the console app.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
XXXX@XXXXX.COM
http://www.yqcomputer.com/
 
 
 

Fatal bug in DDK sample?

Post by Maxim S. S » Fri, 29 Oct 2004 03:12:13

> > Console apps can create a hidden window.

More so. The console app can create the visible windows too, same way as
"-subsystem:windows" app.

The difference between them is stdin/stdout behaviour and whether CreateProcess
will wait for child termination.


No. IoCallDriver is a short routine, you can look in disassembly.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
XXXX@XXXXX.COM
http://www.yqcomputer.com/
 
 
 

Fatal bug in DDK sample?

Post by Maxim S. S » Fri, 29 Oct 2004 03:14:54

> I think using working samples and code is a powerful technic:

...which will be then lost during debugging.


Copy-pasting without reading is not a way to study anything.


Not all samples are this good. The working "combat" NT drivers like Serial are
surely the industry-quality code, but it is possibly not so with the
illustrative samples.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
XXXX@XXXXX.COM
http://www.yqcomputer.com/
 
 
 

Fatal bug in DDK sample?

Post by Calvin Gua » Fri, 29 Oct 2004 04:29:14


DEVICE_OBJECT

I like that. Let's name it ROCKET_IO_DISPATCH-:)
I've 5-6 DO types in my hybrid function/bus filter driver that requires
different dispatching for the same IRP_MJ_Xxx.

--
Calvin Guan Software Engineer/Radeon NT Drivers
ATI Technologies Inc. Markham ON, Canada
www.ati.com
 
 
 

Fatal bug in DDK sample?

Post by Mark Rodd » Tue, 02 Nov 2004 00:56:51

In article <# XXXX@XXXXX.COM >, XXXX@XXXXX.COM
says...



Which of course is why I use base classes with specialized per device object
type child classes. Yes there is the overhead of the redispatch through the
VFT, yes microsoft gets hives over c++ for US in the kernel (its ok for THEM,)
but really this sort of design problem has been solved for quite some time.

--

=====================
Mark Roddy DDK MVP
Windows 2003/XP/2000 Consulting
Hollis Technology Solutions 603-321-1032
www.hollistech.com
XXXX@XXXXX.COM
 
 
 

Fatal bug in DDK sample?

Post by Alexander » Tue, 02 Nov 2004 04:16:03

I'm using my own C++ framework, too. With it, I don't have to use C kludges.
But I feel sorry for those who's got to copy-paste PNP code from some sample
or previous design, modify corresponding functions, replace the function
name prefixes (MYDRIVER_), etc. This state of things is a shame. WDF might
be a step forward, but I'd really like to see it implemented as C++
framework.