Part 3: USB Device Research – USB Enumeration in Windows


Have you ever wondered how or why Windows uses different drivers and configurations for what appears to be USB devices of the same type? I certainly have. That question is part of what sparked my interest in researching MSC, PTP and MTP devices as discussed in my previous posts of this series.

The information that is sent from a USB device to Windows is used by components of the OS to determine how the device is classified, what drivers and configurations are used, and in effect what functionality the USB device is capable of supporting. In this post we will be going over different aspects of device communication and some of the inner workings of Windows that handles USB device enumeration. The information provided is a high-level overview, most of which is pulled from Microsoft’s online library for developers and some from my personal testing. The topics that will be the focus of this post include:

  • How driver stacks are created and how they handle communication with a USB device
  • How Windows chooses the best drivers for a device
  • Registry keys related to installation and enumeration
  • Enumeration of composite devices

1.1 Enumeration & Communication Using Driver Stacks

Communication with a device is accomplished with the help of several different drivers. These drivers are associated with a device object within the device stack, maintained by PnP. Each device node has its own device stack. In the PnP device tree, a node might represent either a device, one function of a composite device, or software components not related to a physical device.

The first object created in a device stack is at the bottom, and the last at the top.

The PDO (Physical Device Object) is the first object created. It is created by the function driver lower in the PnP device tree. The next object created is the FDO (Functional Device Object) this is the main driver in the stack. This driver handles reading, writing and device control requests. There can also be filter drivers in the stack. These are created by the function driver and help the FDO with its tasks. These objects are called Filter DOs (Filter Device Object). A filter driver can occur above the function driver (upper filter) or below the function driver (lower filter). Also, when a device is used in raw mode, there are no function or filter drivers in the device node [1].

When a device is first installed, the INF file used determines which driver is the function and which is the filter. This information is then stored in the registry. The PnP manager uses the information in the registry to enumerate the stack for a device. Refer to the below image for an example of a stack for a USB storage device.

Figure 1

Figure 1: Source: http://msdn.microsoft.com/en-us/library/windows/hardware/hh439632%28v=vs.85%29.aspx

All drivers in the previously mentioned stack are kernel mode drivers. Sometimes, a device can have both a user-mode stack and a kernel-mode stack. User-mode drivers are usually based on UMDF (User-Mode Driver Framework) and are represented as user-mode DLLs.

When communication needs to take place, a driver or component of the OS sends an IRP (I/O Request Packet) to the device stack. It starts at the top of the stack and travels down until an object/driver can complete the request.

1.2 How Does Windows Choose the Best Driver for a USB Device?

1.2.1 Communication between the Device and Windows: Obtaining Hardware IDs and Compatible IDs

When a USB device is attached to a computer running Windows, the USB hub driver queries information from the attached device and creates one or more Hardware IDs and Compatible IDs for the device.

The Hardware ID has a prefix of “USB\” which specifies the bus driver handling the device, followed by the vendor, model and revision identifier [2].  The format of the Hardware ID is:

  • USB\VID_1234&PID_5678&REV_0001

The vendor, model and revision identifiers are pulled from the Device Descriptor Response packet from the fields idProduct, idVendor, and bcdDevice respectively [3], as shown in Figure 2.

Figure 2

Figure 2: USBlyzer Output Between Windows and a Samsung Galaxy S3 phone

The Compatible IDs also have a prefix of “USB\” indicating the hub driver reponsible for handling the device, followed by the class code, subclass code, and protocol code. An example of the format of a Compatible ID is:


The class, subclass, and protocol codes can be pulled either from bDeviceClass, bDeviceSubClass, and bDeviceProtocol fields of the device descriptor; or from bInterfaceClass, bInterfaceSubClass, and bInterfaceProtocol fields of the interface descriptor.

Figure 3

Figure 3: USBlyzer Output Between Windows and a Samsung Galaxy S3 phone

USB.org defines different classes of USB devices so that vendors can use device drivers provided by an OS. The device and interface descriptors are communicated to the OS by the device and contain Class, SubClass, and Protocol fields. According to USB.org, these fields are used to identify the function(s) provided by a USB device and the protocols used to communicate with the function(s) on the device.

You can view the full list of device classes at http://www.usb.org/developers/defined_class but for the purposes of our discussion, below are the classes related to MSC, PTP and MTP:

Figure 4

Figure 4: USB.org Device Classes

1.2.2 Within Windows

The USB hub driver tells the Plug and Play manager that the new device was detected. The Plug and Play manager then queries that USB hub driver for all of the device’s hardware IDs.

Plug and Play then communicates with Windows, indicating that a new device was found and needs to be installed and sends along the list of hardware IDs for processing.

1.2.3 INF Files: Searching for Matching Hardware IDs or Compatible IDs

Using the Hardware IDs, Windows attempts to search for a driver package that matches within various INF files. If it does not find a match, it searches for a driver package that has a matching Compatible ID for the device [4].

1.2.4 Ranking and Installation of Drivers

If one or more matching drivers are found, Windows will assign a rank to each. For more information about how Windows ranks each driver, you can read [5]. The driver with the lowest rank is used. If a device has multiple drivers with the same rank, Windows uses either the Digitally Signed status or driver date and revision to choose which driver should be used.

The driver is installed in the following ways:

  1. Co-installers are registered. A co-installer typically writes additional configuration information to the system registry, or performs other installation tasks that requires install-time information that cannot be handled by the INF file. They can help with obtaining device parameters that are required for the device to operate.
  2. Windows determines the device setup class from entries in the INF, this information is stored in: SYSTEM\CurrentControlSet\Control\Class\{ClassGUID}
  3. PnP then takes control after drivers and co-installers are complete. The PnP manager then calls the AddDevice routine for each driver, starting with lower-filter drivers, then the function driver, and, finally, any upper filter drivers. PnP assigns resources to the device.
  4. If there is a co-installer specified, Windows issues codes to the co-installer for additional installation processing. (This may be where vendor specific applications take over and install the necessary device settings for it to function properly)
  5. After that is complete the device is installed and ready to use.

1.3 Registry Keys


This key represents the device setup class and is used to facilitate device installation [6]. While most classes are system supplied, vendors can also supply their own class. When a device is attached to a system, the INF file used to install a device stores its information here. One device may use multiple different GUIDs, each of which can be related back to the Driver Stack for that particular device. Under each GUID is a key that is created for each device that is attached to the system. The format of the key is “####”, starts at 0000 for the first device installed under a particular Setup Class and increments by one for each additional device installed under that same Setup Class. A reference to this key can be found in SYSTEM\CurrentControlSet\Enum\Enumerator\DeviceID\InstanceID\


A device interface class is a way of exporting device and driver functionality to other system components, including other drivers, as well as user-mode applications. A driver for a particular device will register for a device interface class. When a driver registers an instance of a device interface class, the I/O manager associates the device and the device interface class GUID with a symbolic link name [7]. The following is an example of a symbolic link name for a device:


In the SymbolicLinkName subkey there is an entry named DeviceInstance. The value has the following format: Enumerator\DeviceID\InstanceID


This key is created by the PnP manager. Under this key is a subkey for each device instance present on the system. This subkey has information such as the device description, hardware IDs, compatible IDs, and resource requirements. [8] The enumerator represents a function driver for an object in the driver stack for a device (refer to section 1.1, Device Communication through Driver Stacks). Enumerators for USB devices can include USB, STORAGE, and USBSTOR—among others in Windows versions post XP.

1.4 Multifunction or Composite Devices

Some devices have multiple interfaces that allow a device to perform different functions for each interface. Within Windows, these kinds of devices are enumerated a little differently than single function devices.

After the device is queried for Hardware IDs and the INF files are searched, if a match is found the driver indicated in the INF file is used and generic parent driver does not come into play. However, if no match is found, a Compatible ID of USB\COMPOSITE is used, if supported, and the USB Generic Parent Driver (Usbccgp.sys) is used [9].

The generic parent driver must know which of the interfaces it should manage. This allows the device to have support for some of its interfaces using Microsoft supplied drivers. For interfaces that are not supported by native Microsoft drivers, the vendor must supply the driver and the INF file [10].  In the previous post, I talked about how Windows cannot enumerate BlackBerry devices correctly. This is because the vendor specific software provided by BlackBerry must first be installed so that when the device is attached, it can access vendor specific drivers and INF files that were supplied during the install of the software. Without these, the generic parent driver does not have the necessary information to enumerate the device correctly.

Within the registry, each interface is enumerated as if it were separate a device, but Windows manages the interfaces as components of a single device.

The Hardware ID for the device is appended with MI_xx for each interface that is enumerated for a device. The related entries are propagated to registry keys and values that are handling the functions specific to that interface.

Coming Up…

In the next post I plan on going over the elements of my research, including details about the testing environment and methodologies used, as well as the findings for the following tests:

OSs Tested Windows XP Professional SP3
Windows 7 Professional SP1
Transport Protocols Tested MSC
Test Scenarios First Insert of USB device
Folder Traversal on USB Device
File & Folder Copy to Device
Open Files on Device


  1. http://msdn.microsoft.com/en-us/library/windows/hardware/hh439632%28v=vs.85%29.aspx
  2. http://msdn.microsoft.com/en-us/library/windows/hardware/ff728852%28v=vs.85%29.aspx
  3. http://msdn.microsoft.com/en-us/library/windows/hardware/ff553356%28v=vs.85%29.aspx
  4. http://msdn.microsoft.com/en-us/library/windows/hardware/ff728853%28v=vs.85%29.aspx
  5. http://msdn.microsoft.com/en-us/library/windows/hardware/ff686700%28v=vs.85%29.aspx
  6. http://msdn.microsoft.com/en-us/library/windows/hardware/ff549491%28v=vs.85%29.aspx
  7. http://msdn.microsoft.com/en-us/library/windows/hardware/ff549460%28v=vs.85%29.aspx
  8. http://msdn.microsoft.com/en-us/library/windows/hardware/ff546173%28v=vs.85%29.aspx
  9. http://msdn.microsoft.com/en-us/library/windows/hardware/ff537109%28v=vs.85%29.aspx
  10. http://msdn.microsoft.com/en-us/library/windows/hardware/ff539234%28v=vs.85%29.aspx


Nicole Ibrahim


  1. Hi nicole!!

    I’m reading your USB post series and are amazing, GREAT WORK, i’m loving all them.

    I just noticed this Registry Keys:


    Nevertheless i found “Class” & “DeviceClasses” under “Control” hive. So the complete hives will be:


    Maybe i’m wrong, but i just wanted to let you know.

    Keep good working with your amazing blog and researches.

    Greetings from México city.

    • Hi Héctor,

      I’m glad you’re enjoying the series. I hope that it proves to be helpful for you.
      You are correct regarding the registry keys. I’ve went ahead and updated the post to reflect the correct entries. I appreciate you bringing the errors to my attention, it always helps to have others weight in!

      – Nicole

  2. Hi Nicole,

    I am using McAfee’s DLP to control SD cards, USB, and MTP devices on our network. However, I am seeing MicroSD cards mounting as USB Storage despite being plugged into an SD card slot.

    I think the cause of this is the SD card slot is wired into the internal USB Hub on the motherboard. If so, then an SD card will either be picked up as a USB device or an SD card depending on the manufacturer?

    DLP seems to intermittently pick up SD card serial numbers…sometimes even when they are a MicroSD card inside a Blackberry.

    Incident Handlers are peppering me with questions abt these discrepancies and I am slogging thru tons of driver, kernel, and registry documentation in order to answer their questions.

Leave a Reply

Your email address will not be published. Required fields are marked *