Easiest way to find the type of storage port driver?

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?

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?

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

What larger problem are you trying to solve?

Peter

@“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 :#

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

1 Like

@“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.

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;

}`

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;
}

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

1 Like

@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?

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.

1 Like

@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?

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 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.

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