Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ endif()
# Package config
#
if(LIBVIRTUALHID_INSTALL)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
DESTINATION "${CMAKE_INSTALL_DATADIR}/licenses/libvirtualhid"
COMPONENT library)

configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/libvirtualhid-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/libvirtualhid-config.cmake"
Expand Down
12 changes: 9 additions & 3 deletions LICENSES/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ Windows driver package.
- Cross-platform library source, public headers, non-driver backends, examples,
tests, build scripts, and documentation unless listed below:
[MIT](https://github.com/LizardByte/libvirtualhid/blob/master/LICENSE).
- Windows UMDF driver source under `src/platform/windows/driver/`:
- Windows UMDF driver source under `src/platform/windows/driver/`, the broker
service under `src/platform/windows/broker/`, and the broker entitlement and
evaluation sources
`src/platform/windows/shared/lvh_windows_broker_config.hpp` and
`src/platform/windows/shared/lvh_windows_github_actions_evaluation.hpp`:
[LizardByte Source-Available License 1.0](https://github.com/LizardByte/libvirtualhid/blob/master/LICENSES/LicenseRef-LizardByte-SAL-1.0.md).
- Generated Windows driver package artifacts, including the driver MSI:
[LizardByte Source-Available License 1.0](https://github.com/LizardByte/libvirtualhid/blob/master/LICENSES/LicenseRef-LizardByte-SAL-1.0.md).

The Windows driver MSI may include MIT-licensed helper components from this
repository; packaged installs include both license texts for that reason.
Every installed library distribution includes the MIT notice under
`share/licenses/libvirtualhid`. The Windows driver MSI may include MIT-licensed
helper components from this repository; packaged installs include both license
texts for that reason.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ test app path and does not currently advertise an ARM64 build.
## 📄 License

The cross-platform `libvirtualhid` library is licensed under the MIT License.
The Windows UMDF driver source and generated Windows
driver package artifacts, including the driver MSI, are licensed under the
LizardByte Source-Available License 1.0 (LB-SAL 1.0). See the
The Windows UMDF driver, broker, proprietary entitlement/evaluation sources,
and generated Windows driver package artifacts, including the driver MSI, are
licensed under the LizardByte Source-Available License 1.0 (LB-SAL 1.0). See the
[license map](LICENSES/README.md) for the full repository split.
6 changes: 3 additions & 3 deletions docs/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ effects back into the public callback. Each requested playback repetition
restarts the effect's ramp and envelope timing. A zero-length effect remains
active until its explicit stop event, matching the infinite-effect contract used
by SDL and Steam. The Linux backend lets a new uinput device settle before
reading those effects so an early poll error cannot disable feedback for the
reading those effects, so an early poll error cannot disable feedback for the
device lifetime. Generated UHID nodes are correlated by stable physical and
unique identifiers when available, with device-name matching used only as a
fallback. PlayStation rumble is read from native UHID interrupt-channel output
Expand All @@ -120,7 +120,7 @@ which avoids changing the raw button capability surface. It uses a compact
Generic button layout rather than the sparse Xbox button slots.

Xbox 360 retains its `0x045E:0x028E` identity, while its Linux uinput device uses
the Bluetooth bus so consumers select the sparse button mapping.
the Bluetooth bus, so consumers select the sparse button mapping.
Xbox One and Xbox Series retain their public USB identities, but their Linux
uinput devices use the corresponding Bluetooth product identities (`0x0B20`
and `0x0B13`, respectively), whose standard consumer mappings match the events
Expand Down Expand Up @@ -230,7 +230,7 @@ Current macOS capabilities:
codes.
- Mouse relative movement, absolute movement on the main display, left/middle/
right button transitions, and pixel-based vertical/horizontal scroll.
- Shared keyboard modifier state on mouse events so combinations such as
- Shared keyboard modifier state on mouse events, so combinations such as
shift-click continue to work.

Unsupported macOS capabilities currently return `unsupported_profile`:
Expand Down
2 changes: 1 addition & 1 deletion docs/store-review-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ C:\Program Files\libvirtualhid\services\windows\libvirtualhid_broker.exe

Required validation:
$installRoot = Join-Path $env:ProgramFiles "libvirtualhid"
& "$installRoot\tools\windows\virtualhid_control.exe"
Start-Process "$installRoot\tools\windows\virtualhid_control.exe"

In the libvirtualhid control window, paste the supplied review key into the License key field and click Activate license. Confirm the status changes to Licensed. Then leave the default Xbox Series profile selected and click Create. Use the button and axis controls in the UI to submit input to the virtual controller.

Expand Down
46 changes: 23 additions & 23 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,21 @@ buttons, sticks, triggers, and battery state, show backend and profile
capabilities, list device nodes reported for UI-created devices, and display
normalized gamepad output such as rumble, RGB LED, adaptive trigger, trigger
rumble, and raw report events delivered through the normal callback path. Button
controls are momentary by default so they behave like physical gamepad buttons;
controls are momentary by default, so they behave like physical gamepad buttons;
on Windows, the UI also displays broker license status and can activate,
refresh, or deactivate a machine license. Outside the explicitly marked GitHub
Actions test environment, every Windows UMDF gamepad creation requires a
current successful license validation response and there is no offline grace
period. The CI-only exception is a single five-minute window that begins with
the first gamepad creation attempt. Purchase and account-management buttons use
refresh, or deactivate a machine license without elevation. Every Windows UMDF
gamepad creation requires a current successful license validation response and
there is no offline grace period. Purchase and account-management buttons use
the compiled URLs in
`src/platform/windows/shared/lvh_windows_broker_config.hpp`.
enable `Lock buttons` to keep the old click-to-toggle behavior for held inputs.
Enable `Lock buttons` to click-to-toggle behavior for held inputs.
The resizable window supports a compact width. Its device and control panels
stack, and the button grid reflows, to keep controls usable when it is narrowed.
The UI intentionally does not use gamepad navigation so virtual devices created
stack, and the button grid reflows to keep controls usable when it is narrowed.
The UI intentionally does not use gamepad navigation, so virtual devices created
by the tool cannot drive the tool's own controls.

External devices created by another process, such as Sunshine, are not
enumerated yet. That requires backend protocol support so the Windows driver or
enumerated yet. That requires backend protocol support, so the Windows driver or
Linux backend can expose cross-process device snapshots without letting two
processes race to control the same virtual device.

Expand All @@ -133,7 +131,9 @@ The API centers on portable device concepts:
- `get_license_status`, `activate_license`, `validate_license`, and
`deactivate_license`: provider-neutral machine license operations for host
applications. On Windows these call the installed local broker; license keys
are not retained by the client library or returned to the application.
are not retained by the client library or returned to the application. The
client verifies that the named-pipe server is the SCM-registered running
broker before sending any request.
- `VirtualDevice`: common lifecycle for created devices.
- `Gamepad`: submits normalized gamepad state and receives output callbacks.
- `Keyboard`: submits key press/release and UTF-8 text input.
Expand Down Expand Up @@ -183,18 +183,18 @@ touch, motion, battery, feedback, and lifecycle updates onto the platform-neutra

Built-in gamepad profiles and their platform-neutral default device names are:

| Profile | Default device name |
| --- | --- |
| Generic HID gamepad | `(libvirtualhid) Generic Controller` |
| Xbox 360 | `(libvirtualhid) X-Box 360 Controller` |
| Xbox One | `(libvirtualhid) X-Box One Controller` |
| Xbox Series | `(libvirtualhid) X-Box Series Controller` |
| DualShock 4 USB and Bluetooth | `(libvirtualhid) PS4 Controller` |
| DualSense USB and Bluetooth | `(libvirtualhid) PS5 Controller` |
| Nintendo Switch Pro | `(libvirtualhid) Nintendo Pro Controller` |
| Profile | Default device name |
|-------------------------------|-------------------------------------------|
| Generic HID gamepad | `(libvirtualhid) Generic Controller` |
| Xbox 360 | `(libvirtualhid) X-Box 360 Controller` |
| Xbox One | `(libvirtualhid) X-Box One Controller` |
| Xbox Series | `(libvirtualhid) X-Box Series Controller` |
| DualShock 4 USB and Bluetooth | `(libvirtualhid) PS4 Controller` |
| DualSense USB and Bluetooth | `(libvirtualhid) PS5 Controller` |
| Nintendo Switch Pro | `(libvirtualhid) Nintendo Pro Controller` |

Consumers may replace `DeviceProfile::name` before creating a gamepad, for
example to prepend an application name while preserving the default controller
example, to prepend an application name while preserving the default controller
identity across platform backends.

The platform-neutral Generic HID descriptor reports the D-pad as buttons 13
Expand All @@ -203,8 +203,8 @@ through 16 in the input report. Linux may still route that profile through
standard `ABS_HAT0X` and `ABS_HAT0Y` axes.

Profiles advertise support for features such as rumble, trigger rumble, RGB
LEDs, adaptive triggers, motion sensors, touchpads, battery state, profile
specific buttons, and raw output reports. Consumers should query profile and
LEDs, adaptive triggers, motion sensors, touchpads, battery state,
profile-specific buttons, and raw output reports. Consumers should query profile and
backend capabilities before warning users about unsupported client features.
The `misc1` button represents Share/Capture/Mic Mute-style controls and is
available on the generic, Xbox Series, DualSense, and Switch Pro profiles; Xbox
Expand Down
40 changes: 30 additions & 10 deletions docs/windows-driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ normal desktop application to use the broker without running as administrator
while keeping broker ownership and privileged device operations in the Windows
service.

Status, current-license validation, activation, replacement, deactivation,
gamepad creation, and owned-device destruction are available to authenticated
local users without elevation. Before sending any request, clients compare the
named-pipe server PID to the SCM-registered, currently running
`libvirtualhid_broker` service. This prevents another local process from
impersonating an unavailable broker and collecting a license key. The service
also requests first ownership of the pipe name and rejects remote clients.

All broker messages are fixed-size and fully validated before use, including
protocol versions, exact byte counts, request types, reserved fields, enums,
array bounds, string terminators, and unused payload bytes. Connection, request,
and response operations use cancellable overlapped I/O with explicit completion
and byte-count checks, so a stopped service or disconnected client cannot leave
an operation using expired stack state.

The backend sends fixed-size C protocol structures to the broker. A create
request identifies the backend's existing control handle; the broker duplicates
that handle from the named-pipe client process and issues `DeviceIoControl` on
Expand Down Expand Up @@ -101,7 +116,7 @@ cpack -G WIX -C Release --config .\cmake-build-windows-driver\CPackConfig.cmake

The package defaults to UMDF 2.15, matching the inbox VHF UMDF source driver
while still exposing the framework APIs used by libvirtualhid. The driver links
the MSVC runtime statically so the UMDF host process does not need VC runtime
the MSVC runtime statically, so the UMDF host process does not need VC runtime
DLLs beside the driver.

## Developer Install and Validation
Expand Down Expand Up @@ -180,7 +195,8 @@ diagnostics.

On Windows, the UI also shows broker license status. It can activate a license
key, refresh validation, deactivate the current machine, and open
compiled purchase or account-management URLs.
compiled purchase or account-management URLs. License management and normal
virtual-gamepad use do not require elevation.

## Installation Notes

Expand Down Expand Up @@ -230,8 +246,12 @@ The broker stores machine-scoped license state in:
C:\ProgramData\libvirtualhid\license.dat
```

The file is protected with Windows DPAPI local-machine scope. GitHub Actions
evaluation timing is stored separately with the same protection in
The file is protected with Windows DPAPI local-machine scope. The state
directory and both state files are owned by LocalSystem and use protected DACLs
that grant full access only to `NT SERVICE\libvirtualhid_broker`, LocalSystem,
and built-in administrators; reparse-point state paths are rejected. GitHub
Actions evaluation timing is
stored separately with the same DPAPI and ACL protection in
`C:\ProgramData\libvirtualhid\github-actions-evaluation.dat`. Broker entitlement
configuration is compiled into the Windows broker and diagnostic UI. Update
`src/platform/windows/shared/lvh_windows_broker_config.hpp` when the Polar
Expand Down Expand Up @@ -314,9 +334,9 @@ and must not ship the local pull-request test certificate.

## License

The Windows UMDF driver source and generated Windows driver package artifacts,
including the driver MSI, are licensed under the LizardByte Source-Available
License 1.0 (LB-SAL 1.0). See the [license map](../LICENSES/README.md) for the
full repository license split. The MSI may also include MIT-licensed helper
components from this repository, so packaged installs include both license
texts.
The Windows UMDF driver, broker, proprietary entitlement/evaluation sources,
and generated Windows driver package artifacts, including the driver MSI, are
licensed under the LizardByte Source-Available License 1.0 (LB-SAL 1.0). See
the [license map](../LICENSES/README.md) for the full repository license split.
The MSI may also include MIT-licensed helper components from this repository,
so packaged installs include both license texts.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ elseif(WIN32)
_WIN32_WINNT=0x0600)
target_link_libraries(${PROJECT_NAME}
PRIVATE
advapi32
setupapi
lizardbyte::common)
elseif(APPLE)
Expand Down
3 changes: 3 additions & 0 deletions src/include/libvirtualhid/license.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ namespace lvh {
*
* The license key is sent directly to the platform license service. The library does not
* persist a copy or expose it in the returned status.
* On Windows, authenticated local clients can activate or replace a license without elevation.
*
* @param license_key License key supplied by the customer.
* @param instance_name Optional customer-visible name for this machine activation.
Expand All @@ -98,6 +99,8 @@ namespace lvh {
/**
* @brief Deactivate the stored license from this machine.
*
* On Windows, authenticated local clients can deactivate a license without elevation.
*
* @return Deactivation result and latest license details.
*/
LicenseResult deactivate_license();
Expand Down
Loading
Loading