Device Console (devcon)


DevCon is a command-line tool that displays detailed information about devices and lets you search for and manipulate devices from the command line. DevCon enables, disables, installs, configures, and removes devices on the local computer and displays detailed information about devices on local and remote computers. DevCon is included in the Microsoft Windows Driver Kit (WDK).

Theory of Operation

The DevCon source code is included in the WDK in the src/setup/devcon directory. This topic explains the DevCon design and describes how to use the SetupAPI and device installation functions to enumerate devices and perform device operations in a console application.

For a complete description of DevCon features and instructions for using them, see DevCon.


These instructions pertain to Microsoft Windows XP and later versions of Windows. Although DevCon is supported on Windows 2000, these instructions do not pertain to that version of Windows.

How the Sample Works

Running devcon help provides a list of commands and short descriptions of what each command does. devcon help <command> gives more detailed help about the specified command. The interpretation of each command is done through a DispatchTable dispatch table that is at the bottom of cmds.cpp. Some of the commands make use of a generic device enumerator called EnumerateDevices. A few of these commands work when given a remote target computer and also work if using the 32-bit version of DevCon on Wow64.

The following list describes some of the more interesting functions and the APIs they use:

  • cmdClasses demonstrates the use of SetupDiBuildClassInfoListEx to enumerate all device class GUID. The SetupDiClassNameFromGuidEx and SetupDiGetClassDescriptionEx functions are used to obtain more information about each device class.

  • cmdListClass demonstrates the use of SetupDiClassGuidsFromNameEx to enumerate one or more class GUIDs that match the class name. This command also demonstrates the use of SetupDiGetClassDevsEx to list all the devices for each class GUID.

  • The cmdFind, cmdFindAll, and cmdStatus commands are a simple use of EnumerateDevices (which is explained later) to list devices and display different levels of information about each device. Note that all but cmdFindAll use DIGCF_PRESENT to list only information about devices that are currently present. The main functionality for these and related devices is done inside FindCallback.

  • The cmdEnable, cmdDisable, and cmdRestart commands show how to issue DIF_PROPERTYCHANGE to enable, disable, or restart a device. The main functionality for each of these commands is done inside ControlCallback. These operations cannot be done on a remote computer or in the context of Wow64. You should not use CFGMGR32 APIs because they skip class and co-installers.

  • cmdUpdate shows how to use UpdateDriverForPlugAndPlayDevices to update the driver for all devices to a specific driver. Typically, INSTALLFLAG_FORCE would not be specified to enable UpdateDriverForPlugAndPlayDevices to determine if there is a better match already known. It is specified in DevCon to enable DevCon to be used more effectively as a debugging/testing tool. This cannot be done on a remote computer or in the context of Wow64.

  • cmdInstall is a variation of cmdUpdate to install a driver when there is no associated hardware. It creates a new root-enumerated device instance and associates it with a made up hardware ID that is specified on the command line (which should correspond to a hardware ID in the INF). This cannot be done on a remote computer or in the context of Wow64.

  • cmdRemove is a command to remove devices. Plug and Play (PnP) devices that are removed reappear in response to cmdRescan. The main functionality of this command is in RemoveCallback that demonstrates the use of DIF_REMOVE. This cannot be done on a remote computer or in the context of Wow64. You should not use CFGMGR32 APIs because they skip class and co-installers.

  • cmdRescan shows the correct way to rescan for all Plug and Play (PnP) devices that might have previously been removed or that otherwise require a rescan to detect them.

  • cmdDPAdd enables you to add a Driver Package to the computer. The main functionality of this command demonstrates the use of SetupCopyOEMInf. Adding a Driver Package to the computer does not mean the drivers are installed on devices; it simply means the drivers are available automatically when a new device is plugged in or a existing device is updated.

  • cmdDPDelete enables you to uninstall a Driver Package from the machine. The main functionality of this command demonstrates the use of SetupUninstallOEMInf. Removing a Driver Package from the computer does not uninstall the drivers that are associated with a device. If you want to accomplish both, use cmdRemove on all the devices by using a given Driver Package and then cmdDPDelete to remove the Driver Package itself from the computer.

    Note  This functionality is not available in Windows 2000.

  • cmdDPEnum enables you to enumerate all of the third-party Driver Packages that are currently installed on the computer and also shows you how to get some common properties from a Driver Package (Provider, Class description, DriverVer date, and version).

  • cmdDPEnumLegacy shows you how to enumerate third-party Driver Packages on Windows Server 2003 and earlier operating systems.

  • Reboot shows how to correctly restart the computer from a hardware install program. In particular it passes flags to ExitWindowsEx that cause the restart to be associated with hardware installation. You should never restart the computer unnecessarily.

  • EnumerateDevices demonstrates the use of SetupDiGetClassDevsEx to enumerate all devices or all present devices, either globally or limited to a specific setup class. Demonstrates the use of SetupDiCreateDeviceInfoListEx to create a blank list that is associated with a class or not (for most cases, a blank list does not need to be associated with a class). Demonstrates the use of SetupDiOpenDeviceInfo to add a device instance into a device info list. These last two APIs are ideal to obtain a DeviceInfoData structure from a device instance and machine name when mixing CFGMGR32 APIs with SETUPAPI APIs. SetupDiGetDeviceInfoListDetail is called to obtain a remote machine handle that might be passed into CFGMGR32 APIs. SetupDiEnumDeviceInfo is called to enumerate each and every device that is in the device info list (either explicitly added or determined by the call to SetupDiGetClassDevsEx). The instance ID is obtained by calling CM_Get_Device_ID_Ex, by using information in devInfo (which is obtained from SetupDiEnumerateDeviceInfo) and devInfoListDetail (which is obtained from SetupDiGetDeviceInfoListDetail). GetHwIds is called to obtain a list of hardware and compatible IDs (explained below). After an interesting device has been determined (typically by checking hardware IDs), the callback is called to operate on that individual device.

  • GetHwIds shows how to get the complete list of hardware IDs or compatible IDs for a device by using SetupDiGetDeviceRegistryProperty.

  • GetDeviceDescription shows how to obtain descriptive information about a device. The friendly name is used if it exists; otherwise, the device description is used.

  • DumpDeviceWithInfo shows how to obtain an instance ID (or use any CFGMGR32 API) given HDEVINFO (device information list) and PSP_DEVINFO_DATA (device information data).

  • DumpDeviceStatus shows how to interpret the information that CM_Get_DevNode_Status_Ex returns. Refer to cfg.h for information about what this API returns.

  • DumpDeviceResources shows how to obtain information about resources that a device uses.

  • DumpDeviceDriverFiles is provided as a debugging aid and obtains information about the files that are apparently being used for a device. It uses SetupDiBuildDriverInfoList to obtain information about the driver that is being used for the specified device. The driver list that is associated with a device can be enumerated by calling SetupDiEnumDriverInfo. In this case, there will be no more than one driver listed. This function proceeds to obtain a list of files that would typically be copied for this driver by using DIF_INSTALLDEVICEFILES. SetupScanFileQueue is used to enumerate the file queue to display the list of files that are associated with the driver.

  • DumpDeviceDriverNodes is provided as a debugging aid. This function determines the list of compatible drivers for a device. It uses SetupDiBuildDriverInfoList to obtain the list of compatible drivers. In this case, all drivers are enumerated; however, typically DIF_SELECTBESTCOMPATDRV and SetupDiGetSelectedDriver would be used together to find which driver the operating system would consider to be the best.

  • DumpDeviceStack determines class and device upper and lower filters.

Building the Sample

To build the devcon sample, do the following:

  1. Click the build environment icon in the Windows Driver Kits > Build Environments submenu. This command sets up the correct build environment to build this sample. Note that this sample builds in the 64-bit environments as well as the 32-bit environments.

  2. In a command window, change to the directory that contains the DevCon source code (for example, cd src\setup\devcon).

  3. Use the BLD macro or run the build -c command from the command prompt. This command runs the Microsoft make routines that produce the Build.log, Build.wrn, and Build.err log files. When the build completes, the executable will be placed in the ObjXXX\I386 subdirectory of the <TARGETPATH> directory that is specified in the Sources file (depending on build environment chosen).

  4. If the build does not succeed, check for these errors:
    • The build environment is not set up properly.
    • Modifications made to the sample source code introduced errors.



Send comments about this topic to Microsoft

Build date: 6/29/2012