Re: Multiple DeviceObjects
- From: "Peter Wieland [MSFT]" <peterwie@xxxxxxxxxxxxxxxxxxxx>
- Date: Sun, 18 Jun 2006 04:02:39 GMT
multiple applications can open a single device object if you haven't set the
DO_DEVICE_EXCLUSIVE bit in the device object flags. But you can't tell
which sensor they're opening. If you need to do that you can define a a
"namespace" for your object using file-system type notation.
Say your device object is \device\sensors. Clients can open \device\sensors
multple times, but they could also open \device\sensors\1,
\device\sensors\2, \device\sensors\temperature\outside, etc... This will
work with symbolic links too. If you had a link to \??\sensors then clients
could open \\.\sensors\1 with the same effect.
All of these create operations will go to \Device\Sensors (your device).
Most drivers don't care - they'll just ignore the namespace. You can use it
to distinguish which sensor is being opened. You do this by checking the
FileObject->FileName. If it's a zero length string then there's no trailing
name. If there's a string there, then it's the goop after the name of your
device ("1", "2", "temperature\outside", etc...) and you can parse that to
figure out what sensor the client was trying to open (*).
Once you know which sensor they want, you'll need to record that someplace.
You can't use your device extension, because that's shared with every other
open handle to your device. The file object though, is associated with this
particular handle (**), so it's a great place to keep this information. You
can use the FsContext field in the FileObject - allocate a chunk of memory
and store your per-client context in that field.
Every IRP that you receive will have the corresponding FileObject in the
current stack location. So you can grab your context from the FsContext
field to find out which sensor the client wants to access.
When the client is done with your device it calls CloseHandle. This will
result in one (or more) IRP_MJ_CLEANUP requests. When you get this you
should complete any outstanding I/O with STATUS_CANCELLED (at least any that
won't complete soon on its own). Once all the outstanding I/O is done
you'll get an IRP_MJ_CLOSE - here you free your FsContext structure, drop
the reference count on your per-sensor data, power the sensor down, etc...
This will also work with device interfaces if you have a PNP driver.
IoRegisterDeviceInterface takes a "ReferenceString" which is normally blank.
If you supply this string - say providing "1", the IO manager will append it
to the symbolic link it creates for the interface. When someone enumerates
your interface and opens the corresponding DevicePath
("goopity_goopity_goopity\1"), you'll see "1" in the file object name when
you get the create. So if you have 20 sensors - 10 of type x and 10 of type
y, you can use device interfaces to distingish them by type to clients (so a
client could open all the type x sensors if it wanted easily) and the
ReferenceString to distingish each sensor to your driver.
There are some gotchas with doing this. The namespace stuff is targetted at
file systems, which do their own exclusive management, their own security
management, etc. If you want each sensor to be exclusive then you need to
keep track of how many times each one has been opened and fail the
IRP_MJ_CREATE requests yourself if the one the client wants is already in
use. You also should specify FILE_DEVICE_SECURE_OPEN in the characteristics
for your device object so the I/O manager checks the device object's ACL for
namespace opens.
If you're not going to turn your driver into a bus driver and expose each
sensor through PNP, then i think this namespace stuff is a lot cleaner than
just creating a dozen "sensor" device objects.
-p
* The string is only valid in the context of IRP_MJ_CREATE, so you can't
parse it on each read or write to see what sensor is being used. You need
to allocate an FsContext and store the information in there.
** Well it's a little wierder than that. The client can duplicate the
handle multiple times, and even to other processes and you'll never get
another IRP_MJ_CREATE. You'll get an IRP_MJ_CLEANUP when the last user-mode
handle has been closed. Other user-mode I/O could still be in flight, so
it's not a hard stop.
The IRP_MJ_CLOSE comes some time later when the reference count on the file
object drops to zero. Often this is after the cleanup is completed, but it
could take some time if, for example, a kernel-mode driver had opened your
device and was keeping the file object around to send kernel-mode I/O to it.
So you can't really clean-up until you get the close request. When you do
get the close, there won't be any user-mode I/O in flight.
--
This posting is provided "AS IS" with no warranties, and confers no rights.
"dave" <dave@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:D8773BDA-17BB-4A7C-AEB0-1B423A3446BE@xxxxxxxxxxxxxxxx
I'd like to have more then one user-mode appl
talking to sensors.
dave
"Peter Wieland [MSFT]" wrote:
why do you want a seperate device object for each sensor?
-p
--
This posting is provided "AS IS" with no warranties, and confers no
rights.
"dave" <dave@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:33446352-67FD-4836-A28A-23B0CD11E3F9@xxxxxxxxxxxxxxxx
Hello:
I have user-mode appl that through monolitic
kernel-driver communicate with sensors connected
to data register of parallel port.
I'd like to have separate DeviceObject for each sensor.
Is it right to do it by calling IoCreateDeviceObject()
from DriverEntry() more then once ?
thank you,
dave
P.S. I don't have time to accomplish it by
creating bus driver.
.
- Prev by Date: Re: Recognizing two identical usb devices
- Next by Date: can't see TDI_SEND_DATAGRAM called
- Previous by thread: Re: Recognizing two identical usb devices
- Next by thread: can't see TDI_SEND_DATAGRAM called
- Index(es):
Relevant Pages
|