Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Easiest way to find the type of storage port driver?

Richard_MRichard_M Member Posts: 30

Hello everyone,

What is the easiest way to find the type of storage port driver in a system? meaning finding out whether the system is using storport or scsiport or ataport?

Comments

  • Richard_MRichard_M Member Posts: 30
    edited November 2020

    The only method seems to be using IOCTL_STORAGE_QUERY_PROPERTY, but i couldn't find any sample code that shows how to use it with the STORAGE_BUS_TYPE to find the storage port driver reliably across different OS versions, and the problem is it seems to be not very stable and portable across different windows versions, and also there seem to be no value for storport in the STORAGE_BUS_TYPE enum?

    i guess i can also enumerate kernel modules to see which one is loaded, but multiple of them can be loaded at the same time too, any reliable way to see if certain port driver is the one used by the storage miniport?

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,245

    Well, “the system” could conceivably be using all three simultaneously.

    What larger problem are you trying to solve?

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Richard_MRichard_M Member Posts: 30

    @Peter_Viscarola_(OSR) said:
    Well, “the system” could conceivably be using all three simultaneously.

    What larger problem are you trying to solve?

    Peter

    Correct, but i am looking to find the port driver of a specific storage miniport (specific to a device stack for example device\harddisk0\dr0)
    so lets say i know that the miniport of device\harddisk0\dr0 device stack is X, how to know which port driver X is linked to? i guess one way is to check address of certain major functions and see which module are they pointing to, but there has to be a easier way, maybe using IOCTL_STORAGE_QUERY_PROPERTY?

    I'm not trying to solve any larger problem, just got a curios mind and want to learn more about windows internals :#

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,245

    just got a curios mind and want to learn more about windows internals

    We ask you (in the Community Guidelines, which I know you've read because the text at the top of every page on this site asks you to) to please let us know when this is the case.

    Allow me to quote the Guidelines... the bolding is in the original:

    Students, Hobbyists, Dilettantes, and Dabblers

    While we are first and foremost a community of working, professional, system software developers we absolutely welcome (and encourage, even!) questions from students, hobbyists, and those who wish to dabble in the field of Windows drivers. If you're a student, or if you're asking a question out of general curiosity or academic interest, we ask you to please say so in your post. Also, please don't ask us to do your homework for you. We mean that in both the literal sense (you shouldn't bring assignments from your professors here for us to solve for you) and also the more figurative sense (please do some independent research on your problem before asking us here).

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Richard_MRichard_M Member Posts: 30

    @Peter_Viscarola_(OSR) said:

    just got a curios mind and want to learn more about windows internals

    We ask you (in the Community Guidelines, which I know you've read because the text at the top of every page on this site asks you to) to please let us know when this is the case.

    Allow me to quote the Guidelines... the bolding is in the original:

    Students, Hobbyists, Dilettantes, and Dabblers


    While we are first and foremost a community of working, professional, system software developers we absolutely welcome (and encourage, even!) questions from students, hobbyists, and those who wish to dabble in the field of Windows drivers. If you're a student, or if you're asking a question out of general curiosity or academic interest, we ask you to please say so in your post. Also, please don't ask us to do your homework for you. We mean that in both the literal sense (you shouldn't bring assignments from your professors here for us to solve for you) and also the more figurative sense (please do some independent research on your problem before asking us here).

    Peter

    I apologize, forgot to mention it in my post.

  • ThatsBerkanThatsBerkan Member Posts: 38
    edited November 2020

    You could enumerate every disk devices by their class GUID (IoGetDeviceInterfaces), open every object in the list (ObReferenceObjectByName), and loop thru the device stack of that device (IoGetAttachedDeviceReference, IoGetLowerDeviceObject) until you see one with the BUS_ENUMERATED_DEVICE device flag (meaning this is the PDO), and from there, you can get the driver name of that device (stornvme, storahci, etc...).

    Looping the device stack to retrieve the PDO looks like this :

    `///


    /// Retrieve the PDO of the given device object.
    ///

    ///

    The device we want the physical object of.
    DEVICE_OBJECT* DeviceUtils::GetPhysicalDeviceObject(DEVICE_OBJECT* DeviceObject)
    {
    //
    // Verify the passed parameters.
    //
    if (DeviceObject == NULL)
    {
        return NULL;
    }
    
    // 
    // Setup the enumeration context.
    // 
    
    struct ENUMERATION_CONTEXT
    {
        DEVICE_OBJECT* ReturnedDevice;
    };
    
    ENUMERATION_CONTEXT EnumerationContext = { };
    EnumerationContext.ReturnedDevice = NULL;
    
    // 
    // Enumerate each device in the stack.
    // 
    
    DeviceUtils::EnumerateDeviceStack(DeviceObject, [] (ULONG Idx, DEVICE_OBJECT* Device, VOID* Context) -> bool
    {
        auto EnumerationContext = (ENUMERATION_CONTEXT*) Context;
    
        // 
        // Check if the enumerated device is owned by a BUS driver.
        // 
    
        if (Device->Flags & DO_BUS_ENUMERATED_DEVICE)
        {
            EnumerationContext->ReturnedDevice = Device;
        }
    
        return false;
    
    }, &EnumerationContext);
    
    return EnumerationContext.ReturnedDevice;
    

    }`

  • ThatsBerkanThatsBerkan Member Posts: 38

    You could enumerate the device stack of the disk device you are targetting, until you retrieve a device with the BUS_ENUMERATED_DEVICE flag (meaning this is the Physical Device Object aka PDO), and gets its driver object from there.

    Example for enumerating the device stack to retrieve the PDO:

    /// <summary>
    /// Retrieve the PDO of the given device object.
    /// </summary>
    /// <param name="DeviceObject">The device we want the physical object of.</param>
    DEVICE_OBJECT* DeviceUtils::GetPhysicalDeviceObject(DEVICE_OBJECT* DeviceObject)
    {
        // 
        // Verify the passed parameters.
        // 
    
        if (DeviceObject == NULL)
        {
            return NULL;
        }
    
        // 
        // Setup the enumeration context.
        // 
    
        struct ENUMERATION_CONTEXT
        {
            DEVICE_OBJECT* ReturnedDevice;
        };
    
        ENUMERATION_CONTEXT EnumerationContext = { };
        EnumerationContext.ReturnedDevice = NULL;
    
        // 
        // Enumerate each device in the stack.
        // 
    
        DeviceUtils::EnumerateDeviceStack(DeviceObject, [] (ULONG Idx, DEVICE_OBJECT* Device, VOID* Context) -> bool
        {
            auto EnumerationContext = (ENUMERATION_CONTEXT*) Context;
    
            // 
            // Check if the enumerated device is owned by a BUS driver.
            // 
    
            if (Device->Flags & DO_BUS_ENUMERATED_DEVICE)
            {
                EnumerationContext->ReturnedDevice = Device;
            }
    
            return false;
    
        }, &EnumerationContext);
    
        return EnumerationContext.ReturnedDevice;
    }
    
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,775

    That doesn't help find the port for a given miniport. A port/miniport pair share a single FDO.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Richard_MRichard_M Member Posts: 30

    @ThatsBerkan said:
    You could enumerate the device stack of the disk device you are targetting, until you retrieve a device with the BUS_ENUMERATED_DEVICE flag (meaning this is the Physical Device Object aka PDO), and gets its driver object from there.

    Example for enumerating the device stack to retrieve the PDO:

    /// <summary>
    /// Retrieve the PDO of the given device object.
    /// </summary>
    /// <param name="DeviceObject">The device we want the physical object of.</param>
    DEVICE_OBJECT* DeviceUtils::GetPhysicalDeviceObject(DEVICE_OBJECT* DeviceObject)
    {
      // 
      // Verify the passed parameters.
      // 
    
      if (DeviceObject == NULL)
      {
          return NULL;
      }
    
      // 
      // Setup the enumeration context.
      // 
    
      struct ENUMERATION_CONTEXT
      {
          DEVICE_OBJECT* ReturnedDevice;
      };
    
      ENUMERATION_CONTEXT EnumerationContext = { };
      EnumerationContext.ReturnedDevice = NULL;
    
      // 
      // Enumerate each device in the stack.
      // 
    
      DeviceUtils::EnumerateDeviceStack(DeviceObject, [] (ULONG Idx, DEVICE_OBJECT* Device, VOID* Context) -> bool
      {
          auto EnumerationContext = (ENUMERATION_CONTEXT*) Context;
    
          // 
          // Check if the enumerated device is owned by a BUS driver.
          // 
    
          if (Device->Flags & DO_BUS_ENUMERATED_DEVICE)
          {
              EnumerationContext->ReturnedDevice = Device;
          }
    
          return false;
    
      }, &EnumerationContext);
    
      return EnumerationContext.ReturnedDevice;
    }
    

    Sorry for late respond.

    Thanks for the code, but as Mr Roberts said, this won't help for finding the port of a given miniport.

    @Tim_Roberts said:
    That doesn't help find the port for a given miniport. A port/miniport pair share a single FDO.

    So any idea how can i find the port driver of a given miniport?

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,775

    So any idea how can i find the port driver of a given miniport?

    I think you are still unclear on the concept. What are you expecting here? You cannot reach the port separate from the miniport. The two do not exist as separate entities. There is no such thing as a "port device object" -- that's just not how it works. If you want to send IRPs to the port, you sent them to the port/miniport pair. If you want to send IRPs to the miniport, you send them to the port/miniport pair. That's all there is.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Richard_MRichard_M Member Posts: 30
    edited December 2020

    @Tim_Roberts said:

    So any idea how can i find the port driver of a given miniport?

    I think you are still unclear on the concept. What are you expecting here? You cannot reach the port separate from the miniport. The two do not exist as separate entities. There is no such thing as a "port device object" -- that's just not how it works. If you want to send IRPs to the port, you sent them to the port/miniport pair. If you want to send IRPs to the miniport, you send them to the port/miniport pair. That's all there is.

    I do understand that the two are not separated. i want to find a generic way of finding what is the port driver that a specific miniport is linked against. so no matter what the miniport is, i want to find to find what port driver it is linked to (ataport or scsiport or storport).

    lets say you have found the miniport driver object of a specific storage device stack by going to the bottom of the stack, how do you programmatically find what port driver this miniport driver is linked to?

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,775

    how do you programmatically find what port driver this miniport driver is linked to?

    Let's say you were a human being, sitting at a debugger. Would YOU be able to figure it out? I don't think you could. If you can't do it as a human, then you certainly can't write a program to do it.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Richard_MRichard_M Member Posts: 30
    edited December 2020

    @Tim_Roberts said:

    how do you programmatically find what port driver this miniport driver is linked to?

    Let's say you were a human being, sitting at a debugger. Would YOU be able to figure it out? I don't think you could. If you can't do it as a human, then you certainly can't write a program to do it.

    Yes i can, but its a nasty solution and i was wondering if there is any better solution like using IOCTL_STORAGE_QUERY_PROPERTY in some way or something similar

    the nasty solution is, finding all the modules in kernel, then checking which of them is the IRP_MJ_INTERNAL_DEVICE_CONTROL of miniport is pointing to, and done. i assume this is how windbg finds it too, considering when i check the drvobj of the miniport i can tell which port it is linked against using windbg ( for example it is linked against storport or..)

    but I'm pretty sure there has to be a more clean and robust way of doing it.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,245
    edited December 2020

    Just as a reminder, the OP isn’t trying to solve an actual problem with this. From up thread:

    got a curios mind and want to learn more about windows internals

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Writing WDF Drivers 7 Dec 2020 LIVE ONLINE
Internals & Software Drivers 25 Jan 2021 LIVE ONLINE
Developing Minifilters 8 March 2021 LIVE ONLINE