Published on

Communicating with a USB Device Using WinUSB 2: Installing the Function Driver

Authors

This time I will install WinUsb.sys as the function driver for the device. To proceed, WDK needs to be installed. If you have not installed it yet, install WDF first.

The basic idea, as I remember it, is that the WinUSB API introduced in the next post sends messages to WinUsb.sys, and WinUsb.sys communicates with the device itself.

This step is very simple. All you need is to copy the required DLLs from the installed WDF and write a text file called an INF file.

Once this installation is complete, connecting the USB device no longer causes it to appear as an "Unknown device" warning. In other words, the OS starts recognizing the device.

First, create a driver installation package with a file layout like the one below. Everything except the INF file can simply be copied from the WDK installation folder. The INF file needs to be rewritten to match the device you are communicating with.

driver - amd64 - WdfCoInstaller01009.dll | |- winusbcoinstaller2.dll | |- ia64 - WdfCoInstaller01009.dll | |- winusbcoinstaller2.dll | |- x86 - WdfCoInstaller01009.dll | - winusbcoinstaller2.dll | |- example.inf |- dpinst.exe (I will describe this executable later)

Installation locations of the DLLs and related files:

  • WdfCoInstaller01009.dll: WinDDK\BuildNumber\redist\wdf\CPUArch
  • winusbcoinstaller2.dll: WinDDK\BuildNumber\redist\winusb\CPUArch
  • dpinst.exe: WinDDK\BuildNumber\redist\DIFx\dpinst\MultiLin\CPUArch

CPUArch means values such as ia32, amd64, or x86.

Create the INF file

At minimum, it is enough to change only the sections below. The other parts mainly affect things such as the name shown in Device Manager, so if all you want is device recognition, those do not need to be changed.

  1. In the [Manufacturer] section, put in the device-specific VID and PID values.
    • You can check them from the device properties in Device Manager after connecting the device.
  2. In the [WinUSB_Install] section, set KmdfLibraryVersion to match the version of WDF you are using.
  3. In the [Dev_AddReg] section, set the GUID. This is passed as an argument to the SetupDiGetClassDevs() API.
  4. In the [CoInstallers_AddReg] section, set the version of WdfCoInstaller01009.dll.
  5. In the [SourceDisksNames] section, place the DLLs in folders for each CPU architecture and specify those folders.
  6. The remaining parts mainly affect what is displayed in Device Manager, so they work even if you do not change them.
    • Modify them as needed.
[Version]
Signature = "$Windows NT$"
Class = MyDeviceClass
ClassGUID = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider = %ManufacturerName%
CatalogFile=MyCatFile.cat
DriverVer=09/16/2012,1.0.0.0

; ================== Class section ==================
[ClassInstall32]
Addreg=MyDeviceClassReg

[MyDeviceClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-1

; ========== Manufacturer/Models sections ===========
; Change VID and PID to match the device
[Manufacturer]
%ManufacturerName% = Standard,NTx86,NTamd64,NTia64

[Standard.NTx86]
%DeviceName% =USB_Install, USB\VID_1234&PID_1234

[Standard.NTamd64]
%DeviceName% =USB_Install, USB\VID_1234&PID_1234

[Standard.NTia64]
%DeviceName% =USB_Install, USB\VID_1234&PID_1234

; =================== Installation ===================

[USB_Install]
Include=winusb.inf
Needs=WINUSB.NT

[USB_Install.Services]
Include=winusb.inf
AddService=WinUsb,0x00000002,WinUsb_ServiceInstall

[WinUsb_ServiceInstall]
DisplayName = %WinUsb_SvcDesc%
ServiceType = 1
StartType = 3
ErrorControl= 1
ServiceBinary = %12%\WinUSB.sys

[USB_Install.Wdf]
KmdfService=WINUSB, WinUsb_Install

[WinUsb_Install]
KmdfLibraryVersion=1.9

[USB_Install.HW]
AddReg=Dev_AddReg

[Dev_AddReg]
; Match the GUID on the device side
HKR,,DeviceInterfaceGUIDs,0x10000,"{4CB642FB-45E2-4B5B-9ED9-37D0E35A2C2C}"

[USB_Install.CoInstallers]
AddReg=CoInstallers_AddReg
CopyFiles=CoInstallers_CopyFiles

[CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01011.dll,WdfCoInstaller","WinUsbCoInstaller2.dll"

[CoInstallers_CopyFiles]
WinUsbCoInstaller2.dll
WdfCoInstaller01009.dll

[DestinationDirs]
CoInstallers_CopyFiles=11

; ================= Source Media Section =====================

[SourceDisksNames]
1 = %DiskName%,,,\x86
2 = %DiskName%,,,\amd64
3 = %DiskName%,,,\ia64

[SourceDisksFiles.x86]
WinUsbCoInstaller2.dll=1
WdfCoInstaller01009.dll=1

[SourceDisksFiles.amd64]
WinUsbCoInstaller2.dll=2
WdfCoInstaller01009.dll=2

[SourceDisksFiles.ia64]
WinUsbCoInstaller2.dll=3
WdfCoInstaller01009.dll=3

; =================== Strings ===================

[Strings]
ManufacturerName="ManufacturerName"
ClassName="Samples"
DiskName="USB Installation Disk"
WinUsb_SvcDesc="WinUSB Driver"
DeviceName="MyDeviceClass"

Install WinUsb.sys

Once you have the folder containing the INF file and DLLs described above, connect the USB device and install it. If the OS does not recognize it yet, it will appear as an unknown device or trigger a wizard.

In that wizard, specify the folder containing the INF file as the location of the device driver. If the INF file is written correctly, the driver will be installed and the unknown device warning should disappear. Once it is installed successfully, you should also be able to confirm the device from Device Manager. The name set in the INF file should appear there. Change it as needed. You can also do the same thing through the driver update function in Device Manager.