Skip to content

Commit 88db84c

Browse files
feat(Windows): add broker service and license API (#63)
1 parent 0241d0f commit 88db84c

41 files changed

Lines changed: 3872 additions & 71 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,21 @@ jobs:
300300
throw "Windows driver installer exited with code $($process.ExitCode)."
301301
}
302302
303+
- name: Enable GitHub Actions evaluation window
304+
if: runner.os == 'Windows'
305+
shell: pwsh
306+
run: |
307+
$serviceName = "libvirtualhid_broker"
308+
$serviceRegistryPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$serviceName"
309+
New-ItemProperty `
310+
-LiteralPath $serviceRegistryPath `
311+
-Name Environment `
312+
-PropertyType MultiString `
313+
-Value @("GITHUB_ACTIONS=true") `
314+
-Force | Out-Null
315+
Restart-Service -Name $serviceName -Force
316+
(Get-Service -Name $serviceName).WaitForStatus("Running", [TimeSpan]::FromSeconds(15))
317+
303318
- name: Verify Windows test driver package
304319
if: runner.os == 'Windows'
305320
shell: pwsh
@@ -320,6 +335,9 @@ jobs:
320335
-Verbose
321336
}
322337
338+
- name: Run gamepad adapter example
339+
run: cmake --build cmake-build-ci --config ${{ env.CMAKE_BUILD_CONFIG }} --target run_gamepad_adapter_example
340+
323341
- name: Prepare report directory
324342
run: cmake -E make_directory cmake-build-ci/reports
325343

@@ -384,9 +402,6 @@ jobs:
384402
385403
$coverage.Save($coveragePath)
386404
387-
- name: Run gamepad adapter example
388-
run: cmake --build cmake-build-ci --config ${{ env.CMAKE_BUILD_CONFIG }} --target run_gamepad_adapter_example
389-
390405
- name: Generate gcov report
391406
id: test_report
392407
if: >-
@@ -506,7 +521,7 @@ jobs:
506521
run: >-
507522
cmake --build cmake-build-driver
508523
--config ${{ env.DRIVER_BUILD_CONFIG }}
509-
--target libvirtualhid_windows_catalog gamepad_adapter virtualhid_control
524+
--target libvirtualhid_windows_catalog libvirtualhid_broker gamepad_adapter virtualhid_control
510525
--parallel 2
511526
512527
- name: Validate Azure signing configuration

CMakeLists.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ option(LIBVIRTUALHID_TOOLS_FULLY_STATIC "Attempt to link libvirtualhid tools as
4242
option(LIBVIRTUALHID_TOOLS_STATIC_SDL3 "Prefer a static SDL3 diagnostic UI dependency when available" ON)
4343
option(LIBVIRTUALHID_ENABLE_XTEST "Enable X11/XTest keyboard and mouse fallback on Linux" ON)
4444
option(LIBVIRTUALHID_BUILD_WINDOWS_DRIVER "Build the Windows UMDF2 driver package with the WDK/MSVC toolchain" OFF)
45+
option(LIBVIRTUALHID_BUILD_WINDOWS_BROKER
46+
"Build the Windows broker service used by the monetized UMDF driver package"
47+
${LIBVIRTUALHID_BUILD_WINDOWS_DRIVER})
4548
option(LIBVIRTUALHID_INSTALL
4649
"Install libvirtualhid targets, headers, and CMake package files" ${LIBVIRTUALHID_IS_TOP_LEVEL})
4750
option(LIBVIRTUALHID_ENABLE_PACKAGING "Enable CPack package metadata" ${LIBVIRTUALHID_INSTALL})
@@ -67,6 +70,31 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTS AND NOT CMAKE_CXX_CO
6770
set(CMAKE_C_FLAGS "-fprofile-arcs -ftest-coverage -ggdb -O0")
6871
endif()
6972

73+
set(LIBVIRTUALHID_USES_LIZARDBYTE_COMMON OFF)
74+
if(WIN32)
75+
set(LIBVIRTUALHID_USES_LIZARDBYTE_COMMON ON)
76+
endif()
77+
78+
if(LIBVIRTUALHID_USES_LIZARDBYTE_COMMON OR BUILD_TESTS)
79+
set(LIZARDBYTE_COMMON_BUILD_TEST_SUPPORT
80+
${BUILD_TESTS}
81+
CACHE BOOL "Build lizardbyte-common GoogleTest support helpers" FORCE)
82+
set(LIZARDBYTE_COMMON_INSTALL
83+
${LIBVIRTUALHID_INSTALL}
84+
CACHE BOOL "Install lizardbyte-common targets and package configuration" FORCE)
85+
if(NOT TARGET lizardbyte::common)
86+
add_subdirectory(third-party/lizardbyte-common)
87+
endif()
88+
if(MSVC AND LIBVIRTUALHID_BUILD_WINDOWS_DRIVER)
89+
set_property(TARGET lizardbyte_common PROPERTY
90+
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
91+
if(TARGET lizardbyte_common_test_support)
92+
set_property(TARGET lizardbyte_common_test_support PROPERTY
93+
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
94+
endif()
95+
endif()
96+
endif()
97+
7098
# Copy MinGW runtime DLLs beside a target when using GNU toolchains on Windows.
7199
function(libvirtualhid_copy_mingw_runtime target_name)
72100
if(NOT WIN32 OR NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -103,6 +131,10 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
103131
add_subdirectory(src/platform/windows/driver)
104132
endif()
105133

134+
if(WIN32 AND LIBVIRTUALHID_BUILD_WINDOWS_BROKER)
135+
add_subdirectory(src/platform/windows/broker)
136+
endif()
137+
106138
if(BUILD_DOCS)
107139
add_subdirectory(third-party/doxyconfig docs)
108140
endif()

LICENSES/LicenseRef-LizardByte-SAL-1.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
LIZARDBYTE SOURCE-AVAILABLE LICENSE
22
Version 1.0, May 2026
33

4-
Copyright (C) 2026 David Lane. <https://app.lizardbyte.dev/>
4+
Copyright (C) 2026 LIZARDBYTE LLC. <https://app.lizardbyte.dev/>
55
The Licensor may modify this license document at any time and for any reason.
66
Everyone else is permitted to copy and distribute verbatim copies
77
of this license document, but changing it is not allowed.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
<a href="https://sonarcloud.io/project/overview?id=LizardByte_libvirtualhid"><img src="https://img.shields.io/sonar/quality_gate/LizardByte_libvirtualhid.svg?server=https%3A%2F%2Fsonarcloud.io&style=for-the-badge&logo=sonarqubecloud&label=sonarcloud" alt="SonarCloud"></a>
1616
</div>
1717

18+
<div align="center">
19+
<h2>🎮 Windows Virtual HID Driver License</h2>
20+
<p>
21+
<strong>A license is required to create virtual gamepads with the Windows driver.</strong><br>
22+
This requirement is Windows-only; non-Windows backends do not currently require a license.<br>
23+
Yearly and lifetime options are available.
24+
</p>
25+
<a href="https://buy.polar.sh/polar_cl_zj6Io5NVukXfZSl97ULtFvImfI5L1jbL2cSnc0Y72Pt"><img src="https://img.shields.io/badge/Buy_a_Windows_license-0078D4?logo=windows11&logoColor=white&style=for-the-badge" alt="Buy a Windows license"></a>
26+
</div>
27+
1828
# Overview
1929

2030
## ℹ️ About

cmake/libvirtualhid-config.cmake.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ if(@LIBVIRTUALHID_USES_THREADS@)
88
pkg_check_modules(LIBEVDEV REQUIRED IMPORTED_TARGET libevdev)
99
endif()
1010

11+
find_dependency(lizardbyte-common)
12+
1113
include("${CMAKE_CURRENT_LIST_DIR}/libvirtualhid-targets.cmake")
1214

1315
check_required_components(libvirtualhid)

cmake/packaging/windows.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ if(NOT TARGET virtualhid_control)
3434
"so the virtualhid_control UI tool can be packaged.")
3535
endif()
3636

37+
if(NOT TARGET libvirtualhid_broker)
38+
message(FATAL_ERROR
39+
"The Windows driver installer requires LIBVIRTUALHID_BUILD_WINDOWS_BROKER=ON "
40+
"so the broker service can be packaged.")
41+
endif()
42+
3743
install(TARGETS gamepad_adapter
3844
RUNTIME DESTINATION "tools/windows"
3945
COMPONENT driver)

cmake/packaging/wix_resources/libvirtualhid-driver-installer-patch.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
<CPackWiXFragment Id="#PRODUCT">
33
<CustomAction Id="CA_LibVirtualHidInstallDriver"
44
Directory="INSTALL_ROOT"
5-
ExeCommand="&quot;[WindowsFolder]System32\WindowsPowerShell\v1.0\powershell.exe&quot; -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\windows\install-driver.ps1&quot; -InfPath &quot;[INSTALL_ROOT]drivers\windows\libvirtualhid.inf&quot; -CertificatePath &quot;[INSTALL_ROOT]certificates\libvirtualhid-ci-test.cer&quot; -LogPath &quot;[CommonAppDataFolder]libvirtualhid\install-driver.log&quot;"
5+
ExeCommand="&quot;[WindowsFolder]System32\WindowsPowerShell\v1.0\powershell.exe&quot; -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\windows\install-driver.ps1&quot; -InfPath &quot;[INSTALL_ROOT]drivers\windows\libvirtualhid.inf&quot; -CertificatePath &quot;[INSTALL_ROOT]certificates\libvirtualhid-ci-test.cer&quot; -BrokerPath &quot;[INSTALL_ROOT]services\windows\libvirtualhid_broker.exe&quot; -LogPath &quot;[CommonAppDataFolder]libvirtualhid\install-driver.log&quot;"
66
Execute="deferred"
77
Return="check"
88
Impersonate="no" />
99
<CustomAction Id="CA_LibVirtualHidInstallDriverSilent"
1010
Directory="INSTALL_ROOT"
11-
ExeCommand="&quot;[WindowsFolder]System32\WindowsPowerShell\v1.0\powershell.exe&quot; -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\windows\install-driver.ps1&quot; -InfPath &quot;[INSTALL_ROOT]drivers\windows\libvirtualhid.inf&quot; -CertificatePath &quot;[INSTALL_ROOT]certificates\libvirtualhid-ci-test.cer&quot; -LogPath &quot;[CommonAppDataFolder]libvirtualhid\install-driver.log&quot;"
11+
ExeCommand="&quot;[WindowsFolder]System32\WindowsPowerShell\v1.0\powershell.exe&quot; -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File &quot;[INSTALL_ROOT]scripts\windows\install-driver.ps1&quot; -InfPath &quot;[INSTALL_ROOT]drivers\windows\libvirtualhid.inf&quot; -CertificatePath &quot;[INSTALL_ROOT]certificates\libvirtualhid-ci-test.cer&quot; -BrokerPath &quot;[INSTALL_ROOT]services\windows\libvirtualhid_broker.exe&quot; -LogPath &quot;[CommonAppDataFolder]libvirtualhid\install-driver.log&quot;"
1212
Execute="deferred"
1313
Return="check"
1414
Impersonate="no" />

docs/store-review-validation.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ Driver Store. It is not a kernel-mode `.sys` driver.
1313
Paste this into the Partner Center certification notes field:
1414

1515
```text
16-
This package installs the libvirtualhid Windows user-mode UMDF/VHF virtual HID driver. Applications consume it through the libvirtualhid client API, and the MSI includes a native diagnostic UI for local validation.
16+
This package installs the libvirtualhid Windows user-mode UMDF/VHF virtual HID driver and local broker service. Applications consume it through the libvirtualhid client API, and the MSI includes a native diagnostic UI for local validation.
17+
18+
Every virtual gamepad creation requires an active license. A currently granted review license key with an available device activation is supplied separately in the Partner Center certification credentials or notes. The key is not embedded in the package or this document.
1719
1820
Launch the validation tool below.
1921
@@ -23,15 +25,18 @@ C:\Program Files\libvirtualhid
2325
Installed validation files:
2426
C:\Program Files\libvirtualhid\tools\windows\virtualhid_control.exe
2527
C:\Program Files\libvirtualhid\tools\windows\gamepad_adapter.exe
28+
C:\Program Files\libvirtualhid\services\windows\libvirtualhid_broker.exe
2629
2730
Required validation:
2831
$installRoot = Join-Path $env:ProgramFiles "libvirtualhid"
2932
& "$installRoot\tools\windows\virtualhid_control.exe"
3033
31-
In the libvirtualhid control window, 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.
34+
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.
3235
3336
Expected result:
3437
- The backend status reports windows-umdf with gamepad support available
38+
- The libvirtualhid_broker service is running
39+
- License validation succeeds and the license status reports Licensed
3540
- A virtual HID gamepad is created and appears in the device list
3641
- A virtual HID gamepad child device starts with the Xbox Series HID ID
3742
HID\VID_045E&PID_0B12&IG_00
@@ -59,7 +64,9 @@ Expected result:
5964
2. Reboot only if Windows reports that a reboot is required.
6065
3. Open PowerShell.
6166
4. Run the required validation tool from the submission notes.
62-
5. Optionally run the browser validation steps.
67+
5. Activate the review key supplied through Partner Center.
68+
6. Create the default gamepad and exercise its controls.
69+
7. Optionally run the browser validation steps.
6370

6471
If the default install location was changed during MSI installation, replace
6572
`$env:ProgramFiles\libvirtualhid` with the selected install directory.
@@ -76,5 +83,6 @@ The `x360` profile is not used for Store review. The Windows UMDF/VHF backend is
7683
HID-only and intentionally does not emulate the Xbox 360 XUSB stack.
7784

7885
The reviewer-visible success signal is the installed `ROOT\LIBVIRTUALHID`
79-
control device, the `\\.\LibVirtualHid` control path, and a started HID gamepad
80-
child device while `virtualhid_control.exe` has a gamepad created.
86+
control device, the `\\.\LibVirtualHid` control path, the running
87+
`libvirtualhid_broker` service, and a started HID gamepad child device while
88+
`virtualhid_control.exe` has a gamepad created.

docs/usage.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ unless they explicitly enable additional options.
7676
fallback.
7777
- `LIBVIRTUALHID_BUILD_WINDOWS_DRIVER`: build the Windows UMDF2 driver package
7878
with the Microsoft WDK/MSVC toolchain.
79+
- `LIBVIRTUALHID_BUILD_WINDOWS_BROKER`: build the Windows broker service used by
80+
the driver package for gamepad creation, active-device limits, and license
81+
state.
7982
- `LIBVIRTUALHID_ENABLE_PACKAGING`: enable CPack package metadata.
8083
- `LIBVIRTUALHID_WARNINGS_AS_ERRORS`: treat project warnings as errors.
8184

@@ -102,6 +105,14 @@ capabilities, list device nodes reported for UI-created devices, and display
102105
normalized gamepad output such as rumble, RGB LED, adaptive trigger, trigger
103106
rumble, and raw report events delivered through the normal callback path. Button
104107
controls are momentary by default so they behave like physical gamepad buttons;
108+
on Windows, the UI also displays broker license status and can activate,
109+
refresh, or deactivate a machine license. Outside the explicitly marked GitHub
110+
Actions test environment, every Windows UMDF gamepad creation requires a
111+
current successful license validation response and there is no offline grace
112+
period. The CI-only exception is a single five-minute window that begins with
113+
the first gamepad creation attempt. Purchase and account-management buttons use
114+
the compiled URLs in
115+
`src/platform/windows/shared/lvh_windows_broker_config.hpp`.
105116
enable `Lock buttons` to keep the old click-to-toggle behavior for held inputs.
106117
The resizable window supports a compact width. Its device and control panels
107118
stack, and the button grid reflows, to keep controls usable when it is narrowed.
@@ -119,6 +130,10 @@ The API centers on portable device concepts:
119130

120131
- `Runtime`: owns backend discovery, initialization, device creation, and
121132
shutdown.
133+
- `get_license_status`, `activate_license`, `validate_license`, and
134+
`deactivate_license`: provider-neutral machine license operations for host
135+
applications. On Windows these call the installed local broker; license keys
136+
are not retained by the client library or returned to the application.
122137
- `VirtualDevice`: common lifecycle for created devices.
123138
- `Gamepad`: submits normalized gamepad state and receives output callbacks.
124139
- `Keyboard`: submits key press/release and UTF-8 text input.

0 commit comments

Comments
 (0)