Specifications

Everything, in full.

The complete capability list. The product page shows what HIDMaestro is; this page proves what it does. Each entry is covered at length in the documentation.

Identity and fidelity

Exact hardware identity
Profile-driven VID/PID, product strings, HID descriptors, axis and button layout, and bus type. A Bluetooth controller carries the hardware and compatible IDs a real device of its transport carries, classic BTHENUM or LE BTHLEDevice, so it reports as Bluetooth, not as a USB device wearing its name. SDL3's controller database matches it, Steam recognizes it, Chrome identifies it, joy.cpl shows the right name.
Valve personas Steam recognizes
Three composite personas present the whole USB device a real Valve controller presents: the Steam Deck's controller (five interfaces, reproduced from a real unit's lsusb dump), the wired 2015 Steam Controller (every descriptor verbatim from a real unit), and the 2026 Steam Controller. Steam files them under its own hardware rather than Generic DirectInput, answers arrive for the GET_REPORT interrogation Steam performs before claiming a device, and each packs its own wire format cross-checked against SDL's decoders. As of v2.0.2 each reports on its own clock, every 4 ms on the Deck and the 2026 controller and every 9 ms on the 2015 controller, so SDL integrates the true rotation whatever rate a program submits at. Motion arrives in each device's own axes and units, each unit answers its own serial so Steam keeps separate settings for it, the trackpads report pressure, and the Deck's and 2026 controller's trigger bits set at 90 percent of travel, their firmware's default.
A Switch Pro that answers back
The Switch Pro Controller is not a passive device: hosts drive a Nintendo subcommand handshake and stall without a device that answers. HIDMaestro answers it from the profile's data over the real Bluetooth wire, with a descriptor extracted byte-exact from a live Pro's SDP cache: SPI calibration reads, input-mode switch, and full-mode reports with gyro and accel every 15 ms on the device's own clock. switch-pro-usb is the same pad on its USB descriptor. SDL3 and Steam Input bind it as a real Bluetooth Pro Controller with motion and rumble.
A Switch 2 Pro with motion
switch2-pro-controller-composite presents a Switch 2 Pro Controller the way the pad appears over USB: HID on one interface and a vendor bulk pair on the other, with a real pad's descriptors byte for byte. Windows binds WinUSB to the second interface from the persona's own descriptors, with no driver install. Steam and SDL start it with the pad's own commands and then read its gyro and accelerometer, which the consumer submits in g and degrees per second. SDL reads 1 g and 100 degrees per second back within 1 percent on every axis. Rumble comes back decoded. DirectInput, WGI and browsers see a gamepad that never reports, as with a real pad, and switch2-pro-controller stays the profile for them.
Pressure-sensitive DualShock 3
dualshock-3-full presents a DualShock 3 the way Sony's sixaxis.sys driver and DsHidMini's SXS mode do on Windows, the form PCSX2 and RPCS3 read button pressure from. Cross, circle, square, triangle, L1, R1 and each d-pad direction take a pressure from 0 to 255, and L2 and R2 take theirs from the triggers. Motion, battery, rumble and the player LEDs come through as well. Stock SDL3 configured the way PCSX2 configures it reads every pressure axis. PCSX2 and RPCS3 themselves have not been run against it.
Controller audio and haptics
A real USB DualSense is a four-interface composite, and three profiles present all four. Windows gets the pad's own Speakers and Headset Microphone endpoints, and the 4-channel stream behind them carries the speaker on channels 1 and 2 and the voice-coil actuators on 3 and 4. That stream is the only path on Windows by which a game hands a controller its authored haptic waveforms. It reaches your code as UsbAudio.Output with each channel's role named. Nothing extra to install: the USB transport ships inside the DLL and deploys itself the first time you create one.
Wii U GameCube adapter
gamecube-adapter is Nintendo's WUP-028, the four-port adapter Melee players use, on the USB/IP transport. Its descriptors match 57 public dumps of the real adapter. Dolphin's and Slippi's own adapter code, compiled unmodified, reads all four ports, and so does SDL 3.4.18 built with libusb. The official SDL3 build for Windows has no libusb and lists no adapter, real or virtual. BindWinUsb() binds WinUSB to this one virtual adapter, so libusb hosts open it with no Zadig step. A restore never changes the driver of a devnode that is present. A real adapter that takes the instance after the virtual one is gone opens on WinUSB too, and after a kill it can open on WinUSB again at its next plug-in until a teardown, cleanup, reclaim, re-bind or follow-up finds the devnode gone and marks it to install Windows' HID driver. Each port has its own connection, input and rumble, and a controller connected to an empty port reports itself at rest. The adapter is a profile and no code: its ports, command protocol and WinUSB binding are JSON run by mechanisms any profile can use. A host poll interval can be set faster than the descriptor's 8 ms, as Melee players overclock the adapter.
Capture a controller you own
Point HMDeviceExtractor at any controller you have plugged in and get a ready-to-deploy profile back. Clone a DualSense and ship a 16-button variant that Windows, Steam, and games still see as a DualSense. Build a flight stick, racing wheel, or arcade panel from scratch with arbitrary VID/PID, axis count, button count, and resolution.

The catalog

337 device profiles
Embedded profiles across 73 vendors: Xbox 360, Xbox Series, DualSense, Thrustmaster, Logitech, flight sticks, racing wheels, keyboards, mice, and more. Every device is a JSON file. Adding support for a new one means writing JSON, not modifying code.
Keyboards and mice
A profile can be a keyboard or a mouse. The catalog holds 51 keyboards and 52 mice from 32 vendors, each the report descriptor of a real device's keyboard or mouse interface. Raw Input lists each one as its kind, a Scroll Lock pressed on a virtual keyboard turns Scroll Lock on, and the mouse moves the cursor. SubmitKeyboard, SubmitMouse and SubmitConsumer pack into whatever reports the profile declares. Every report arrives: the driver confirms each one Windows takes, and a burst of 600 one-count moves lost nothing. If the consumer dies with a key held, the driver lets go of it, and the next session's cleanup removes the devices it left.
Devices are JSON
Add a controller by writing a data-only JSON profile or by capturing one you already own, with no recompile. The SDK and the drivers hold no per-device code: battery scenario S88 fails on a device name, a vendor or product ID compared or switched on, or a profile field only one device sets, and the Sony feature answers, the Switch Pro's and Switch 2 Pro's protocols, the DualShock 3's sixaxis form and the XUSB companion's answers are all profile data. A report field's wire form is parameters: min and max, invert, a center for offset binary, a scale for motion counts, a battery level table, bit groups packed across frames, and a sensor clock that counts elapsed time. Profiles load strictly: a mistake refuses the file, and HMContext.ProfileLoadIssues lists it with the JSON path and the reason. A profile built in code meets the same checks at create, which throws HMProfileException before it touches the machine. A profile takes the feature answers, protocol and presentation it does not carry from a model it names with deviceModelFrom, or from identity defaults that keep a profile made outside the catalog behaving as its VID and PID did in 1.x. A device that builds its reports from its own state, as the Switch Pro, the Switch 2 Pro and the DualShock 3 do, carries a state block and report programs, compiled at build for the catalog and interpreted for your own profiles. HIDMaestroProfileCheck, in the release ZIP, checks a profile file as the SDK loads it and prints each problem with its JSON path. Adding a controller to a code-per-device emulator means writing and compiling a new device implementation. That difference is the whole point of the profile system. A device that carries several controllers in one report, and the commands it answers, are data too: the Wii U GameCube adapter's four ports and its command protocol are its profile, run by mechanisms any profile can use.

Latency and transport

~35 µs measured input latency
The input number is real propagation, measured over 10,000 single-press iterations and reproducible with one command. The methodology is published in the repository at docs/testing/latency.md.
Event-driven output at 0.15 ms
Rumble, force feedback, and LED packets are signaled to the consumer per captured packet at ~0.18 ms median, roughly 50x faster than the 9.4 ms poll-quantized path it replaced. A controller at rest costs no measurable CPU unless its profile repeats its last report at rest as the real device does, as 21 profiles do: a DualSense over Bluetooth every 1.25 ms, a DualShock 4 every 4 ms.
No socket, no batching cap
Standard profiles use shared memory between the SDK and UMDF2 drivers. Input and output are signaled per frame or packet. Composite profiles use the bundled USB/IP transport over a loopback connection.
The comparison, honestly
VIIPER's published Windows figure, 168 µs, is localhost-only. Running it over an actual network, the thing the project is named for, adds roughly 1 to 5 ms on wired LAN or 10 to 50 ms over Wi-Fi on top of that figure, a caveat its docs mention only in passing. It also batches reports every millisecond, capping the update rate at 1000 Hz. HIDMaestro's input is event-driven with no fixed cap.
Networking at the right layer
Standard profiles keep controller traffic in shared memory. Composite profiles use a local loopback USB/IP connection. Applications can build network sharing above the SDK, as PadForge does with Remote Link.
Fast to start, fast to recover
When the installed driver already matches, InstallDriver() completes in ~40-60 ms and a consumer goes from process start to a live controller in about a second. If the consuming app is force-closed mid-session, the next launch evicts the orphaned devices and has the first controller live again in ~2.3 s, measured with an Xbox Series BT profile in the mix, the deepest teardown stack.

APIs and consumers

Every gaming API at once
DirectInput sees correct axes and buttons. XInput sees separate triggers in one slot. SDL3/HIDAPI sees the right identity and bus type. The browser sees a STANDARD GAMEPAD with separate triggers. WGI sees one Gamepad. RawInput sees the same device as all of them, at the same time.
Multi-controller
No hard limit on simultaneous virtual controllers. Tested with 6 mixed types, correct per-controller ordering across every API. XInput caps Xbox-family profiles at its own 4 slots. Non-Xbox profiles run beyond it. Controllers from several programs that embed HIDMaestro coexist on one machine, each program keeping its own.
Programs side by side
Two or more programs that embed HIDMaestro run on one machine, and none removes or writes to another's controllers, driver or files unless it calls the remove-everything cleanup. Each program claims ownership before its first machine-wide write, and each controller claims a transport index and an identity, all as named pipes that Windows deletes when the program ends. Asking for an identity another live program holds throws HMResourceInUseException. Sweeps remove only what exited programs left. Driver deploys take one machine-wide lock, never downgrade, and install the 2.0.0 driver over any older one, whatever runs on it. Device registrations and removals take another, so no program on this release registers a device while another removes one. While a program built on v1.12.0 runs, controllers take transport indices from 64, out of its way. That older program still removes every HIDMaestro device at its InstallDriver and first create, so programs built on HIDMaestro 1.x must move to 2.0.0. Everything the SDK runs elevated is staged where only Administrators and SYSTEM can write, and checked against its SHA-256 first.
Hot-plug
Create and remove controllers on the fly, about 200 ms for a single controller as measured before v2.0.0. Live-swap a controller's profile mid-session. No reboots, no leftover devices.
Force feedback answered
HID PID 1.0 answers for DirectInput force-feedback games, plus rumble and haptic output events the consumer routes to real hardware. The driver accepts the writes and raises them to your application in real time.

VR

Virtual VR controllers
An embedded OpenVR driver presents a left and a right hand to SteamVR. The hands hold real SteamVR hand roles, serve the modern input system through a full input profile, and serve legacy GetControllerState readers through a shipped legacy binding. Controllers exist only while a consumer is live, so an idle machine shows no phantom devices. SteamVR is the one dependency, and it installs Steam-client-free and account-free via Valve's own steamcmd.

The SDK

One DLL
HIDMaestro.Core.dll contains the 337-profile catalog, a driver and helper payload for x64 and one for ARM64, the signing tools, and usbip-win2's signed host controller driver for both, 18.1 MB in all as of v2.0.1. It picks the set matching the machine. The OpenVR plugin is x64 for its SteamVR host. A source build can leave out the ARM64 payload or the USB/IP transport, and HMBuildInfo reports what a build carries.
NativeAOT and single-file apps
HIDMaestro.Core.dll loads its catalog and runs in NativeAOT apps and in trimmed, self-contained, single-file apps, for x64 and ARM64. Profiles load through source-generated JSON and every Win32 call goes through LibraryImport. A Release build fails on any warning from the trim, single-file and AOT analyzers. At v1.12.0 both kinds of app loaded none of the 336 profiles.
Self-bootstrapping install
InstallDriver() creates a locally trusted certificate, signs the driver, and installs it. No EV certificate, no test-signing mode, no reboot. When the installed driver already matches, the call completes in ~40-60 ms. Only one program deploys at a time. An older driver is upgraded whatever runs on it, and a newer one is never downgraded.
Removing HIDMaestro
HIDMaestroUninstall.exe, in the release ZIP as a NativeAOT build for x64 and ARM64 that needs no .NET runtime, removes HIDMaestro from a computer: every virtual controller and its device records, the driver packages, the signing certificate and its private key, HIDMaestro's registry keys, its staging and OpenVR folders, the folders older releases left in each account's %TEMP%, its OpenVR registration, its OEM name overrides and its DeviceOverrides keys. The joy.cpl and GameInput keys it shares with real controllers go back to what they held before, each only while it still holds what HIDMaestro wrote. --preview lists what would go and changes nothing, and --json writes the report as JSON. A program does the same with HMUninstall.Preview() and HMUninstall.Run(), and never blocks itself. The driver is shared by every HIDMaestro program on the machine, so a removal refuses while another one runs and names it, and a program on 2.0.1 or later that starts during a removal waits for it to end. A removal never restarts the computer and never follows a link. With usbip-win2 included it also takes usbip-win2's root-hub filter, which restarts every USB 3 root hub. The report says what stays and why, such as the GameInputSvc start type and Windows' own logs.
A UI instead of code
If you want to use HIDMaestro through a UI instead of code, install PadForge. It wraps this SDK with a full input-mapping app.

Validation

Regression coverage
The battery has 101 scenarios covering lifecycle, encoders, consumer APIs, USB/IP, VR, the battery reply a pad gives XInput, device identity across nine lives per family, the driver catalogs for both architectures, the DualShock 3 and 4 reports against the programs that read them, the Switch 2 Pro persona against a capture of a real pad, the registry keys a virtual shares with real devices, every catalog keyboard and mouse through Raw Input, programs running side by side as separate processes, NativeAOT and single-file apps, the GameCube adapter persona through Dolphin, Slippi and SDL, every raw value of every catalog conversion through the SDK's rounding, the Sony, Valve and Nintendo vendor-blob reports against golden bytes, profiles and device models loaded strictly, every report program three ways, the protocol engine and device clock, the version contract on the live driver, a Joy-Con built from the Switch Pro's mechanisms, the SDK and drivers checked for device shortcuts, and a full removal of HIDMaestro inside Windows Sandbox. Production signing and the full HIDMaestro integration gate remain pending.
Judged by the real consumers
The battery checks more than HIDMaestro's own decode of its own encode. A stock upstream SDL3 build reads the Valve personas and must bind each with its own Valve driver, and a scenario starts the actual Steam client and asserts it claims and classifies them, gives a second Deck and a second 2026 controller settings of their own, and drives the Deck's haptics. Another runs Steam's own firmware updater, which must see the 2026 Steam Controller persona and offer it no update. Stock SDL3 arms the Bluetooth DualShock 4 persona itself and must keep reading it, and opens the DualShock 3 persona the way PCSX2 configures it. SDL3 with libusb starts the Switch 2 Pro persona and reads its motion back on every axis, and the Steam client must add it and keep reading it. The decoders Steam Input is built on are the judges. Dolphin's and Slippi's own adapter code, compiled unmodified, reads the GameCube adapter persona, and SDL built with libusb lists one gamepad per port.

Platform and licensing

Native on ARM64 Windows
The HID driver, the XInput companion and the device helper are built for ARM64 as well as x64, and the INFs carry an NTARM64 section. HIDMaestro.Core.dll holds both sets and installs the one matching the operating system. Composite personas use a Microsoft-signed ARM64 build of the USB transport. The release has an ARM64 ZIP with an ARM64 test app and profile extractor. Use v1.9.1 or later on ARM64. The battery builds the ARM64 driver catalog on every run, and no ARM64 machine has run the battery yet.
Windows 10 and 11
Windows 10/11 on x64 and Windows 11 on ARM64, with .NET 10 and a 64-bit consumer. Every release has a ZIP for each architecture.
UMDF2 standard profiles
Standard profiles run through the Windows UMDF2 stack and a locally trusted signing certificate. Composite profiles use the bundled Microsoft-signed USB/IP transport. The installation does not enable Windows test-signing mode.
The composite exception, stated
Composite Sony, Valve and Nintendo profiles use the bundled usbip-win2 0.9.8.1 kernel transport, redistributed unmodified and checked against its pinned SHA-256 at build and again before Windows installs it. As of v2.0.1 the SDK installs only its host controller, silently, on a machine that has none. It never runs usbip-win2's installer or uninstaller and never installs its root-hub filter, so no USB device drops. The install is recorded, so a removal takes HIDMaestro's install and leaves another program's. A machine HIDMaestro put on 0.9.7.7 or 0.9.7.5 is moved to 0.9.8.1 automatically, through one Windows driver update that leaves the root-hub filter alone, in a session where the controller is still unused.
MIT licensed
Free and open source. Use it in your own projects, commercial or otherwise, with no restrictions.

Also included

Faster than 1.12.0
A DualShock 4 create takes about half the time it took on 1.12.0, because a create installs the driver the store's search chose before instead of searching again. A game reads a DualShock 4 or DualSense report about 30 percent sooner after the submit. The driver and the XInput companion are built with the WDK's release optimization, and no submit, output report or USB/IP transfer allocates memory. The release notes give each path's numbers against 1.12.0.

Who ships it

Public projects that use, ship or build on HIDMaestro, each checked against its own source, README or site. Where a project's newest release includes HIDMaestro, it carries HIDMaestro's license notice.

PadForge
The flagship. Every capability this SDK ships, in one app.
foundation-sunshine
A Sunshine fork whose DualSense support is built on HIDMaestro.
Vibepollo
A Sunshine fork whose DualSense over USB/IP draws on HIDMaestro's composite descriptors.
Sunshine Control Panel
Installs Foundation Sunshine's DualSense sidecar, HIDMaestro Core included.
Kitsune Input
A DualSense bridge app whose virtual gamepad is derived from HIDMaestro.
HHL Gamepad WLAN
HandHeld Legend's app for HOJA gamepads over WLAN, on a pinned HIDMaestro.
JoystickGremlinEx
A flight-sim remapper driving the SDK from Python over pythonnet.
Rubylight
A Moonlight streaming host whose DualSense haptics draw on HIDMaestro's composite descriptors.
Nearcade
Pins the SDK as a submodule for its remote-play bridge.
GKME
An Android phone as a Windows gamepad, crediting HIDMaestro as its driver framework.
FlexInput
Uses HIDMaestro as its default virtual-device backend.
DirectXInput
Its source drives Xbox pads, keyboards and mice through HIDMaestro.
dualsense-command
Bundles the runtime in its bridge installers.
ApexBridge
Combines sim racing wheels, pedals and shifters into one virtual force feedback wheel.
AxisNex
A free stick-calibration app whose tuned input reaches games through a HIDMaestro controller.
ControllerOS
A programmable controller platform whose virtual Xbox backend is a pinned HIDMaestro.
DK Desktop Essentials
A local-first Windows suite whose Controller Hub outputs through HIDMaestro.
DS5Bridge
Presents a GameSir pad to games as a virtual DualSense.
dualsense-bridge
Forwards a DualSense over UDP to a HIDMaestro DualSense on Windows.
DualSenseBridge (Sahecz)
A DualSense or DualSense Edge as a virtual Xbox 360 controller for games without PlayStation support.
EasyRazer
A Razer Huntsman analog keyboard tool with an experimental HIDMaestro gamepad.
ForzaDualSenseHaptic
DualSense haptics for Forza Horizon 6, with HIDMaestro as an Xbox emulation backend.
G7 Bridge
A GameSir G7 Pro on its 2.4 GHz receiver as a virtual Steam Controller.
GKMD
A virtual USB game controller engine modified from HIDMaestro 1.5.1.
GlassPad
Touches on a screen overlay as a virtual gamepad, through HIDMaestro.
hidmaestro-client-rust
A native Rust client for a HIDMaestro Xbox 360 controller, with no .NET.
hidmaestro-rs
Virtual controllers for Rust tests and MCP assistants, through a .NET bridge to HIDMaestro.
InputLine
Brings a Steam Controller from an iPad or iPhone to a PC as a wired Steam Controller.
JoyLinkea 2
Phones as web controllers for a Windows PC over a LAN or online.
KSX
Splits keyboards and arcade encoders into virtual controllers, with a HIDMaestro DualSense output.
libvirtualhid
LizardByte's cross-platform virtual HID library, whose Windows tools carry HIDMaestro's PID force feedback block.
LivePad
Turns live-stream chat into a shared Xbox controller.
MagicKeyboardBridge
Fn and Control remapping for Apple's Magic Keyboard, through a HIDMaestro keyboard.
MaratronVR
A manual treadmill as VR locomotion, with a HIDMaestro gamepad output on Windows.
mascon-bridge
Turns an analog lever into a virtual ZUIKI mascon for JR EAST Train Simulator.
Mimic Tear
A neural network that learns a player's style to fight Elden Ring bosses, with a HIDMaestro controller bridge.
NATSX Controller
Turns an Android phone into an Xbox 360 controller on Windows.
OmniPad
A phone gamepad whose Windows HID emulation runs on HIDMaestro.
OpenVR Emulation Driver XboxVR
Two SteamVR controllers driven by an Xbox controller, through HIDMaestro's VR controllers.
PandaPro8K
Bridges a GameSir G7 Pro 8K's extra controls and motion into Steam Input.
PanguBridge
Bridges a Beitong Pangu controller to a virtual DualSense Edge or Xbox controller.
PCSX2 Remote Play System
Streams PCSX2 and RPCS3 over a LAN and feeds the client's controller back through HIDMaestro.
Satellite
A wireless-gamepad server that plugs matching virtual controllers into the host PC for its LAN clients.
SCX-VPad
A Rust virtual controller driver that carries HIDMaestro's Sony USB descriptor and firmware tables.
Sunburst
A Rust streaming project whose gamepad layer ports HIDMaestro's SDK and reuses its profiles.
Switch 2 Native Bridge
Switch 2 Pro Controllers and Joy-Cons over Bluetooth, seen by Steam as wired Switch 2 Pro Controllers.
SwitchProXInput
A Switch Pro to XInput bridge on HIDMaestro's xbox-360-wired profile.
T16Bridge
Two Thrustmaster T.16000M sticks as two independent virtual controllers.
TrackPad CAD
Touchpad gestures as SpaceMouse input, through a HIDMaestro SpaceMouse Pro.
USB Racing Controller
An Android phone as an Xbox racing controller over a USB cable.
virtual-gamepad
A phone-to-PC Xbox 360 controller over WebRTC, driven through HIDMaestro.

Full comparison

Every capability, against the tools people usually reach for. The product page carries a shortened version of this table.

Capability HIDMaestro VIIPER ViGEmBus vJoy WinUHid
Kernel driver requiredNo, except the composite USB personasYes (USBIP)YesYesNo (on VHF)
Installs without test-signingYesYesYesYesNo
Network playApp layer via consumers (PadForge Remote Link)In the driver: +1-5 ms wired, +10-50 ms Wi-FiNoNoNo
Exact identity, incl. Bluetooth busYes, 337 profilesUSB only2 fixed typesFixed identity4 presets, USB only
Add a new deviceJSON, or capture one you ownWrite Go per deviceN/AN/AWrite C, or raw descriptor
Local single-press latency~35 µs measured168 µs publishedN/AN/ANot published
StatusActiveActiveRetiredStaleActive

Questions, answered plainly

Is it really free?
Yes. MIT licensed, free and open source, commercial use welcome with no restrictions. HIDMaestro will never become paid, freemium, or Patreon early-access paywalled.
Do I need to enable test-signing mode?
No. Standard profiles use UMDF2 with a locally trusted certificate. The bundled USB/IP kernel packages retain their upstream Microsoft signatures. The SDK does not enable Windows test-signing mode.
Does anything kernel-mode get installed?
Composite Sony, Valve and Nintendo profiles install the bundled usbip-win2 0.9.8.1 transport on a machine that has none. As of v2.0.1 that is its host controller alone: the SDK never runs usbip-win2's installer or installs its root-hub filter, so no USB device drops. Standard profiles use the Windows UMDF2 stack. A machine HIDMaestro put on 0.9.7.7 or 0.9.7.5 is moved to 0.9.8.1 automatically, with no window and no USB device dropping, so there is nothing to do when updating.
Can I add a controller you don't ship?
Yes, without touching code. Write a data-only JSON profile, or point HMDeviceExtractor at a controller you have plugged in and get a ready-to-deploy profile back.
How is this different from ViGEmBus, vJoy, or VIIPER?
Those tools install kernel drivers and present a small set of fixed device types. HIDMaestro runs in user mode and presents the exact identity of the profile you pick, 337 of them, down to the bus type, and adding a device means writing JSON rather than driver code. VIIPER additionally routes input through a network stack even for local play. The full comparison table above puts the tools side by side.
Does it work with Steam?
Yes. Steam recognizes the virtual controllers as the hardware their profiles declare, and the Valve personas go further: Steam files them under its own hardware, with the regression battery starting the actual Steam client to prove it claims and classifies all three.
Can two programs that embed HIDMaestro run on one machine?
Yes, as of v2.0.0. Each program keeps its own controllers, identities and sections, and a sweep removes only what exited programs left. The one exception is the remove-everything cleanup, RemoveAllVirtualControllers(HMCleanupScope.Everything, ...), which an uninstaller or a support tool calls. The driver is deployed by one program at a time and never downgraded, and the 2.0.0 driver is installed over any older one, whatever runs on it. A running program built on v1.12.0 or older still removes every HIDMaestro device on the machine at its InstallDriver and at its first create, and while one runs, a v2.0.0 program's controllers take transport indices from 64. Programs built on HIDMaestro 1.x must move to 2.0.0.
How do I remove HIDMaestro from a computer?
As of v2.0.1, run HIDMaestroUninstall.exe from the release ZIP. --preview lists what would go and changes nothing, and --yes removes without asking. A program that embeds HIDMaestro calls HMUninstall.Run() instead, from its own uninstaller or a settings button. A removal refuses while another program that embeds HIDMaestro runs, and other programs install the driver again at their next InstallDriver or create. With --include-usbip it also takes what usbip-win2's own installer left, its root-hub filter included, which restarts every USB 3 root hub. Windows' own logs and the GameInputSvc start type stay, and the report says why.
Does it work in NativeAOT and single-file apps?
Yes, as of v2.0.0, for NativeAOT and for trimmed, self-contained, single-file apps, on x64 and ARM64. The battery runs the two apps for the machine's architecture, so the ARM64 apps are built and published and have not run on ARM64 hardware.
Does the GameCube adapter work with Dolphin and Slippi?
Yes. The gamecube-adapter profile is Nintendo's WUP-028 on the USB/IP transport, and BindWinUsb() binds WinUSB to the virtual adapter so Dolphin and Slippi open it through libusb with no Zadig step. Their own adapter code, compiled unmodified, reads all four ports. The official SDL3 build for Windows has no libusb and lists no adapter, real or virtual.
Does HIDMaestro support ARM64?
Yes. Use v1.9.1 or later. One HIDMaestro.Core.dll serves x64 and ARM64 and carries a native driver payload for each, and the release has an ARM64 ZIP with an ARM64 test app and profile extractor. The ARM64 payload builds and is signed, and the battery builds its driver catalog on every run. No ARM64 machine has run the battery yet.