1

I have a \\.\SCSI#: handle created via CreateFile(). I know it points to a specific HBA or (in my case) NVMe Controller. It must have a Bus/Device/Function associated with it's enumeration.

So far I've tried to figure this out via wmi, though I'm more than open to a C solution via WinApi. (actually would prefer a solution in C).

By getting an object using:

gwmi -namespace root\cimv2 -class Win32_SCSIController  | format-list *

It yields my NVMe device like so:

PSComputerName              : DESK
Status                      : OK
Name                        : Standard NVM Express Controller
StatusInfo                  : 3
__GENUS                     : 2
__CLASS                     : Win32_SCSIController
__SUPERCLASS                : CIM_SCSIController
__DYNASTY                   : CIM_ManagedSystemElement
__RELPATH                   : Win32_SCSIController.DeviceID="PCI\\VEN_1987&DEV_5008&SUBSYS_50081987&REV_01\\4&CB74546&0&00E8"
__PROPERTY_COUNT            : 31
__DERIVATION                : {CIM_SCSIController, CIM_Controller, CIM_LogicalDevice, CIM_LogicalElement...}
__SERVER                    : DESK
__NAMESPACE                 : root\cimv2
__PATH                      : \\DESK\root\cimv2:Win32_SCSIController.DeviceID="PCI\\VEN_1987&DEV_5008&SUBSYS_50081987&REV_01\\4&CB74546&0&00E8"
Availability                : 3
Caption                     : Standard NVM Express Controller
ConfigManagerErrorCode      : 0
ConfigManagerUserConfig     : False
ControllerTimeouts          :
CreationClassName           : Win32_SCSIController
Description                 : Standard NVM Express Controller
DeviceID                    : PCI\VEN_1987&DEV_5008&SUBSYS_50081987&REV_01\4&CB74546&0&00E8
DeviceMap                   :
DriverName                  : stornvme
ErrorCleared                :
ErrorDescription            :
HardwareVersion             :
Index                       :
InstallDate                 :
LastErrorCode               :
Manufacturer                : Standard NVM Express Controller
MaxDataWidth                :
MaxNumberControlled         :
MaxTransferRate             :
PNPDeviceID                 : PCI\VEN_1987&DEV_5008&SUBSYS_50081987&REV_01\4&CB74546&0&00E8
PowerManagementCapabilities :
PowerManagementSupported    :
ProtectionManagement        :
ProtocolSupported           : 2
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : DESK
TimeOfLastReset             :
Scope                       : System.Management.ManagementScope
Path                        : \\DESK\root\cimv2:Win32_SCSIController.DeviceID="PCI\\VEN_1987&DEV_5008&SUBSYS_50081987&REV_01\\4&CB74546&0&00E8"
Options                     : System.Management.ObjectGetOptions
ClassPath                   : \\DESK\root\cimv2:Win32_SCSIController
Properties                  : {Availability, Caption, ConfigManagerErrorCode, ConfigManagerUserConfig...}
SystemProperties            : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...}
Qualifiers                  : {dynamic, Locale, provider, UUID}
Site                        :                     :

Notice how the Index is blank... I figured that this would have been the number in \.\SCSI#:

Playing a little more, I can get the Bus/Device/Function from this:

$a = gwmi -namespace root\cimv2 -class Win32_PnPEntity -filter "DeviceId='PCI\\VEN_1987&DEV_5008&SUBSYS_50081987&REV_01\\4&CB74546&0&00E8'"

$a.GetDeviceProperties('DEVPKEY_Device_LocationInfo').deviceProperties.Data
PCI bus 5, device 0, function 0

I also thought about calling IOCTL_SCSI_GET_ADDRESS on the \\.\SCSI#: handle, though that doesn't work (which sort of makes sense since it isn't a lun-handle, but rather a controller one)

How do I associate a PCIe Bus/Device/Function info with the \\.\SCSI#: handle?

csm10495
  • 569
  • 6
  • 12
  • I estimate that "handle" means the handle that is returned by CreateFile, isnt it? I don't know if there is a chance to get this information through the handle. But you may get such information through the SetupDi* functions by quering for devices in the GUID_DEVCLASS_SCSIADAPTER class. See MSDN about SetupDiGetClassDevs(), SetupDiEnumDeviceInfo() and SetupDiGetDeviceRegistryProperty() for more details. The properties you might need is SPDRP_BUSNUMBER, SPDRP_ADDRESS and SPDRP_UI_NUMBER. – Willy K. Sep 27 '18 at 14:34
  • Yes, handles are via ```CreateFile()```. Interesting enough, using GUID Explorer, I can see that SPDRP_UI_NUMBER does not exist on the device. SPDRP_BUSNUMBER is 5 (for I guess PCIe Bus). SPDRP_ADDRESS is 0. That would match with the \\.\SCSI# in this case, however on my system I have a device as \\.\SCSI1: and it's SPDRP_ADDRESS is 0x170000 so it doesn't seem to line up always. Thanks for trying though. – csm10495 Sep 28 '18 at 04:57
  • Yes, that's right - SRDRP_UI_NUMBER may not be available - it may represent the slot number. The others are to be interpreted as follows:
    SPDRP_BUSNUMBER = PCI bus number
    SRDRP_ADDRESS[15...8] = PCI device number
    SRDRP_ADDRESS[7...0] = PCI function number
    – Willy K. Oct 01 '18 at 07:38

0 Answers0