DevCon Sample

SUMMARY

This document accompanies the "DevCon" sample which is a text-mode device console. The instructions herein apply to the Windows XP operating system. DevCon has been designed for use on Windows 2000 and Windows XP. It will also work on Windows 98 or Windows ME.

The "DevCon" sample described in this article is a command line utility that acts as an alternative to Device Manager. The sample allows one or more devices to be enabled, disabled, restarted, updated, removed and queried. The sample demonstrates how to use SetupAPI and CfgMgr32 API's together effectively to enumerate devices and perform device operations.

HOW IT WORKS

Running "devcon help" will provide a list of commands along with short descriptions of what each command does. "devcon help <command>" will give more detailed help on that command. The interpretation of each command is done via a dispatch table "DispatchTable" that is at the bottom of "cmds.cpp". Some of the commands make use of a generic device enumerator "EnumerateDevices". Some of these commands will work when given a remote target computer, and will also work if using the 32-bit devcon on Wow64.  A description of some of the more interesting functions and the APIs they use follows:

Classes

This command demonstrates the use of SetupDiBuildClassInfoListEx to enumerate all device class GUID's. The function SetupDiClassNameFromGuidEx and SetupDiGetClassDescriptionEx are used to obtain more information about each device class.

ListClass

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

Find FindAll Status

A simple use of EnumerateDevices (explained below) to list devices and display different levels of information about each device. Note that all but FindAll use DIGCF_PRESENT to only list information about devices that are currently present. The main functionality for these and related devices is done inside FindCallback.

Enable Disable Restart

These commands show how to issue DIF_PROPERTYCHANGE to enable a device, disable a device, or restart a device. The main functionality for each of these commands is done inside ControlCallback.

These operations cannot be done on a remote machine or in the context of Wow64. CFGMGR32 API's should not be used as they skip class and co-installers.

Update

This command shows how to use UpdateDriverForPlugAndPlayDevices to update the driver for all devices to a specific driver. Normally INSTALLFLAG_FORCE would not be specified allowing UpdateDriverForPlugAndPlayDevices to determine if there is a better match already known. It's specified in DevCon to allow DevCon to be used more effectively as a debugging/testing tool. This cannot be done on a remote machine or in the context of Wow64.

Install

A variation of Update 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 specified on the command line (which should correspond to a hardware ID in the INF). This cannot be done on a remote machine or in the context of Wow64.

Remove

A command to remove devices. Plug & Play devices that are removed will reappear in response to Rescan. The main functionality of this command is in RemoveCallback that demonstrates the use of DIF_REMOVE. This cannot be done on a remote machine or in the context of Wow64. CFGMGR32 API's should not be used as they skip class and co-installers.

Rescan

This command shows the correct way to rescan for all Plug & Play devices that may have previously been removed, or that otherwise require a rescan to detect them.

Reboot

This function shows how to correctly reboot the machine from a hardware install program. In particular it passes flags to ExitWindowsEx that cause the reboot to be associated with hardware installation. You should never reboot the machine 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 associated with a class or not (for most cases, a blank list need not be associated with a class). Demonstrates the use of SetupDiOpenDeviceInfo to add a device instance into a device info list. These last two API's are ideal to obtain a DeviceInfoData structure from a device instance and machine name when mixing CFGMGR32 API's with SETUPAPI API's. SetupDiGetDeviceInfoListDetail is called to obtain a remote machine handle that may be passed into CFGMGR32 API's. 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, using information in devInfo (obtained from SetupDiEnumerateDeviceInfo) and devInfoListDetail (obtained from SetupDiGetDeviceInfoListDetail). GetHwIds is called to obtain a list of hardware and compatible ID's (explained below). Once an interesting device has been determined (typically by checking hardware ID's) then the callback is called to operate on that individual device.

GetHwIds

Shows how to get the complete list of hardware ID's or compatible ID's for a device 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 info list) and PSP_DEVINFO_DATA (device info data).

DumpDeviceStatus

Shows how to interpret the information returned by CM_Get_DevNode_Status_Ex. Refer to cfg.h for information returned by this API.

DumpDeviceResources

Shows how to obtain information about resources used by a device.

DumpDeviceDriverFiles

Provided as a debugging aid, obtains information about the files apparently being used for a device. It uses SetupDiBuildDriverInfoList to obtain information about the driver being used for the specified device. The driver list associated with a device may 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 normally be copied for this driver using DIF_INSTALLDEVICEFILES. SetupScanFileQueue is used to enumerate the file queue to display the list of files that are associated with the driver.

DumpDeviceDriverNodes

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 OS would consider to be the best.

DumpDeviceStack

This function determines class and device upper and lower filters.

BUILDING THE DEVCON SAMPLE

To build the devcon sample:
  1. Use Microsoft Visual Studio 6 to build devcon.dsp

    There are four different builds for Console/Windows, Windows 98/NT

USING DEVCON

DevCon is provided in ready to run form:

FileDescription
DevConNT.exeWindows 2000/XP Console executable
DevConNTc.exeWindows 2000/XP Win32 executable
DevConC.exeWindows 98 Console executable
DevCon.exeWindows 98 Win32 executable

DevCon is a command line utility with built in documentation available by typing "devcon help".

TESTING

Type "devcon find *" to list device instances of all present devices on the local machine.

Type "devcon status @root\rdp_mou\0000" to list status of the terminal server mouse driver.

Type "devcon status *PNP05*" to list status of all COM ports.

CODE TOUR

File Manifest

FileDescription
DevCon.htmSample tour documentation for this binary (this file).
DevCon.dswWorspace file for Visual Studio 6.
DevCon.dspProject file for Visual Studio 6.
DevCon.cppSource file for tmain entry point and utility functions.
Cmds.cppSource file for supported commands.
Dump.cppSource file for functions that output information about devices.
DevCon.hHeader file for sample.
DevCon.rcResource file containing some strings and version information.
resource.hHeader file for resources.
SETUPAPI.HHeader file for the Windows 98 builds. In Widows 98 some structure lengts depend on MAX_COMPUTERNAME_LENGTH, in Windows 2000/XP they depend on MAX_PATH.
CFGMGR32.libConfig manager import library to make devcon work in Windows 98. In Windows 98 some functions are exported by cfgmgr32.dll that are exported by setupapi.dll in Windows 2000/XP.

Top of page

© Microsoft Corporation 2001, adapted to Win32 and Windows 98 by Kay Bruns 2008