How to re-enable a disabled device?

I'm tweaking on a KMDF lower class filter driver attached to an USB device. When i sent my IOCTL to the lower class filter, I change its WDF_DEVICE_STATE.Disabled to WdfTrue, and this cause the USB device to stop functioning. The device stack for the USB is also torn down (the EvtCleanupContextCallback is triggered right after the state is set). My questions are:

  • Is this the proper way to disable an USB device?
  • How can I re-enable the USB without physically replug it? I'm thinking of trying to to get the port of the USB before change the filter's state, then trigger a port cycle/reset when i need to re-enable the device. Is it OK?

Thanks in advanve for the advice and explaination

Normally devices of all sorts are enabled / disabled via user mode programs. The standard device manager, or another control program. Users and administrators expect it to work this way

It is hard to think of a situation where you would want a filter driver to do this unless there is some error that can't be recovered

Hi there,

Thanks for the reply. I understand that normally programs will work with CM_Enable_Devnode() and CM_Disable_Devnode() to do this operation. However I'm thinking of a case when PCs were not in a directory to apply policies and they can only install a standalone program to monitor which device can be plugged in the machine.

I think that using the user mode program only, some geeks can try to manipulate it and bypass the function. I want to explore if there is anything I can do if I'm in kernel :smiley:

Would like to hear your advice on tackling this in KM. Just think it is like I would like to understand deeper how CM_Enable_Devnode/CM_Disable_Devnode works and want to implement similar functions in KM :smiley:

there is no equivalent functionality in the kernel. if the allow device app is a service, only admins can alter its state. If the user is an admin, they can also install drivers or remove your filter. There is no reason to consider moving this logic in KM

Hi Doron,

So just for my curiosity, how CM_Enable_Devnode/CM_Disable_Devnode works in the background? How could it enable/disable a device?

Thanks for the knowledge

I'm not sure what answer you are expecting. Those are user-mode APIs. In fact, they are the lowest-level user-mode APIs for enabling and disabling devices. The SetupDi APIs end up calling the CM_xxx APIs, which have been present in WIndows NT forever, and even in the Win 95 VMM.

Hi Tim,

I understand those are UM APIs. What I'm curious on is how they work, i.e what components do they interact to, and how do they interact with these components to enable/disable a device.

Like, when ReadFile() is called, an IRP_MJ_READ is sent to the device in charge of file reading and there is a driver handling that (for example). What I'm seeking for is similar to that (although maybe this will happens entirely on UM - that's OK, I just want to understand how it works :smiley: )

For a PnP device, this ends up sending a series of IRP_MJ_PNP ioctls down the driver stack, and in response the drivers handle the details of closing the device objects. It then calls the UnloadDriver callback, and removes the driver from memory. There are probably internal tables to update, but it's really not all that complicated.

1 Like

Hi Tim,

Thanks for the quick explaination. I've also have a small trackdown and also see the device being unloaded. I'm wondering how the system can re-enable the device after the driver of it has been unload. Does it use mechanisms to reload the driver back for exactly the device that has been unloaded?

Well, there's nothing "reload" about it. The USB hub hardware reports to the operating system that your device stopped responding. The operating system treats it as an unplug. After that, it's like your device (and your driver) never existed.

When the USB hub hardware notices that you chirp back in, it signals the host controller that a new device has arrived, and that starts the whole enumeration and plug-in process all over again, just as if you had plugged in a completely different device. The system goes to search for the matching driver, and loads it (and its filters) just like it did the first time.

1 Like