Tips for Coding in Driverland

Try the Mouse Driver First

Sending data the mouse driver is easier than sending it to the joystick driver, and way easier than sending it to the keyboard driver. Once you have it working with the mouse driver, you will understand the basics of working with the drivers. So start with the mouse.

Use the Keyboard Driver Ping and Timeout Features

It is possible to send a key-down command to the driver, then not send the corresponding key-up command (due to a crash or maybe forgot). This leaves the key in a pressed state and acts like you are physically pressing the key on the real keyboard. The keyboard driver has special feature which requires that you ping it every so often (every 100 ms is good) and if the driver has not received a ping in the timeout value (5000 ms is good), the driver will automatically release all the keys.

If you are using the keyboard driver, you will appreciate this feature. Without this feature, you would be rebooting. Often.

Use the SDK utils during development

When you are coding for sending data to a driver, use the SDK’s keyboard and joystick reader utilities to see if the data is being sent correctly to the driver. This way you are sure it is being read correctly from the driver, so you can concentrate of the sending to the driver.

Find the drivers in Windows Device Manager

Just set the View menu to Devices by connection and that makes it easier to see the drivers listed.

Get to know the driver installation log

There is a C:\Windows\INF\setupapi.dev.log file that records all driver install and uninstall activity. Any error’s will be listed in the log with a !!! prefix. This log can get quite large, but you can delete it so that it is recreated when you install the drivers. There’s a lot of fascinating driver info in this log. If a driver didn’t install, this should be your first stop.

Here’s the log entries for running install.bat in the Joystick driver folder. There are no errors during the installation:

[Device Install Log]
OS Version = 10.0.18363
Service Pack = 0.0
Suite = 0x0100
ProductType = 1
Architecture = amd64

[BeginLog]

[Boot Session: 2020/06/14 07:43:13.938]

>>> [Delete Device - ROOT\HIDCLASS\0001]
>>> Section start 2020/06/14 11:09:59.223
cmd: devcon.exe remove root\ttcvcontr -runhidden
dvi: Query-and-Remove succeeded
<<< Section end 2020/06/14 11:09:59.250
<<< [Exit status: SUCCESS]


>>> [Device Install (UpdateDriverForPlugAndPlayDevices) - root\ttcvcontr]
>>> Section start 2020/06/14 11:09:59.278
cmd: devcon.exe install ttcvcontr.inf root\ttcvcontr -runhidden
ndv: INF path: C:\HID Virtual Device Kit Standard 1.6\Drivers Signed\Joystick\ttcvcontr.inf
ndv: Install flags: 0x00000001
ndv: {Update Device Driver - ROOT\HIDCLASS\0001}
ndv: Search options: 0x00000080
ndv: Searching single INF 'C:\HID Virtual Device Kit Standard 1.6\Drivers Signed\Joystick\ttcvcontr.inf'
dvi: {Build Driver List} 11:09:59.309
dvi: Searching for hardware ID(s):
dvi: root\ttcvcontr
dvi: Created Driver Node:
dvi: HardwareID - root\ttcvcontr
dvi: InfName - c:\hid virtual device kit standard 1.6\drivers signed\joystick\ttcvcontr.inf
dvi: DevDesc - Tetherscript Virtual Joystick
dvi: Section - ttcvcontrollershim.win8.NT
dvi: Rank - 0x00ff0000
dvi: Signer Score - Authenticode
dvi: DrvDate - 05/26/2020
dvi: Version - 9.31.12.96
dvi: {Build Driver List - exit(0x00000000)} 11:09:59.364
dvi: {DIF_SELECTBESTCOMPATDRV} 11:09:59.368
dvi: Default installer: Enter 11:09:59.371
dvi: {Select Best Driver}
dvi: Class GUID of device changed to: {745a17a0-74d3-11d0-b6fe-00a0c90f57da}.
dvi: Selected Driver:
dvi: Description - Tetherscript Virtual Joystick
dvi: InfFile - c:\hid virtual device kit standard 1.6\drivers signed\joystick\ttcvcontr.inf
dvi: Section - ttcvcontrollershim.win8
dvi: {Select Best Driver - exit(0x00000000)}
dvi: Default installer: Exit
dvi: {DIF_SELECTBESTCOMPATDRV - exit(0x00000000)} 11:09:59.404
ndv: Force Installing Driver:
ndv: Inf Name - ttcvcontr.inf
ndv: Driver Date - 05/26/2020
ndv: Driver Version - 9.31.12.96
ndv: Driver package 'C:\WINDOWS\System32\DriverStore\FileRepository\ttcvcontr.inf_amd64_834f068120bd2a35\ttcvcontr.inf' is already imported.
sto: {Setup Import Driver Package: c:\hid virtual device kit standard 1.6\drivers signed\joystick\ttcvcontr.inf} 11:09:59.428
sto: Driver package already imported as 'oem25.inf'.
sto: {Setup Import Driver Package - exit (0x00000000)} 11:09:59.438
dvi: Searching for hardware ID(s):
dvi: root\ttcvcontr
dvi: Class GUID of device changed to: {745a17a0-74d3-11d0-b6fe-00a0c90f57da}.
dvi: {Plug and Play Service: Device Install for ROOT\HIDCLASS\0001}
dvi: Driver INF Path: C:\WINDOWS\INF\oem25.inf
dvi: Driver Node Name: ttcvcontr.inf:ed86ca11221ae399:ttcvcontrollershim.win8:9.31.12.96:root\ttcvcontr,
dvi: Driver Store Path: C:\WINDOWS\System32\DriverStore\FileRepository\ttcvcontr.inf_amd64_834f068120bd2a35\ttcvcontr.inf
dvi: Searching for hardware ID(s):
dvi: root\ttcvcontr
dvi: Class GUID of device changed to: {745a17a0-74d3-11d0-b6fe-00a0c90f57da}.
dvi: {Core Device Install} 11:09:59.483
dvi: {Install Device - ROOT\HIDCLASS\0001} 11:09:59.484
dvi: Device Status: 0x01802001, Problem: 0x0 (0x00000000)
dvi: Parent device: HTREE\ROOT\0
dvi: {Configure Device - ROOT\HIDCLASS\0001} 11:09:59.486
dvi: Device Status: 0x01802001, Problem: 0x0 (0x00000000)
dvi: Parent device: HTREE\ROOT\0
sto: {Configure Driver Package: C:\WINDOWS\System32\DriverStore\FileRepository\ttcvcontr.inf_amd64_834f068120bd2a35\ttcvcontr.inf}
sto: Source Filter = root\ttcvcontr
inf: Class GUID = {745a17a0-74d3-11d0-b6fe-00a0c90f57da}
inf: Class Options = Configurable BootCritical
inf: {Configure Driver: Tetherscript Virtual Joystick}
inf: Section Name = ttcvcontrollershim.win8.NT
inf: {Add Service: WUDFRd}
inf: Start Type = 3
inf: Service Type = 1
inf: Error Control = 1
inf: Image Path = \SystemRoot\System32\drivers\WUDFRd.sys
inf: Display Name = Windows Driver Foundation - User-mode Driver Framework Reflector
inf: Group = Base
inf: Updated service 'WUDFRd'.
inf: Leaving existing description (A kernel mode driver that uses message-based interprocess communication mechanism to communicate with the driver manager and host process to facilitate UMDF drivers).
inf: {Add Service: exit(0x00000000)}
inf: {Add Service: mshidumdf}
inf: Start Type = 3
inf: Service Type = 1
inf: Error Control = 1
inf: Image Path = \SystemRoot\System32\Drivers\mshidumdf.sys
inf: Leaving existing error control (0).
inf: Leaving existing load order group (Base).
inf: Leaving existing display name (Pass-through HID to UMDF Driver).
inf: Updated service 'mshidumdf'.
inf: Leaving existing description (Device Driver to provide pass-through interface between HIDCLASS and UMDF).
inf: {Add Service: exit(0x00000000)}
inf: Hardware Id = root\ttcvcontr
inf: {Configure Driver Configuration: ttcvcontrollershim.win8.NT}
inf: Service Name = mshidumdf
inf: Lower Filters = WUDFRd
inf: Config Flags = 0x00000000
inf: {Configure Driver Configuration: exit(0x00000000)}
inf: {Configure Driver: exit(0x00000000)}
flq: Copying 'C:\WINDOWS\System32\DriverStore\FileRepository\ttcvcontr.inf_amd64_834f068120bd2a35\ttcvcontr.dll' to 'C:\WINDOWS\System32\drivers\UMDF\ttcvcontr.dll'.
cpy: Existing file 'C:\WINDOWS\System32\drivers\UMDF\ttcvcontr.dll' remains unchanged.
flq: Copying 'C:\WINDOWS\System32\DriverStore\FileRepository\ttcvcontr.inf_amd64_834f068120bd2a35\WudfUpdate_01011.dll' to 'C:\WINDOWS\System32\WudfUpdate_01011.dll'.
cpy: Existing file 'C:\WINDOWS\System32\WudfUpdate_01011.dll' remains unchanged.
sto: {Configure Driver Package: exit(0x00000000)}
dvi: Install Device: Configuring device (oem25.inf:root\ttcvcontr,ttcvcontrollershim.win8.NT). 11:09:59.521
dvi: Install Device: Configuring device completed. 11:09:59.525
dvi: Device Status: 0x01802001, Problem: 0x0 (0x00000000)
dvi: Install Device: Starting device 'ROOT\HIDCLASS\0001'. 11:09:59.527
dvi: Install Device: Starting device completed. 11:09:59.561
dvi: {Configure Device - exit(0x00000000)} 11:09:59.562
dvi: {Install Device - exit(0x00000000)} 11:09:59.565
dvi: {Core Device Install - exit(0x00000000)} 11:09:59.565
ump: {Plug and Play Service: Device Install exit(00000000)}
ndv: {Update Device Driver - exit(00000000)}
ndv: {Install Related Drivers} 11:09:59.583
ndv: {Install Related Drivers: exit(0x00000000)} 11:09:59.590
<<< Section end 2020/06/14 11:09:59.596
<<< [Exit status: SUCCESS]