How to access the 'AttachedDevice' member of _DEVICE_OBJECT

Hello,

I’ve run the code analysis on the usbip-win project.
I get the following warnings:

driver\stub\stub_dev.c(128): warning C28175: The 'AttachedDevice' member of _DEVICE_OBJECT should not be accessed by a driver:  Access to this member may be permitted for certain classes of drivers. See the documentation for this warning for more information.
driver\stub\stub_dev.c(138): warning C28175: The 'AttachedDevice' member of _DEVICE_OBJECT should not be accessed by a driver:  Access to this member may be permitted for certain classes of drivers. See the documentation for this warning for more information.

The source code follows as below:

static BOOLEAN
is_usbip_stub_attached(PDEVICE_OBJECT pdo)
{
	DEVICE_OBJECT	*attached;

	attached = pdo->AttachedDevice;
	while (attached) {
		PDRIVER_OBJECT	drvobj = attached->DriverObject;

		if (drvobj != NULL) {
			UNICODE_STRING	name_uni;
			RtlInitUnicodeString(&name_uni, L"\\driver\\usbip_stub");
			if (RtlEqualUnicodeString(&drvobj->DriverName, &name_uni, TRUE))
				return TRUE;
		}
		attached = attached->AttachedDevice;
	}
	return FALSE;
}

The help page of Microsoft recommends that the proper way is to use IoEnumerateDeviceObjectList function.
I’m not sure that I get the attached devices using this function.
I think that IoGetAttachedDevice or IoGetAttachedDeviceReference function is more proper than IoEnumerateDeviceObjectList function.
But, I don’t know how to use these functions to solve the above warnings in detail.

As I’m a beginner in the driver development, I hope someone to let me know a good solution or provide the sample code.

Thanks,
Andrey

You need to use IoGetAttachedDeviceReference to do this correctly. The code shown is indeed not good. It is vulnerable to changes in the device stack while enumerating the stack.

Hi, @Mark_Roddy
Thanks for your reply.

I have one question.
As you see the is_usbip_stub_attached() function, this function gets all the attached devices via loop.
How can we implement this loop using IoGetAttachedDeviceReference function?

Thanks.

Hi, @Mark_Roddy

I’ve modified the is_usbip_stub_attached() function as below:

static BOOLEAN
is_usbip_stub_attached(PDEVICE_OBJECT pdo)
{
	PDEVICE_OBJECT attached = NULL;

	attached = IoGetAttachedDeviceReference(pdo);
	while (attached && attached != pdo) {
		PDRIVER_OBJECT	drvobj = attached->DriverObject;
		pdo = attached;
		ObDereferenceObject(attached);

		if (drvobj != NULL) {
			UNICODE_STRING	name_uni;
			RtlInitUnicodeString(&name_uni, L"\\driver\\usbip_stub");
			if (RtlEqualUnicodeString(&drvobj->DriverName, &name_uni, TRUE))
				return TRUE;
		}

		attached = IoGetAttachedDeviceReference(pdo);
	}
	return FALSE;
}

Please check if my code is correct.

Thanks.

You can’t dereference the device object while you are using the contents of the object, in particular the driver object. So your code needs some more work to get the object dereferenced correctly.

As an aside, this seems like a horrible way to do anything. So what is the code trying to do by searching for the usbip_stub driver?

A better way to do this would be to have a custom ioctl that only usbip_stub responds to, basically a ping function for usbip_stub. Then you could just send the ioctl down the stack and your function returns true if usbip_stub responds with success.

“AttachedDevice” gives you the drivers above you, right? Function devices should simply not care whether a specific filter is in the stack above you. That’s the whole point of the architecture. You do what you need to do, without worrying about the filters above you.

Similar to what Mark said, you could have the upper filter send down a specific ioctl to register itself, but what would you do with that information? How does this help you?

AttachedDevice" gives you the drivers above you, right?

Or all the current occupants of the stack you might want to attach to. I believe the op is trying to probe for usbip_stub on a device stack in order to only attach to that particular stack. That’s a valid thing to do, AFAIC.