How can I tell if a device interface class is being properly registered?

I have the world’s simplest driver, it’s loaded at boot time and it’s an ordinary WDM driver and everything’s just peach with it, it works fine. I’m creating an FDO and a symbolic link into the DOS namespace, and I can open my device with an application.

HOWEVER - now I want to have this device broadcast (register) a device interface. I’ve been trying to do this two different ways, and neither of them seem to work.

First way: in the driver’s AddDevice() routine, I make the following calls in order:

status = IoRegisterDeviceInterface(…, &name); // name is a PUNICODE_STRING
status = IoSetDeviceInterfaceState(&name, TRUE);

When I look at the behavior of this sequence of calls using a test application (which is written in C, and uses CreateFile() to open the device), when I use the SetupDiEnumClassDevs() request, I get the following results:

if DIGCF_PRESENT is set, and I use the ClassGuid for my device, I see it.
if DIGCF_ALLCLASSES | DIGCF_DEVICE_INTERFACE is set, I see my Interface GUID in the list.

if DIGCF_ALLCLASSES | DIGCF_DEVICE_INTERFACE | DIGCF_PRESENT is set, I see nothing, the enum immediately returns with an 0x103 (end of list).

So, this suggests to me, that the SetupDiXxx functionality may not be doing what I think they are (based on the documentation, which we all know is miserably incomplete).

Here is what I think should happen: if I call SetupDiEnumClassDevs with the interfaceGuid and only DIGCF_PRESENT | DIGCF_DEVICE_INTERFACE set, it should return a device information set with precisely one element (which should be my interface).

And instead, I get an empty information set.

Any ideas?

The real question is, how can I tell whether my device interface (class) is being properly broadcast into the registry? I also tried this a different way, using AddInterface directives in a .INF file, and that way had some horrible results, but the bottom line is the interface GUID appears nowhere in the registry even when the driver installs properly and even after the same interface is thereafter registered inside the driver.

??? (confused)

xxxxx@advancedbionics.com wrote:

I have the world’s simplest driver, it’s loaded at boot time and it’s an ordinary WDM driver and everything’s just peach with it, it works fine. I’m creating an FDO and a symbolic link into the DOS namespace, and I can open my device with an application.

HOWEVER - now I want to have this device broadcast (register) a device interface. I’ve been trying to do this two different ways, and neither of them seem to work.

First way: in the driver’s AddDevice() routine, I make the following calls in order:

status = IoRegisterDeviceInterface(…, &name); // name is a PUNICODE_STRING
status = IoSetDeviceInterfaceState(&name, TRUE);

IoSetDeviceInterfaceState should be done in your IRP_MN_START_DEVICE
handler, not during AddDevice. Your device isn’t really ready to
service requests until that point. In fact, the PnP manager takes
special action to defer notification of device interface changes until
the end of StartDevice.

You should then disable it in IRP_MN_REMOVE_DEVICE.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks Tim, I’ll look into that.

My question though, is this: WHY am I not seeing the device interface?

It’s being properly registered and enabled by the driver (at least, both routines cited are getting good status codes, and the symbolic name being returned from IoCreateDeviceInterface is correct), and I’m invoking the test app AFTER the device is created.

Therefore, the interface should exist, and it should be enabled, and my app should be able to see it.

Why is it not being seen? WHERE can I look, to find out if all the necessary elements are in place for the system to correctly report this interface to my application? In the registry? WHERE in the registry?

I want to find out what specifically is going wrong with this code, because this should be the world’s simplest device interface implementation, and according to the documentation it should work as is.

Conceptually, I’m guessing three things: a) there’s a device, b) there’s an interface, and c) there’s some kind of “connection” between the device and the interface. It’s this part (c) which appears to be broken, because I can see the interface GUID in the registry (although I’m not sure whether it’s in the right place), it’s just not being made available to my application.

xxxxx@advancedbionics.com wrote:

My question though, is this: WHY am I not seeing the device interface?

I want to find out what specifically is going wrong with this code, because this should be the world’s simplest device interface implementation, and according to the documentation it should work as is.

Not exactly. The documentation says that IoSetDeviceInterfaceState
should be called in the IRP_MN_START_DEVICE handler, and that there is
special handling for interface enabling in the START_DEVICE completion
handler. You’re calling it at AddDevice time, which happens before
START_DEVICE.

Conceptually, I’m guessing three things: a) there’s a device, b) there’s an interface, and c) there’s some kind of “connection” between the device and the interface.

Yes – a many-to-many connection.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> Not exactly. The documentation says that IoSetDeviceInterfaceState

should be called in the IRP_MN_START_DEVICE handler, and that there is
special handling for interface enabling in the START_DEVICE completion
handler. You’re calling it at AddDevice time, which happens before
START_DEVICE.

This is a tangential issue. The documentation states and provides examples of this call being made from the AddDevice routine too. It doesn’t really matter where it’s made from (after device creation), as long as no one tries to access the underlying device till it’s ready.

All right, well, here’s what I’ve discovered so far:

a) the naming issue of ??\ in the kernel vs \?\ at the application level
b) when you create the interface from an INF file it behaves very differently than when you create it from inside the driver
c) framework-managed devices do some “additional” stuff with interfaces (created via INF files) that isn’t documented in the INF AddInterface page.
d) the application-level SetupDi() calls and their internal implementations ARE LESS THAN HELPFUL in terms of the error information they return (grumble grumble)…

So, here’s a very specific question to give you an idea of where I’m at with this: how can a framework-managed device turn its interface on and off (enable and disable)? If the interface is created from an INF file, what state is it in before, during, and after the framework-managed USB device is plugged in?

xxxxx@advancedbionics.com wrote:

So, here’s a very specific question to give you an idea of where I’m at with this: how can a framework-managed device turn its interface on and off (enable and disable)? If the interface is created from an INF file, what state is it in before, during, and after the framework-managed USB device is plugged in?

When you call WdfDeviceCreateDeviceInterface from the DeviceAdd
callback, the framework automatically enables and disables the interface
for you when the device enters and exits its “working state”, where
“working state” means when you enter D0 and exit D0. A KMDF driver can
also call WdfDeviceSetDeviceInterfaceState if it wants more control.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Kmdf does not disable the device interface on d0 exit. It disabled it on surprise remove or graceful remove.

d

dent from a phpne with no keynoard

-----Original Message-----
From: Tim Roberts
Sent: December 01, 2010 5:25 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] How can I tell if a device interface class is being properly registered?

xxxxx@advancedbionics.com wrote:
>
> So, here’s a very specific question to give you an idea of where I’m at with this: how can a framework-managed device turn its interface on and off (enable and disable)? If the interface is created from an INF file, what state is it in before, during, and after the framework-managed USB device is plugged in?

When you call WdfDeviceCreateDeviceInterface from the DeviceAdd
callback, the framework automatically enables and disables the interface
for you when the device enters and exits its “working state”, where
“working state” means when you enter D0 and exit D0. A KMDF driver can
also call WdfDeviceSetDeviceInterfaceState if it wants more control.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

(amplifying Doron’s post)

[quote]
Kmdf does not disable the device interface on d0 exit. It disabled it on
surprise remove or graceful remove.

[quote]

And if you think about it, that’s exactly the way you’d want it to work. Consider a device with a device interface that idles in D3 when there are no active requests to process. You certainly wouldn’t want an application to get repeated enabled/disabled notifications every time the device entered/left D0. That would be a real mess…

Peter
OSR