PDO to device instance ID?

I’ve got a SCSI filter driver, with devices attached to each LUN PDO as
well as the SCSI port FDO. Given a PDO, is there a way to get/query/
generate the device instance ID string (DEVINSTID) used to identify the
device to user-mode configuration manager APIs?

I’ve watched IRP_MN_QUERY_ID, ID types BusQueryDeviceID and
BusQueryInstanceID. These provide most of, but not all, of the info
that is catenated to make the ID string (since SCSIPORT sets UniqueID
false in response to IRP_MN_QUERY_CAPABILITIES.)

For example, BusQueryDeviceID and BusQueryInstanceID will return:

SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B

and

000

respectively. But the corresponding device instance ID string is:

SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5CE303&1&000.

The additional “3&5CE303&1&” is related to the parent devnode, the SCSI
adapter in this case, but I don’t know what information is encoded so I
don’t see how to get this string or its components from either the LUN
or port device objects.

Ideally, I’d like a solution that is not specific to PCI, SCSI, or disks.

Alternatively, given a candidate device instance ID string, can I use it
in user-mode to open a handle to the device so I can use DeviceIoControl()
to query it? It looks like I might, if I convert backslashes to #, and
append an interface GUID. This gives me a symbolic link name that points
at the LUN PDO. But this approach is device-type specific (because of
the GUID).

BTW, does anyone have any information about ZwPlugPlayControl(), above
what is found in the Nebbett book?


Dave Cox
Hewlett-Packard Co.
HPSO/SSMO (Santa Barbara)
https://ecardfile.com/id/Dave+Cox

Call IoGetDeviceProperty() “on” your PDO.

  • Matt

From: “COX,DAVID (HP-Roseville,ex1)” <david_cox2>
Sent: Monday, May 01, 2000 2:15 PM

> I’ve got a SCSI filter driver, with devices attached to each LUN PDO as
> well as the SCSI port FDO. Given a PDO, is there a way to get/query/
> generate the device instance ID string (DEVINSTID) used to identify the
> device to user-mode configuration manager APIs?
>
> I’ve watched IRP_MN_QUERY_ID, ID types BusQueryDeviceID and
> BusQueryInstanceID. These provide most of, but not all, of the info
> that is catenated to make the ID string (since SCSIPORT sets UniqueID
> false in response to IRP_MN_QUERY_CAPABILITIES.)
>
> For example, BusQueryDeviceID and BusQueryInstanceID will return:
>
> SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B

[snip]</david_cox2>

Which DeviceProperty do you propose I query? I’ve tried

DevicePropertyCompatibleIDs,
DevicePropertyHardwareID(s),
DevicePropertyFriendlyName and
DevicePropertyPhysicalDeviceObjectName.

None of these return the entire device instance (node) ID string, or
the particular piece that I am missing (“3&5CE303&1&” in my previous
example).

DevicePropertyHardwareID returns strings like

SCSI\DiskSEAGATE_ST118273_CLAR18_351B

whereas the corresponding device instance ID is

SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5CE303&1&000.


Dave Cox
Hewlett-Packard Co.
HPSO/SSMO (Santa Barbara)
https://ecardfile.com/id/Dave+Cox

-----Original Message-----
From: Matt A. [mailto:xxxxx@motu.com]
Sent: Monday, May 01, 2000 11:42 AM
To: NT Developers Interest List
Subject: [ntdev] Re: PDO to device instance ID?

Call IoGetDeviceProperty() “on” your PDO.

  • Matt

From: “COX,DAVID (HP-Roseville,ex1)” <david_cox2>
Sent: Monday, May 01, 2000 2:15 PM

> I’ve got a SCSI filter driver, with devices attached to each LUN PDO as
> well as the SCSI port FDO. Given a PDO, is there a way to get/query/
> generate the device instance ID string (DEVINSTID) used to identify the
> device to user-mode configuration manager APIs?
>
> I’ve watched IRP_MN_QUERY_ID, ID types BusQueryDeviceID and
> BusQueryInstanceID. These provide most of, but not all, of the info
> that is catenated to make the ID string (since SCSIPORT sets UniqueID
> false in response to IRP_MN_QUERY_CAPABILITIES.)
>
> For example, BusQueryDeviceID and BusQueryInstanceID will return:
>
> SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B

[snip]


You are currently subscribed to ntdev as: david_cox2@hp.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)</david_cox2>

I’m sorry, you are right. IoGetDeviceProperty() can only get you a
“hardware ID” (non-instance specific). You’re after an instance-specific
“device ID”.

AFAIK, the device ID can be obtained by sending a IRP_MN_QUERY_ID to the
PDO – which is presumably the same way the Plug and Play Manager does it.
Why this method isn’t retrieving the “whole” ID for you, I don’t know.

How are you determining what your “corresponding device instance ID” (that
you’ve shown below) should be? That is, how do you know this is the
expected ID? – where is it showing up?

  • Matt

----- Original Message -----
From: “COX,DAVID (HP-Roseville,ex1)” <david_cox2>
Sent: Monday, May 01, 2000 5:05 PM

> Which DeviceProperty do you propose I query? I’ve tried
>
> DevicePropertyCompatibleIDs,
> DevicePropertyHardwareID(s),
> DevicePropertyFriendlyName and
> DevicePropertyPhysicalDeviceObjectName.
>
> None of these return the entire device instance (node) ID string, or
> the particular piece that I am missing (“3&5CE303&1&” in my previous
> example).
>
> DevicePropertyHardwareID returns strings like
>
> SCSI\DiskSEAGATE_ST118273_CLAR18_351B
>
> whereas the corresponding device instance ID is
>
> SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5CE303&1&000.

[snip]</david_cox2>

How about using IoOpenDeviceRegistryKey() and then ZwQueryKey() to find the
name of the key? Given your example below, I think that will give you

HKLM\System\CCS\Enum\SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5
CE303&1&000

or at least

3&5CE303&1&000

/simgr

-----Original Message-----
From: Matt A. [mailto:xxxxx@motu.com]
Sent: Monday, May 01, 2000 9:02 PM
To: NT Developers Interest List
Subject: [ntdev] Re: PDO to device instance ID?

I’m sorry, you are right. IoGetDeviceProperty() can only get you a
“hardware ID” (non-instance specific). You’re after an instance-specific
“device ID”.

AFAIK, the device ID can be obtained by sending a IRP_MN_QUERY_ID to the
PDO – which is presumably the same way the Plug and Play Manager does it.
Why this method isn’t retrieving the “whole” ID for you, I don’t know.

How are you determining what your “corresponding device instance ID” (that
you’ve shown below) should be? That is, how do you know this is the
expected ID? – where is it showing up?

  • Matt

----- Original Message -----
From: “COX,DAVID (HP-Roseville,ex1)” <david_cox2>
Sent: Monday, May 01, 2000 5:05 PM

> Which DeviceProperty do you propose I query? I’ve tried
>
> DevicePropertyCompatibleIDs,
> DevicePropertyHardwareID(s),
> DevicePropertyFriendlyName and
> DevicePropertyPhysicalDeviceObjectName.
>
> None of these return the entire device instance (node) ID string, or
> the particular piece that I am missing (“3&5CE303&1&” in my previous
> example).
>
> DevicePropertyHardwareID returns strings like
>
> SCSI\DiskSEAGATE_ST118273_CLAR18_351B
>
> whereas the corresponding device instance ID is
>
> SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5CE303&1&000.

[snip]


You are currently subscribed to ntdev as: xxxxx@stratus.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)</david_cox2>

Thanks for trying.

IRP_MN_QUERY_ID can get the device ID
(SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B) and the instance
ID (000). The DDK documents that these two together, and possibly some
other information, make up the unique device instance ID. The reason
for the “other information” is that the instance ID retrieved via
IRP_MN_QUERY_ID is not guaranteed to be unique across all busses on the
system. Windows does not necessarily expect a bus driver to be able to
generate an instance ID that is different from IDs generated for devices
on other buses, which the particular bus driver may or may not control
or be aware of. The bus driver reports whether it can do this or not
via the UniqueID flag in the DEVICE_CAPABILITIES struct returned for
IRP_MN_QUERY_CAPABILITIES.

For these reasons, I do not believe PnP Mgr uses the documented IRPs
alone to query the strings used in configuration manager APIs, though
it must use them to assemble the full instance ID initially.

I have determined that the PDO’s DEVOBJ_EXTENSION contains, in the
opaque part, a pointer to a devnode structure (completely undocumented
as far as I can tell) which contains a UNICODE_STRING, which is the
fully-qualified instance-specific ID. I imagine that the user-mode
portion of PnP Mgr has access to this. Sure would be nice if I did.

I am determining what the device instance ID string *should* be by
walking the devnode tree in user-mode and querying & displaying all
their ID strings. While there are many devnodes, there is only one
SCSI disk of the type I’ve mentioned in the system, so it is easy
enough to find.

I’ll attach the code for anyone who is interested. I don’t guarantee
it will compile as-is; I’ve stripped out stuff that is specific to our
product, including main().


Dave Cox
Hewlett-Packard Co.
HPSO/SSMO (Santa Barbara)
https://ecardfile.com/id/Dave+Cox

-----Original Message-----
From: Matt A. [mailto:xxxxx@motu.com]
Sent: Monday, May 01, 2000 6:02 PM
To: NT Developers Interest List
Subject: [ntdev] Re: PDO to device instance ID?

I’m sorry, you are right. IoGetDeviceProperty() can only get you a
“hardware ID” (non-instance specific). You’re after an instance-specific
“device ID”.

AFAIK, the device ID can be obtained by sending a IRP_MN_QUERY_ID to the
PDO – which is presumably the same way the Plug and Play Manager does it.
Why this method isn’t retrieving the “whole” ID for you, I don’t know.

How are you determining what your “corresponding device instance ID” (that
you’ve shown below) should be? That is, how do you know this is the
expected ID? – where is it showing up?

  • Matt

----- Original Message -----
From: “COX,DAVID (HP-Roseville,ex1)” <david_cox2>
Sent: Monday, May 01, 2000 5:05 PM

> Which DeviceProperty do you propose I query? I’ve tried
>
> DevicePropertyCompatibleIDs,
> DevicePropertyHardwareID(s),
> DevicePropertyFriendlyName and
> DevicePropertyPhysicalDeviceObjectName.
>
> None of these return the entire device instance (node) ID string, or
> the particular piece that I am missing (“3&5CE303&1&” in my previous
> example).
>
> DevicePropertyHardwareID returns strings like
>
> SCSI\DiskSEAGATE_ST118273_CLAR18_351B
>
> whereas the corresponding device instance ID is
>
> SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5CE303&1&000.

[snip]


You are currently subscribed to ntdev as: david_cox2@hp.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)</david_cox2>

Thanks, this looks like a good way to do it without venturing into
undocumented, non-portable territory. I will give it a shot.


Dave Cox
Hewlett-Packard Co.
HPSO/SSMO (Santa Barbara)
https://ecardfile.com/id/Dave+Cox

-----Original Message-----
From: Graham, Simon [mailto:xxxxx@stratus.com]
Sent: Tuesday, May 02, 2000 5:33 AM
To: NT Developers Interest List
Subject: [ntdev] Re: PDO to device instance ID?

How about using IoOpenDeviceRegistryKey() and then ZwQueryKey() to find the
name of the key? Given your example below, I think that will give you

HKLM\System\CCS\Enum\SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5
CE303&1&000

or at least

3&5CE303&1&000

/simgr

Alas, the approach suggested below does not work. The key opened
is “Device Parameters”, a child of the key whose name I want.
ZwQueryKey(KeyBasicInformation) retrieves the key leaf name, not
the entire path. I’ve resorted to using ObQueryNameString(), with
returns the entire path, and then parsing back from the end to find
the path element above “Device Parameters”.


Dave Cox
Hewlett-Packard Co.
HPSO/SSMO (Santa Barbara)
https://ecardfile.com/id/Dave+Cox

-----Original Message-----
From: Graham, Simon [mailto:xxxxx@stratus.com]
Sent: Tuesday, May 02, 2000 5:33 AM
To: NT Developers Interest List
Subject: [ntdev] Re: PDO to device instance ID?

How about using IoOpenDeviceRegistryKey() and then ZwQueryKey() to find the
name of the key? Given your example below, I think that will give you

HKLM\System\CCS\Enum\SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5
CE303&1&000

or at least

3&5CE303&1&000

/simgr

-----Original Message-----
From: Matt A. [mailto:xxxxx@motu.com]
Sent: Monday, May 01, 2000 9:02 PM
To: NT Developers Interest List
Subject: [ntdev] Re: PDO to device instance ID?

I’m sorry, you are right. IoGetDeviceProperty() can only get you a
“hardware ID” (non-instance specific). You’re after an instance-specific
“device ID”.

AFAIK, the device ID can be obtained by sending a IRP_MN_QUERY_ID to the
PDO – which is presumably the same way the Plug and Play Manager does it.
Why this method isn’t retrieving the “whole” ID for you, I don’t know.

How are you determining what your “corresponding device instance ID” (that
you’ve shown below) should be? That is, how do you know this is the
expected ID? – where is it showing up?

  • Matt

----- Original Message -----
From: “COX,DAVID (HP-Roseville,ex1)” <david_cox2>
Sent: Monday, May 01, 2000 5:05 PM

> Which DeviceProperty do you propose I query? I’ve tried
>
> DevicePropertyCompatibleIDs,
> DevicePropertyHardwareID(s),
> DevicePropertyFriendlyName and
> DevicePropertyPhysicalDeviceObjectName.
>
> None of these return the entire device instance (node) ID string, or
> the particular piece that I am missing (“3&5CE303&1&” in my previous
> example).
>
> DevicePropertyHardwareID returns strings like
>
> SCSI\DiskSEAGATE_ST118273_CLAR18_351B
>
> whereas the corresponding device instance ID is
>
> SCSI\DISK&VEN_SEAGATE&PROD_ST118273_CLAR18&REV_351B\3&5CE303&1&000.

[snip]


You are currently subscribed to ntdev as: xxxxx@stratus.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)


You are currently subscribed to ntdev as: david_cox2@hp.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)</david_cox2>