Using Devcon

A while back I wrote about using SetupAPI functions in VB.NET. The goal was to be able to work with devices and ultimately enable and disable a device.

The code was what I would eventually use, but initially I used Devcon. Devcon is essentially the Device Manager over a command line. It is freely available. You can even get the source code from the Windows Server 2003 Driver Development Kit (DDK). It may be available in the newer Windows Driver Kit (WDK) as well.

To demonstrate the usefulness of devcon, we can look at some examples from my blog and see how they coorelate to devcon commands

Retrieving Device Setup Class Names and Getting Friendly Class Names:
We can use the following command

devcon classes

This would give us output similar to:

Listing 53 setup class(es).
WCEUSBS : Windows CE USB Devices
USB : Universal Serial Bus controllers
PnpPrinters : IEEE 1394 and SCSI printers
Dot4 : IEEE 1284.4 devices
Dot4Print : IEEE 1284.4 compatible printers
Computer : Computer
DiskDrive : Disk drives
Display : Display adapters
fdc : Floppy disk controllers
hdc : IDE ATA/ATAPI controllers
Keyboard : Keyboards
MEDIA : Sound, video and game controllers
Modem : Modems
Monitor : Monitors
Mouse : Mice and other pointing devices
MTD : PCMCIA and Flash memory devices
MultiFunction : Multifunction adapters
Net : Network adapters
NetClient : Network Client
NetService : Network Service
NetTrans : Network Protocol
PCMCIA : PCMCIA adapters
Ports : Ports (COM & LPT)
Printer : Printers
SCSIAdapter : SCSI and RAID controllers
System : System devices
Unknown : Other devices
FloppyDisk : Floppy disk drives
Processor : Processors
MultiPortSerial : Multi-port serial adapters
SmartCardReader : Smart card readers
VolumeSnapshot : Storage volume shadow copies
1394Debug : 1394 Debugger Device
1394 : IEEE 1394 Bus host controllers
Infrared : Infrared devices
Image : Imaging devices
TapeDrive : Tape drives
Volume : Storage volumes
Battery : Batteries
HIDClass : Human Interface Devices
61883 : 61883 Device Class
LegacyDriver : Non-Plug and Play Drivers
SDHost : Secure Digital host controllers
UsbPcCardReader : USB PC-Card Readers
Avc : AVC Device Class
Enum1394 : IEEE 1394 IP Network Enumerator
MediumChanger : Medium Changers
NtApm : NT Apm/Legacy Support
SBP2 : SBP2 IEEE 1394 Devices
Bluetooth : Bluetooth Radios
WPD : Windows Portable Devices
USB : Motorola USB Device

You'll note that we aren't receiving the Class Guid. I'm not sure if this is that important anyway.

Actually Getting to the Devices and Getting Device Names:

There are a couple of ways we can do this. The first option is to simply specify a class. That happens with the = argument

devcon find =net

PCI\VEN_14E4&DEV_169D&SUBSYS_105E147B&REV_11\4&1B41B794&0&00E0: Broadcom NetLink (TM) Gigabit Ethernet
ROOT\CNTX_VPCNETS2_MP\0000 : Linksys Wireless-G USB Network Adapter #9 - Virtual Machine Network Services Driver
ROOT\CNTX_VPCNETS2_MP\0009 : Broadcom NetLink (TM) Gigabit Ethernet - Virtual Machine Network Services Driver
ROOT\CNTX_VPCNETS2_MP\0010 : Linksys Wireless-G USB Network Adapter #10 - Virtual Machine Network Services Driver
ROOT\MS_NDISWANBH\0000 : WAN Miniport (Network Monitor)
ROOT\MS_PSCHEDMP\0001 : Broadcom NetLink (TM) Gigabit Ethernet - Packet Scheduler Miniport
ROOT\MS_PSCHEDMP\0002 : Linksys Wireless-G USB Network Adapter - Packet Scheduler Miniport
ROOT\MS_PTIMINIPORT\0000 : Direct Parallel
31 matching device(s) found.

We can also use

devcon listclass Net

To find all devices, even those that aren't present, we type

devcon findall =Net

We can also filter based on how the device is connected. This command will show just PCI devices in the net class

devcon find =Net PCI\*

You can do this without even specifying the class as well.

devcon find PCI\*

Getting Status on a Device:

Similar to the last set of commands we can use

devcon status =Net

Name: Broadcom NetLink (TM) Gigabit Ethernet
Driver is running.
Name: Linksys Wireless-G USB Network Adapter #9 - Virtual Machine Network Se
rvices Driver
Driver is running.
Name: Broadcom NetLink (TM) Gigabit Ethernet - Virtual Machine Network Servi
ces Driver
Driver is running.
Name: WAN Miniport (L2TP)
Driver is running.
Name: WAN Miniport (Network Monitor)
Driver is running.
Name: Broadcom NetLink (TM) Gigabit Ethernet - Packet Scheduler Miniport
Driver is running.
Name: Linksys Wireless-G USB Network Adapter - Packet Scheduler Miniport
Driver is running.
Name: Linksys Wireless-G USB Network Adapter #7 - Packet Scheduler Miniport
Driver is running.
Name: Direct Parallel
Driver is running.
31 matching device(s) found.

The same arguments as last time can be used.

Enabling/Disabling a device:

You can use wildcards again, although I usually am very explicit with what I am enabling or disabling.

devcon disable @"HDAUDIO\FUNC_01&VEN_10EC&DEV_0880&SUBSYS_147B9B01&REV_1008\4&EEB356C&0&0001"
HDAUDIO\FUNC_01&VEN_10EC&DEV_0880&SUBSYS_147B9B01&REV_1008\4&EEB356C&0&0001: Disabled
1 device(s) disabled.

devcon enable @"HDAUDIO\FUNC_01&VEN_10EC&DEV_0880&SUBSYS_147B9B01&REV_1008\4&EEB356C&0&0001"
HDAUDIO\FUNC_01&VEN_10EC&DEV_0880&SUBSYS_147B9B01&REV_1008\4&EEB356C&0&0001: Enabled
1 device(s) enabled.

All this works quite well in most situations. There were a couple reasons why I eventually opted with the VB.NET way of doing things. First, efficiency. There is a lot of overhead to enabling and disabling a device with Devcon. This can slow down a program, especially when enabling and disabling a device can be quite time consuming in a computers way of imagining time. 500 milliseconds can be an eternity. 2-3 seconds can be a long time for a user to look at no progress.

The Second reason is just the nature of devcon. Since it is meant to be similar to the Device Manager itself, it acts like the Device Manager. This means devices are disabled on a per-profile basis. So, if you diable a device in one hardware profile and then boot in a different profile, it won't continue to be disabled. In my particular project, this wasn't ideal.

If these reasons aren't compelling enough for you to code this in .NET or C++, then you should look at using Devcon to accomplish your task.

No comments: