Passing multiple buffers from user app to driver

I am developing a toolset that will exercise storage devices attached to
Windows XP and later systems, perhaps Windows 2000 also. Unlike most, mine
will (I think) manage to deliver arbitrary CDBs to a device at an arbitrary
queue depth. As most of you know, you can use Read/WriteFile to manage an
arbitrary queue depth of READ and WRITE. You can also send arbitrary CDBs
through SPTI, but SCSIPORT serializes them per device, or maybe LUN, so you
won’t see a queue of arbitrary CDBs on the device.

In order to get around these limitations, I am working with the following
architecture. Filter driver intercepts SCSI INQUIRY and changes the
PERIPHERAL DEVICE TYPE to something for which Windows doesn’t provide a
class driver. Custom class driver supports this new type, and app accesses
devices through custom class driver, by supplying a struct, in the user
buffer to Read/WriteFile, which includes the CDB, a pointer to user buffer,
and a pointer to sense buffer. I also have IOCTL available between app and
class driver.

I’m currently using an SRB as the user buffer passed into Read/Write, and
the class driver is responsible for looking at the pointers in the SRB for
the real data and sense data buffers, and locking them into memory. Gary
Little, this should look very familiar.

Before I go all the way down this road, I’m asking myself if I am painting
myself into a corner, or at least making life harder on myself than I need
to. Gary, and a few others, had some issues with this approach, which
appeared, based on my reading of the archive, to be due to the complexity of
the options available. (direct or buffered? Do you associate the secondary
MDLs with the Irp or not? Do you need to map the buffer?) I think I
understand what I need to do if I pursue this approach, but Mark Roddy
suggested if I have a top level driver, I should be able to avoid having
embedded data object pointers. In the archive articles I saw, Mark didn’t
elaborate in a way that I could wrap my limited brain around.

Since my devices aren’t disks to the system, I don’t have to worry about an
FS above me, and so I *think* my class driver qualifies as a top level
driver? If that’s so, how can I pass a buffer describing the CDB, plus a
pointer to user data buffer and another one for the sense buffer?

Backing up even a step further, do I gain anything by supporting Read/Write,
or should I just limit myself to IOCTLs, since the direction of dataflow is
determined by the contents of the CDB, and in some cases, isn’t even
defined? Is there a performance issue that I don’t know about, or would I
be able to get just as much concurrency if I were to limit the interface to
IOCTLs?

Thanks,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.
E-mail address is pointed at a domain squatter. Use reply-to instead.

A few suggestions:

  1. having a filter which changes the INQURIY data won’t help (at least
    for 2k and above). The hardware IDs are generated by the port driver
    based on INQUIRY data and there’s no viable option to get in between
    port and miniport. Instead why don’t you just change the service
    assigned to the device to load your private class driver?

  2. Personally I’d just do everything with IOCTLs rather than trying to
    map an IOCTL mechanism on top of READ/WRITE. Heck, you could even use
    the existing pass-through structures and just send the SRBs you generate
    down with tags.

  3. make your IOCTLs buffered. In order to be secure you’d have to copy
    much of the IOCTL buffer to private storage anyway to keep the app from
    changing the values from under you. Since the top-level structure you
    use is small the overhead of buffering would probably be comparable to
    that of DIRECT IO. Note that you wouldn’t be copying the data buffer,
    just the control structure.

  4. Your class driver would need to generate SRBs just the same way any
    other class driver would. Create an MDL for the data buffer (if any),
    set all the flags appropriately, copy back the sense-info buffer if a
    check-sense occurs (the port driver writes directly to the sense-info
    buffer so it can’t be in user space), etc…

-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Monday, January 13, 2003 3:47 PM
To: NT Developers Interest List

I am developing a toolset that will exercise storage devices attached to
Windows XP and later systems, perhaps Windows 2000 also. Unlike most,
mine will (I think) manage to deliver arbitrary CDBs to a device at an
arbitrary queue depth. As most of you know, you can use Read/WriteFile
to manage an arbitrary queue depth of READ and WRITE. You can also send
arbitrary CDBs through SPTI, but SCSIPORT serializes them per device, or
maybe LUN, so you won’t see a queue of arbitrary CDBs on the device.

In order to get around these limitations, I am working with the
following architecture. Filter driver intercepts SCSI INQUIRY and
changes the PERIPHERAL DEVICE TYPE to something for which Windows
doesn’t provide a class driver. Custom class driver supports this new
type, and app accesses devices through custom class driver, by supplying
a struct, in the user buffer to Read/WriteFile, which includes the CDB,
a pointer to user buffer, and a pointer to sense buffer. I also have
IOCTL available between app and class driver.

I’m currently using an SRB as the user buffer passed into Read/Write,
and the class driver is responsible for looking at the pointers in the
SRB for the real data and sense data buffers, and locking them into
memory. Gary Little, this should look very familiar.

Before I go all the way down this road, I’m asking myself if I am
painting myself into a corner, or at least making life harder on myself
than I need to. Gary, and a few others, had some issues with this
approach, which appeared, based on my reading of the archive, to be due
to the complexity of the options available. (direct or buffered? Do
you associate the secondary MDLs with the Irp or not? Do you need to
map the buffer?) I think I understand what I need to do if I pursue
this approach, but Mark Roddy suggested if I have a top level driver, I
should be able to avoid having embedded data object pointers. In the
archive articles I saw, Mark didn’t elaborate in a way that I could wrap
my limited brain around.

Since my devices aren’t disks to the system, I don’t have to worry about
an FS above me, and so I *think* my class driver qualifies as a top
level driver? If that’s so, how can I pass a buffer describing the CDB,
plus a pointer to user data buffer and another one for the sense buffer?

Backing up even a step further, do I gain anything by supporting
Read/Write, or should I just limit myself to IOCTLs, since the direction
of dataflow is determined by the contents of the CDB, and in some cases,
isn’t even defined? Is there a performance issue that I don’t know
about, or would I be able to get just as much concurrency if I were to
limit the interface to IOCTLs?

Thanks,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.
E-mail address is pointed at a domain squatter. Use reply-to instead.


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Peter,

Thanks for the reply.

Hmm, even though this is plain text, Outlook Express won’t indent and prefix
the lines in your message. I wonder why not? Since it won’t, I’ll respond
to the item numbers, instead of inline.

  1. Bummer, I think. Maybe cool beans, depending on the answer to this
    followup: So how does one selectively “change the service assigned to the
    device”? I don’t want to load my private class driver on every disk device,
    just some of them. I didn’t know that is possible, and don’t have a clue
    how to go about it. I guess I’m a bit confused by what is actually used to
    determine which class driver is loaded on the device. I thought it was a
    raw INQUIRY sent by the PnP Manager, not the HWID. Is that incorrect? This
    PnP stuff is great, as long as you aren’t trying to color outside the lines
    in any way. Otherwise, understanding the limitations and exceptions is
    headache inducing.

  2. I’m reading this as confirmation of my suspicion that I won’t gain any
    benefits by implementing Read/Write, and using IOCTLs exclusively is just as
    good, as far as performance goes, and is less complex.

  3. Do you mean in the app (METHOD_BUFFERED), or the DO_BUFFERED_IO flag?
    Or both? However you answer that, I’m reading your suggestion as: Copy the
    packet (which is an SRB) into the SRB in the IRP…

  4. lock down the user buffer, set the appropriate members of the IRP and
    embedded SRB, and send it down. Which is what I already thought I need to
    do. For sense, I don’t need to probe and lock it for the Port driver, it
    will allocate it’s own sense buffer, I just need to copy from that sense
    buffer to the app’s sense buffer in the event of a check sense. Is that
    correct? I saw in the disk class driver that the Port *could* allocate a
    sense buffer, it just wasn’t obvious (to me) that it *will*, even if enough
    space is provided. Or (probably), I understand this whole stack a lot less
    than I thought I did.

Thanks,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

“Peter Wieland” wrote in message
news:xxxxx@ntdev…

A few suggestions:

1) having a filter which changes the INQURIY data won’t help (at least
for 2k and above). The hardware IDs are generated by the port driver
based on INQUIRY data and there’s no viable option to get in between
port and miniport. Instead why don’t you just change the service
assigned to the device to load your private class driver?

2) Personally I’d just do everything with IOCTLs rather than trying to
map an IOCTL mechanism on top of READ/WRITE. Heck, you could even use
the existing pass-through structures and just send the SRBs you generate
down with tags.

3) make your IOCTLs buffered. In order to be secure you’d have to copy
much of the IOCTL buffer to private storage anyway to keep the app from
changing the values from under you. Since the top-level structure you
use is small the overhead of buffering would probably be comparable to
that of DIRECT IO. Note that you wouldn’t be copying the data buffer,
just the control structure.

4) Your class driver would need to generate SRBs just the same way any
other class driver would. Create an MDL for the data buffer (if any),
set all the flags appropriately, copy back the sense-info buffer if a
check-sense occurs (the port driver writes directly to the sense-info
buffer so it can’t be in user space), etc…

-p

> -----Original Message-----

From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Tuesday, January 14, 2003 12:42 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Passing multiple buffers from user app to driver

Peter,

Thanks for the reply.

Hmm, even though this is plain text, Outlook Express won’t
indent and prefix the lines in your message. I wonder why
not? Since it won’t, I’ll respond to the item numbers,
instead of inline.

  1. Bummer, I think. Maybe cool beans, depending on the
    answer to this
    followup: So how does one selectively “change the service
    assigned to the device”? I don’t want to load my private
    class driver on every disk device, just some of them. I
    didn’t know that is possible, and don’t have a clue how to go
    about it. I guess I’m a bit confused by what is actually
    used to determine which class driver is loaded on the device.
    I thought it was a raw INQUIRY sent by the PnP Manager, not
    the HWID. Is that incorrect? This PnP stuff is great, as
    long as you aren’t trying to color outside the lines in any
    way. Otherwise, understanding the limitations and exceptions
    is headache inducing.

The inquiry data is supplied to Pnp in an IRP that can be filtered by a PDO
(bus) filter driver so that you can change the INQUIRY device type (from
e.g. Disk to Whatever,) and have a Whatever class driver of your own design
to handle all scsi disks. You don’t have to get in between Scsiport and the
miniport.

  1. PNP assigns a service to a device based on its search through the INF
    files for matching hardware or compatible IDs. The service is a
    property of the device-node. The device nodes can be enumerated and
    their properties modified from user-mode through the SetupDI API which
    is documented in the DDK. I’d suggest wading through that
    documentation.

  2. pretty-much equivalent.

  3. METHOD_BUFFERED. The DO__IO flags only apply to
    READ/WRITE requests.

    4) You would need to allocate a sense buffer from non-paged pool and
    supply it to the port driver in the SenseInfoBuffer field of the SRB.
    When the request returns you would copy the data (if any) into the
    user’s buffer (make sure you wrap any access to or from user addresses
    in a try/except and that you validate the address) and free the buffer
    you allocated.

    -p

    -----Original Message-----
    From: Phil Barila [mailto:xxxxx@Seagate.com]
    Sent: Tuesday, January 14, 2003 9:42 AM
    To: NT Developers Interest List

    Peter,

    Thanks for the reply.

    Hmm, even though this is plain text, Outlook Express won’t indent and
    prefix the lines in your message. I wonder why not? Since it won’t,
    I’ll respond to the item numbers, instead of inline.

    1) Bummer, I think. Maybe cool beans, depending on the answer to this
    followup: So how does one selectively “change the service assigned to
    the device”? I don’t want to load my private class driver on every disk
    device, just some of them. I didn’t know that is possible, and don’t
    have a clue how to go about it. I guess I’m a bit confused by what is
    actually used to determine which class driver is loaded on the device.
    I thought it was a raw INQUIRY sent by the PnP Manager, not the HWID.
    Is that incorrect? This PnP stuff is great, as long as you aren’t
    trying to color outside the lines in any way. Otherwise, understanding
    the limitations and exceptions is headache inducing.

    2) I’m reading this as confirmation of my suspicion that I won’t gain
    any benefits by implementing Read/Write, and using IOCTLs exclusively is
    just as good, as far as performance goes, and is less complex.

    3) Do you mean in the app (METHOD_BUFFERED), or the DO_BUFFERED_IO
    flag?
    Or both? However you answer that, I’m reading your suggestion as: Copy
    the packet (which is an SRB) into the SRB in the IRP…

    4) lock down the user buffer, set the appropriate members of the IRP
    and embedded SRB, and send it down. Which is what I already thought I
    need to do. For sense, I don’t need to probe and lock it for the Port
    driver, it will allocate it’s own sense buffer, I just need to copy from
    that sense buffer to the app’s sense buffer in the event of a check
    sense. Is that correct? I saw in the disk class driver that the Port
    could allocate a sense buffer, it just wasn’t obvious (to me) that it
    will, even if enough space is provided. Or (probably), I understand
    this whole stack a lot less than I thought I did.

    Thanks,

    Phil

    Philip D. Barila
    Seagate Technology, LLC
    (720) 684-1842
    As if I need to say it: Not speaking for Seagate.

    “Peter Wieland” wrote in message
    news:xxxxx@ntdev…

    A few suggestions:

    1) having a filter which changes the INQURIY data won’t help (at least
    for 2k and above). The hardware IDs are generated by the port driver
    based on INQUIRY data and there’s no viable option to get in between
    port and miniport. Instead why don’t you just change the service
    assigned to the device to load your private class driver?

    2) Personally I’d just do everything with IOCTLs rather than trying to
    map an IOCTL mechanism on top of READ/WRITE. Heck, you could even use
    the existing pass-through structures and just send the SRBs you generate
    down with tags.

    3) make your IOCTLs buffered. In order to be secure you’d have to copy
    much of the IOCTL buffer to private storage anyway to keep the app from
    changing the values from under you. Since the top-level structure you
    use is small the overhead of buffering would probably be comparable to
    that of DIRECT IO. Note that you wouldn’t be copying the data buffer,
    just the control structure.

    4) Your class driver would need to generate SRBs just the same way any
    other class driver would. Create an MDL for the data buffer (if any),
    set all the flags appropriately, copy back the sense-info buffer if a
    check-sense occurs (the port driver writes directly to the sense-info
    buffer so it can’t be in user space), etc…

    -p


    You are currently subscribed to ntdev as: xxxxx@microsoft.com To
    unsubscribe send a blank email to xxxxx@lists.osr.com

“Roddy, Mark” wrote in message news:xxxxx@ntdev…
>
>
>
> > -----Original Message-----
> > From: Phil Barila [mailto:xxxxx@Seagate.com]
> > Sent: Tuesday, January 14, 2003 12:42 PM
> > To: NT Developers Interest List
> > Subject: [ntdev] Re: Passing multiple buffers from user app to driver
> >
> >
> > Peter,
> >
> > Thanks for the reply.
> >
> > Hmm, even though this is plain text, Outlook Express won’t
> > indent and prefix the lines in your message. I wonder why
> > not? Since it won’t, I’ll respond to the item numbers,
> > instead of inline.
> >
> > 1) Bummer, I think. Maybe cool beans, depending on the
> > answer to this
> > followup: So how does one selectively “change the service
> > assigned to the device”? I don’t want to load my private
> > class driver on every disk device, just some of them. I
> > didn’t know that is possible, and don’t have a clue how to go
> > about it. I guess I’m a bit confused by what is actually
> > used to determine which class driver is loaded on the device.
> > I thought it was a raw INQUIRY sent by the PnP Manager, not
> > the HWID. Is that incorrect? This PnP stuff is great, as
> > long as you aren’t trying to color outside the lines in any
> > way. Otherwise, understanding the limitations and exceptions
> > is headache inducing.
>
> The inquiry data is supplied to Pnp in an IRP that can be filtered by a
PDO
> (bus) filter driver so that you can change the INQUIRY device type (from
> e.g. Disk to Whatever,) and have a Whatever class driver of your own
design
> to handle all scsi disks. You don’t have to get in between Scsiport and
the
> miniport.

OK, so two people with a history of giving right answers (appear to) have a
fundamental disagreement on where you have to intercept the information the
device provides the OS in order to convince the OS that something else is
really there.

As you know, Mark, I’m using your ScsiView as my filter, and it works great
out of the box. I haven’t yet twiddled the bits in the INQUIRY data, just
to see what happens, as I was trying to nail down some other points. It
looks like I’m going to have to do an experiment here…

OK, I’ve done it. I really don’t want this to be true, but it looks like
Peter is right. The first thing the PDO sees is a CLAIM_DEVICE IRP,
followed by 1 READ CAPACITY, two sector 0 reads, and another READ CAPACITY.
Disk devices don’t get an INQUIRY through the PDO at all, that I’ve been
able to see. I’d really like to be wrong about this, because the SetupDi
morass that Peter euphemistically suggested that I wade in seems even worse
than this stuff.

So, unless someone has some counter evidence, it appears that going swimming
with the SetupDi swamp denizens is the only thing for this particular
problem, aside from wedging the SCSIPORT/miniport interface, which won’t
work at all for other storage port drivers.

Anything I missed? I think it’s safe to assume I missed a few obvious
things, but if they were obvious to me, I wouldn’t have missed them.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.
E-mail address is pointed at a domain squatter. Use reply-to instead.

Mark was right - you could build a filter driver which attached to the
port driver, filtered the bus relations list, attached device objects to
the child devices and filtered the calls to the PDO from PNP in order to
change the device IDs. However that’s a lot of work.

SetupDi’s a bit complex, but much simpler than figuring out which sets
of IOCTLS and SRBs you’d need to filter in order to make the filtering
scheme (even the simple one you were hoping for) work. And when you’ve
got a bug in your application you can just restart it … No machine
reboots necessary.

SetupDiSetDeviceRegistryProperty looks like it will allow you to set the
service for the device. For that to work you’d first have to install
your device driver. Take a look at the addfilter sample in the ddk for
something that locates devices with a particular interface (disks in
this case) and sets its properties.

-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Tuesday, January 14, 2003 1:21 PM
To: NT Developers Interest List

“Roddy, Mark” wrote in message
news:xxxxx@ntdev…
>
>
>
> > -----Original Message-----
> > From: Phil Barila [mailto:xxxxx@Seagate.com]
> > Sent: Tuesday, January 14, 2003 12:42 PM
> > To: NT Developers Interest List
> > Subject: [ntdev] Re: Passing multiple buffers from user app to
> > driver
> >
> >
> > Peter,
> >
> > Thanks for the reply.
> >
> > Hmm, even though this is plain text, Outlook Express won’t indent
> > and prefix the lines in your message. I wonder why not? Since it
> > won’t, I’ll respond to the item numbers, instead of inline.
> >
> > 1) Bummer, I think. Maybe cool beans, depending on the answer to
> > this
> > followup: So how does one selectively “change the service assigned
> > to the device”? I don’t want to load my private class driver on
> > every disk device, just some of them. I didn’t know that is
> > possible, and don’t have a clue how to go about it. I guess I’m a
> > bit confused by what is actually used to determine which class
> > driver is loaded on the device.
> > I thought it was a raw INQUIRY sent by the PnP Manager, not the
> > HWID. Is that incorrect? This PnP stuff is great, as long as you
> > aren’t trying to color outside the lines in any way. Otherwise,
> > understanding the limitations and exceptions is headache inducing.
>
> The inquiry data is supplied to Pnp in an IRP that can be filtered by
> a
PDO
> (bus) filter driver so that you can change the INQUIRY device type
> (from e.g. Disk to Whatever,) and have a Whatever class driver of your

> own
design
> to handle all scsi disks. You don’t have to get in between Scsiport
> and
the
> miniport.

OK, so two people with a history of giving right answers (appear to)
have a fundamental disagreement on where you have to intercept the
information the device provides the OS in order to convince the OS that
something else is really there.

As you know, Mark, I’m using your ScsiView as my filter, and it works
great out of the box. I haven’t yet twiddled the bits in the INQUIRY
data, just to see what happens, as I was trying to nail down some other
points. It looks like I’m going to have to do an experiment here…

OK, I’ve done it. I really don’t want this to be true, but it looks
like Peter is right. The first thing the PDO sees is a CLAIM_DEVICE
IRP, followed by 1 READ CAPACITY, two sector 0 reads, and another READ
CAPACITY.
Disk devices don’t get an INQUIRY through the PDO at all, that I’ve been
able to see. I’d really like to be wrong about this, because the
SetupDi morass that Peter euphemistically suggested that I wade in seems
even worse than this stuff.

So, unless someone has some counter evidence, it appears that going
swimming with the SetupDi swamp denizens is the only thing for this
particular problem, aside from wedging the SCSIPORT/miniport interface,
which won’t work at all for other storage port drivers.

Anything I missed? I think it’s safe to assume I missed a few obvious
things, but if they were obvious to me, I wouldn’t have missed them.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.
E-mail address is pointed at a domain squatter. Use reply-to instead.


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Well now Phil is totally confused 'cause he’s just decided that you were
right and I was wrong :slight_smile:

Phil - at the risk of sounding like an add that makes me vomit - you need to
think outside the scsi box. The inquiry is a consequence of
IRP_MN_QUERY_DEVICE_RELATIONS type BusRelations on the bus FDO.

-----Original Message-----
From: Peter Wieland [mailto:xxxxx@windows.microsoft.com]
Sent: Tuesday, January 14, 2003 4:37 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Passing multiple buffers from user app to driver

Mark was right - you could build a filter driver which
attached to the port driver, filtered the bus relations list,
attached device objects to the child devices and filtered the
calls to the PDO from PNP in order to change the device IDs.
However that’s a lot of work.

SetupDi’s a bit complex, but much simpler than figuring out
which sets of IOCTLS and SRBs you’d need to filter in order
to make the filtering scheme (even the simple one you were
hoping for) work. And when you’ve got a bug in your
application you can just restart it … No machine reboots necessary.

SetupDiSetDeviceRegistryProperty looks like it will allow you
to set the service for the device. For that to work you’d
first have to install your device driver. Take a look at the
addfilter sample in the ddk for something that locates
devices with a particular interface (disks in this case) and
sets its properties.

-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Tuesday, January 14, 2003 1:21 PM
To: NT Developers Interest List

“Roddy, Mark” wrote in message
> news:xxxxx@ntdev…
> >
> >
> >
> > > -----Original Message-----
> > > From: Phil Barila [mailto:xxxxx@Seagate.com]
> > > Sent: Tuesday, January 14, 2003 12:42 PM
> > > To: NT Developers Interest List
> > > Subject: [ntdev] Re: Passing multiple buffers from user app to
> > > driver
> > >
> > >
> > > Peter,
> > >
> > > Thanks for the reply.
> > >
> > > Hmm, even though this is plain text, Outlook Express won’t indent
> > > and prefix the lines in your message. I wonder why not?
> Since it
> > > won’t, I’ll respond to the item numbers, instead of inline.
> > >
> > > 1) Bummer, I think. Maybe cool beans, depending on the answer to
> > > this
> > > followup: So how does one selectively “change the
> service assigned
> > > to the device”? I don’t want to load my private class driver on
> > > every disk device, just some of them. I didn’t know that is
> > > possible, and don’t have a clue how to go about it. I
> guess I’m a
> > > bit confused by what is actually used to determine which class
> > > driver is loaded on the device.
> > > I thought it was a raw INQUIRY sent by the PnP Manager, not the
> > > HWID. Is that incorrect? This PnP stuff is great, as
> long as you
> > > aren’t trying to color outside the lines in any way. Otherwise,
> > > understanding the limitations and exceptions is headache inducing.
> >
> > The inquiry data is supplied to Pnp in an IRP that can be
> filtered by
> > a
> PDO
> > (bus) filter driver so that you can change the INQUIRY device type
> > (from e.g. Disk to Whatever,) and have a Whatever class
> driver of your
>
> > own
> design
> > to handle all scsi disks. You don’t have to get in between Scsiport
> > and
> the
> > miniport.
>
> OK, so two people with a history of giving right answers
> (appear to) have a fundamental disagreement on where you have
> to intercept the information the device provides the OS in
> order to convince the OS that something else is really there.
>
> As you know, Mark, I’m using your ScsiView as my filter, and
> it works great out of the box. I haven’t yet twiddled the
> bits in the INQUIRY data, just to see what happens, as I was
> trying to nail down some other points. It looks like I’m
> going to have to do an experiment here…
>
> OK, I’ve done it. I really don’t want this to be true, but
> it looks like Peter is right. The first thing the PDO sees
> is a CLAIM_DEVICE IRP, followed by 1 READ CAPACITY, two
> sector 0 reads, and another READ CAPACITY. Disk devices don’t
> get an INQUIRY through the PDO at all, that I’ve been able to
> see. I’d really like to be wrong about this, because the
> SetupDi morass that Peter euphemistically suggested that I
> wade in seems even worse than this stuff.
>
> So, unless someone has some counter evidence, it appears that
> going swimming with the SetupDi swamp denizens is the only
> thing for this particular problem, aside from wedging the
> SCSIPORT/miniport interface, which won’t work at all for
> other storage port drivers.
>
> Anything I missed? I think it’s safe to assume I missed a
> few obvious things, but if they were obvious to me, I
> wouldn’t have missed them.
>
> Phil
> –
> Philip D. Barila
> Seagate Technology, LLC
> (720) 684-1842
> As if I need to say it: Not speaking for Seagate.
> E-mail address is pointed at a domain squatter. Use reply-to instead.
>
>
>
> —
> You are currently subscribed to ntdev as:
> xxxxx@microsoft.com To unsubscribe send a blank email to
> xxxxx@lists.osr.com
>
>
>
>
> —
> You are currently subscribed to ntdev as:
> xxxxx@stratus.com To unsubscribe send a blank email to
> xxxxx@lists.osr.com
>

OK, so I was looking at the wrong stuff inside the filter driver. So I have
the mechanism, if I have the ability. :slight_smile:

I’m not sure I agree with you on the complexity of the SetupDi API, vs the
fairly limited number of IOCTLs and SRBs that go into the PnP stuff. I
wasn’t concerned with mucking around with the SCSI INQUIRY data, because
that’s well defined, and the OS, more or less, has an expected behavior to
the changes I intended to make. I’m a bit more reluctant to start twiddling
with PnP IDs, since those are wholly defined by Microsoft, and you guys like
to change things. However, I need this for two projects, not just one, and
for the other one, I just don’t see any other way around having the filter
in there, so I’ll start looking at the device IDs in the bus relations list.

I’ll keep in mind the SetupDi routine you mentioned, as that looks like it
could solve this problem, though not the other one.

Thanks,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

“Peter Wieland” wrote in message
news:xxxxx@ntdev…

Mark was right - you could build a filter driver which attached to the
port driver, filtered the bus relations list, attached device objects to
the child devices and filtered the calls to the PDO from PNP in order to
change the device IDs. However that’s a lot of work.

SetupDi’s a bit complex, but much simpler than figuring out which sets
of IOCTLS and SRBs you’d need to filter in order to make the filtering
scheme (even the simple one you were hoping for) work. And when you’ve
got a bug in your application you can just restart it … No machine
reboots necessary.

SetupDiSetDeviceRegistryProperty looks like it will allow you to set the
service for the device. For that to work you’d first have to install
your device driver. Take a look at the addfilter sample in the ddk for
something that locates devices with a particular interface (disks in
this case) and sets its properties.

-p

“Roddy, Mark” wrote in message news:xxxxx@ntdev…
>
> Well now Phil is totally confused 'cause he’s just decided that you were
> right and I was wrong :slight_smile:

Well, no, I’m less confused than I was, because I’m now looking at the right
part of the filter for the stuff I need to change.

> Phil - at the risk of sounding like an add that makes me vomit - you need
to
> think outside the scsi box. The inquiry is a consequence of
> IRP_MN_QUERY_DEVICE_RELATIONS type BusRelations on the bus FDO.

That’s exactly where I’m looking. If I’m finally getting a clue (which is
arguable), the data I want to change is in the DEVICE_EXTENSION on the PDOs
in the pdo list in Irp->IoStatus.Information. Or maybe it’s more clear to
say that I see data that matches what I think I need to change hanging off
of that pointer, but I’m not sure if changing it here will accomplish what I
want. It’s not a system critical disk, so here goes…

:slight_smile:

Thanks,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

“Phil Barila” wrote in message
news:xxxxx@ntdev…
>
> “Roddy, Mark” wrote in message
news:xxxxx@ntdev…
> >
> > Well now Phil is totally confused 'cause he’s just decided that you were
> > right and I was wrong :slight_smile:
>
> Well, no, I’m less confused than I was, because I’m now looking at the
right
> part of the filter for the stuff I need to change.
>
> > Phil - at the risk of sounding like an add that makes me vomit - you
need
> to
> > think outside the scsi box. The inquiry is a consequence of
> > IRP_MN_QUERY_DEVICE_RELATIONS type BusRelations on the bus FDO.
>
> That’s exactly where I’m looking. If I’m finally getting a clue (which is
> arguable), the data I want to change is in the DEVICE_EXTENSION on the
PDOs
> in the pdo list in Irp->IoStatus.Information. Or maybe it’s more clear to
> say that I see data that matches what I think I need to change hanging off
> of that pointer, but I’m not sure if changing it here will accomplish what
I
> want. It’s not a system critical disk, so here goes…
>
> :slight_smile:

Recognizing that it’s not usually good form to crow, I changed the suspect
data in the device extension to the value defined in SPC - 3 as “Unknown”.
Lo and behold, up pops a “Found New Hardware Wizard”, looking for driver for
a SEAGATE ST19171W SCSI Other Device.

Thanks to Peter and Mark, who together gave me the right combination of
ideas so I could use Mark’s excellent filter to do what I need it to.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

The private data area of the port driver is exactly that - private.
There is no guarantee that it won’t change the next time the driver is
updated. The byte you’re editing today could be part of a kernel-mode
pointer tomorrow. You should not be modifying the private data areas of
any drivers.

If you want to do this through a filter then you need to attach a device
object to the PDO in order to modify the PDO’s responses to
IRP_MJ_PNP\IRP_MN_QUERY_ID requests. This is how you change the HWID
such that PNP will load a driver of your choosing rather than the one
the INF specifies.

Thanks,
-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Tuesday, January 14, 2003 3:17 PM
To: NT Developers Interest List

“Phil Barila” wrote in message
news:xxxxx@ntdev…
>
> “Roddy, Mark” wrote in message
news:xxxxx@ntdev…
> >
> > Well now Phil is totally confused 'cause he’s just decided that you
> > were right and I was wrong :slight_smile:
>
> Well, no, I’m less confused than I was, because I’m now looking at the
right
> part of the filter for the stuff I need to change.
>
> > Phil - at the risk of sounding like an add that makes me vomit - you
need
> to
> > think outside the scsi box. The inquiry is a consequence of
> > IRP_MN_QUERY_DEVICE_RELATIONS type BusRelations on the bus FDO.
>
> That’s exactly where I’m looking. If I’m finally getting a clue
> (which is arguable), the data I want to change is in the
> DEVICE_EXTENSION on the
PDOs
> in the pdo list in Irp->IoStatus.Information. Or maybe it’s more
> clear to say that I see data that matches what I think I need to
> change hanging off of that pointer, but I’m not sure if changing it
> here will accomplish what
I
> want. It’s not a system critical disk, so here goes…
>
> :slight_smile:

Recognizing that it’s not usually good form to crow, I changed the
suspect data in the device extension to the value defined in SPC - 3 as
“Unknown”.
Lo and behold, up pops a “Found New Hardware Wizard”, looking for driver
for a SEAGATE ST19171W SCSI Other Device.

Thanks to Peter and Mark, who together gave me the right combination of
ideas so I could use Mark’s excellent filter to do what I need it to.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Also - you should try causing a bus rescan with your filter in place. I
suspect that the device will get surprise removed and redetected when
you do since you’ve corrupted the copy of the INQUIRY data that scsiport
uses to detect when someone has replaced one SCSI device with another.

-p

-----Original Message-----
From: Peter Wieland
Sent: Tuesday, January 14, 2003 3:32 PM
To: ‘NT Developers Interest List’

The private data area of the port driver is exactly that - private.
There is no guarantee that it won’t change the next time the driver is
updated. The byte you’re editing today could be part of a kernel-mode
pointer tomorrow. You should not be modifying the private data areas of
any drivers.

If you want to do this through a filter then you need to attach a device
object to the PDO in order to modify the PDO’s responses to
IRP_MJ_PNP\IRP_MN_QUERY_ID requests. This is how you change the HWID
such that PNP will load a driver of your choosing rather than the one
the INF specifies.

Thanks,
-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Tuesday, January 14, 2003 3:17 PM
To: NT Developers Interest List

“Phil Barila” wrote in message
news:xxxxx@ntdev…
>
> “Roddy, Mark” wrote in message
news:xxxxx@ntdev…
> >
> > Well now Phil is totally confused 'cause he’s just decided that you
> > were right and I was wrong :slight_smile:
>
> Well, no, I’m less confused than I was, because I’m now looking at the
right
> part of the filter for the stuff I need to change.
>
> > Phil - at the risk of sounding like an add that makes me vomit - you
need
> to
> > think outside the scsi box. The inquiry is a consequence of
> > IRP_MN_QUERY_DEVICE_RELATIONS type BusRelations on the bus FDO.
>
> That’s exactly where I’m looking. If I’m finally getting a clue
> (which is arguable), the data I want to change is in the
> DEVICE_EXTENSION on the
PDOs
> in the pdo list in Irp->IoStatus.Information. Or maybe it’s more
> clear to say that I see data that matches what I think I need to
> change hanging off of that pointer, but I’m not sure if changing it
> here will accomplish what
I
> want. It’s not a system critical disk, so here goes…
>
> :slight_smile:

Recognizing that it’s not usually good form to crow, I changed the
suspect data in the device extension to the value defined in SPC - 3 as
“Unknown”.
Lo and behold, up pops a “Found New Hardware Wizard”, looking for driver
for a SEAGATE ST19171W SCSI Other Device.

Thanks to Peter and Mark, who together gave me the right combination of
ideas so I could use Mark’s excellent filter to do what I need it to.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

You’re right, of course. It’s not even sure to work with another port
driver. I intercepted the wrong IRP, thanks for the guidance to the right
one.

It appears that modifying the WCHAR strings at Irp->UserIosb->Information
(for the various different IDs requested) is the right approach. Is it?

Thanks,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

“Peter Wieland” wrote in message
news:xxxxx@ntdev…

The private data area of the port driver is exactly that - private.
There is no guarantee that it won’t change the next time the driver is
updated. The byte you’re editing today could be part of a kernel-mode
pointer tomorrow. You should not be modifying the private data areas of
any drivers.

If you want to do this through a filter then you need to attach a device
object to the PDO in order to modify the PDO’s responses to
IRP_MJ_PNP\IRP_MN_QUERY_ID requests. This is how you change the HWID
such that PNP will load a driver of your choosing rather than the one
the INF specifies.

Thanks,
-p

yes - that’s a much better approach.

-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Tuesday, January 14, 2003 4:54 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Passing multiple buffers from user app to driver

You’re right, of course. It’s not even sure to work with another port
driver. I intercepted the wrong IRP, thanks for the guidance to the
right one.

It appears that modifying the WCHAR strings at
Irp->UserIosb->Information (for the various different IDs requested) is
the right approach. Is it?

Thanks,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

“Peter Wieland” wrote in message
news:xxxxx@ntdev…

The private data area of the port driver is exactly that - private.
There is no guarantee that it won’t change the next time the driver is
updated. The byte you’re editing today could be part of a kernel-mode
pointer tomorrow. You should not be modifying the private data areas of
any drivers.

If you want to do this through a filter then you need to attach a device
object to the PDO in order to modify the PDO’s responses to
IRP_MJ_PNP\IRP_MN_QUERY_ID requests. This is how you change the HWID
such that PNP will load a driver of your choosing rather than the one
the INF specifies.

Thanks,
-p


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Having thought about this again, as it has been almost three years since I wrote a sample
scsi bus filter that converted disks to others, I misspoke, or rather I was less than
accurate :slight_smile:

While Inquiry data is collected by scsiport through an enumeration triggered by
IRP_MN_QUERY_DEVICE_RELATIONS targeted at the FDO (the bus driver FDO,) what you want to do
is to use your PDO filter to transmogrify the IRP_MN_QUERY_ID type BusQueryDeviceID on its
way back up the stack (i.e. in a completion handler after the bus driver below you has filled
it in. At Irp->IoStatus.Information you will have the hideous multistring widechar array
PnpIds that you then have to parse your way through replacing things like SCSI\Disk with
Scsi\Other and GenDisk with ScsiOther etc. etc. And do try not to leak the original buffer at
IoStatus.Information (which is a hint that it is easier to replace the buffer rather than
edit it inplace.)

This will avoid your doing the BAD THING with the device extension of the PDO below you and
is actually a legitimate PnP operation.

===========================
Mark Roddy
Consultant, Microsoft DDK MVP
Hollis Technology Solutions
xxxxx@hollistech.com
www.hollistech.com
603-321-1032

-----Original Message-----
From: “Peter Wieland”
To: “NT Developers Interest List”
Date: Tue, 14 Jan 2003 18:18:58 -0800
Subject: [ntdev] Re: Passing multiple buffers from user app to driver

> yes - that’s a much better approach.
>
> -p
>
> -----Original Message-----
> From: Phil Barila [mailto:xxxxx@Seagate.com]
> Sent: Tuesday, January 14, 2003 4:54 PM
> To: NT Developers Interest List
> Subject: [ntdev] Re: Passing multiple buffers from user app to driver
>
>
> You’re right, of course. It’s not even sure to work with another port
> driver. I intercepted the wrong IRP, thanks for the guidance to the
> right one.
>
> It appears that modifying the WCHAR strings at
> Irp->UserIosb->Information (for the various different IDs requested) is
> the right approach. Is it?
>
> Thanks,
>
> Phil
> –
> Philip D. Barila
> Seagate Technology, LLC
> (720) 684-1842
> As if I need to say it: Not speaking for Seagate.
>
> “Peter Wieland” wrote in message
> news:xxxxx@ntdev…
>
> The private data area of the port driver is exactly that - private.
> There is no guarantee that it won’t change the next time the driver is
> updated. The byte you’re editing today could be part of a kernel-mode
> pointer tomorrow. You should not be modifying the private data areas
> of
> any drivers.
>
> If you want to do this through a filter then you need to attach a
> device
> object to the PDO in order to modify the PDO’s responses to
> IRP_MJ_PNP\IRP_MN_QUERY_ID requests. This is how you change the HWID
> such that PNP will load a driver of your choosing rather than the one
> the INF specifies.
>
> Thanks,
> -p
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@microsoft.com To
> unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@hollistech.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

“Mark Roddy” wrote in message news:xxxxx@ntdev…
>
>
> Having thought about this again, as it has been almost three years since I
> wrote a sample scsi bus filter that converted disks to others, I misspoke,
> or rather I was less than accurate :slight_smile:

Just a bit… :slight_smile:

> While Inquiry data is collected by scsiport through an enumeration
> triggered by IRP_MN_QUERY_DEVICE_RELATIONS targeted at
> the FDO (the bus driver FDO,) what you want to do is to use your PDO
> filter to transmogrify the IRP_MN_QUERY_ID type BusQueryDeviceID
> on its way back up the stack (i.e. in a completion handler after the bus
> driver below you has filled it in. At Irp->IoStatus.Information you will

To be completely precise, it’s at Irp->UserIosb->Information, at least in XP
with all SPs and hotfixes applied. IoStatus.Information appears to really
be an attempt to provide information, though I’m not sure what.

> have the hideous multistring widechar array PnpIds that you then have to
> parse your way through replacing things like SCSI\Disk withScsi\Other and
> GenDisk with ScsiOther etc. etc. And do try not to leak the original
> buffer at IoStatus.Information (which is a hint that it is easier to
> replace the buffer rather than edit it inplace.)

In my case, I’m mostly replacing “Disk” with “Diag”, so I don’t really need
to replace the buffer, but it’s just safer to do that, especially if I
decide to change more than that later. It appears to be paged pool, though
I’m not sure about that. I’ll just use NP pool until I know I figure that
one out.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

Use Irp->IoStatus.Information. Irp->UserIosb->Information could be a
pointer to a user-mode address space, may not be paged in, may not be
valid, etc…

-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Wednesday, January 15, 2003 11:18 AM
To: NT Developers Interest List

“Mark Roddy” wrote in message news:xxxxx@ntdev…
>
>
> Having thought about this again, as it has been almost three years
> since I wrote a sample scsi bus filter that converted disks to others,

> I misspoke, or rather I was less than accurate :slight_smile:

Just a bit… :slight_smile:

> While Inquiry data is collected by scsiport through an enumeration
> triggered by IRP_MN_QUERY_DEVICE_RELATIONS targeted at the FDO (the
> bus driver FDO,) what you want to do is to use your PDO filter to
> transmogrify the IRP_MN_QUERY_ID type BusQueryDeviceID on its way back

> up the stack (i.e. in a completion handler after the bus driver below
> you has filled it in. At Irp->IoStatus.Information you will

To be completely precise, it’s at Irp->UserIosb->Information, at least
in XP with all SPs and hotfixes applied. IoStatus.Information appears
to really be an attempt to provide information, though I’m not sure
what.

> have the hideous multistring widechar array PnpIds that you then have
> to parse your way through replacing things like SCSI\Disk
> withScsi\Other and GenDisk with ScsiOther etc. etc. And do try not to
> leak the original buffer at IoStatus.Information (which is a hint that

> it is easier to replace the buffer rather than edit it inplace.)

In my case, I’m mostly replacing “Disk” with “Diag”, so I don’t really
need to replace the buffer, but it’s just safer to do that, especially
if I decide to change more than that later. It appears to be paged
pool, though I’m not sure about that. I’ll just use NP pool until I
know I figure that one out.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Of course, you and Mark are both right. I didn’t have the completion
routine setup yet, so I was looking in the debugger at the Irp when it
returned from sending it down. There is apparently some other completion
routine copying the Irp->UserIosb->Information to Irp->IoStatus.Information
at some point before my completion routine is called.

Thanks for the help,

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

“Peter Wieland” wrote in message
news:xxxxx@ntdev…

Use Irp->IoStatus.Information. Irp->UserIosb->Information could be a
pointer to a user-mode address space, may not be paged in, may not be
valid, etc…

-p

-----Original Message-----
From: Phil Barila [mailto:xxxxx@Seagate.com]
Sent: Wednesday, January 15, 2003 11:18 AM
To: NT Developers Interest List

“Mark Roddy” wrote in message news:xxxxx@ntdev…
>
>
> Having thought about this again, as it has been almost three years
> since I wrote a sample scsi bus filter that converted disks to others,

> I misspoke, or rather I was less than accurate :slight_smile:

Just a bit… :slight_smile:

> While Inquiry data is collected by scsiport through an enumeration
> triggered by IRP_MN_QUERY_DEVICE_RELATIONS targeted at the FDO (the
> bus driver FDO,) what you want to do is to use your PDO filter to
> transmogrify the IRP_MN_QUERY_ID type BusQueryDeviceID on its way back

> up the stack (i.e. in a completion handler after the bus driver below
> you has filled it in. At Irp->IoStatus.Information you will

To be completely precise, it’s at Irp->UserIosb->Information, at least
in XP with all SPs and hotfixes applied. IoStatus.Information appears
to really be an attempt to provide information, though I’m not sure
what.

> have the hideous multistring widechar array PnpIds that you then have
> to parse your way through replacing things like SCSI\Disk
> withScsi\Other and GenDisk with ScsiOther etc. etc. And do try not to
> leak the original buffer at IoStatus.Information (which is a hint that

> it is easier to replace the buffer rather than edit it inplace.)

In my case, I’m mostly replacing “Disk” with “Diag”, so I don’t really
need to replace the buffer, but it’s just safer to do that, especially
if I decide to change more than that later. It appears to be paged
pool, though I’m not sure about that. I’ll just use NP pool until I
know I figure that one out.

Phil

Philip D. Barila
Seagate Technology, LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com