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: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ jobs:
$certificatePath = Join-Path $env:GITHUB_WORKSPACE "cmake-build-driver\certificates\libvirtualhid-ci-test.cer"
cmake `
-DBUILD_DOCS=OFF `
-DBUILD_EXAMPLES=OFF `
-DBUILD_EXAMPLES=ON `
-DBUILD_TESTS=OFF `
-DLIBVIRTUALHID_BUILD_WINDOWS_DRIVER=ON `
-DLIBVIRTUALHID_ENABLE_PACKAGING=ON `
Expand All @@ -469,7 +469,7 @@ jobs:
run: >-
cmake --build cmake-build-driver
--config ${{ env.DRIVER_BUILD_CONFIG }}
--target libvirtualhid_windows_catalog
--target libvirtualhid_windows_catalog gamepad_adapter
--parallel 2

- name: Validate Azure signing configuration
Expand Down
33 changes: 20 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ Build the UMDF package separately with the Microsoft driver toolchain:
```powershell
cmake -S . -B cmake-build-windows-driver -G "Visual Studio 17 2022" -A x64 `
-DLIBVIRTUALHID_BUILD_WINDOWS_DRIVER=ON -DLIBVIRTUALHID_ENABLE_PACKAGING=ON `
-DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF
cmake --build cmake-build-windows-driver --config Release --target libvirtualhid_umdf
cmake --build cmake-build-windows-driver --config Release --target libvirtualhid_windows_catalog
-DBUILD_TESTS=OFF -DBUILD_EXAMPLES=ON
cmake --build cmake-build-windows-driver --config Release `
--target libvirtualhid_windows_catalog gamepad_adapter
cpack -G WIX -C Release --config .\cmake-build-windows-driver\CPackConfig.cmake
```

Expand All @@ -189,15 +189,22 @@ powershell -ExecutionPolicy Bypass -File .\scripts\windows\install-driver.ps1 `
-InfPath .\cmake-build-windows-driver\src\platform\windows\driver\package\Release\libvirtualhid.inf `
-LogPath .\cmake-build-windows-driver\install-driver.log
powershell -ExecutionPolicy Bypass -File .\scripts\windows\test-installed-driver.ps1 `
-GamepadAdapterPath .\cmake-build-ci\examples\Debug\gamepad_adapter.exe `
-GamepadAdapterPath .\cmake-build-windows-driver\examples\Release\gamepad_adapter.exe `
-GamepadProfile xseries
powershell -ExecutionPolicy Bypass -File .\scripts\windows\test-browser-gamepad.ps1 `
-GamepadAdapterPath .\cmake-build-ci\examples\Debug\gamepad_adapter.exe `
-GamepadAdapterPath .\cmake-build-windows-driver\examples\Release\gamepad_adapter.exe `
-GamepadProfile xseries
powershell -ExecutionPolicy Bypass -File .\scripts\windows\uninstall-driver.ps1 `
-Force -RemoveCertificateSubject "CN=libvirtualhid CI Test Driver Signing"
```

The WiX driver installer also installs validation files under the default
install root, `C:\Program Files\libvirtualhid`:

- `scripts\windows\test-installed-driver.ps1`
- `scripts\windows\test-browser-gamepad.ps1`
- `tools\windows\gamepad_adapter.exe`

The helper stages the INF with `pnputil`, updates an existing
`ROOT\LIBVIRTUALHID` device when present, and creates that root-enumerated
device when it is missing. It uses SetupAPI/NewDev directly so MSI installs do
Expand All @@ -213,22 +220,22 @@ if `\\.\LibVirtualHid` cannot be opened, or if a held gamepad adapter instance
does not produce a started HID child device such as
`HID\VID_045E&PID_0B12&IG_00` or an Xbox Series-compatible HID child such as
`HID\VID_045E&PID_02FF&IG_00`. That check is also run by the Windows CI legs
for every Windows UMDF/VHF-supported `gamepad_adapter` profile
after installing the Windows Driver Installer artifact. The browser helper is for manual
for every Windows UMDF/VHF-supported `gamepad_adapter` profile after installing
the Windows Driver Installer artifact. The browser helper is for manual
diagnostics: it launches a normal desktop Edge or Chrome instance at
`https://hardwaretester.com/gamepad`, holds a virtual gamepad, and fails if the
browser Gamepad API does not report a controller matching the selected profile
or does not observe changing button and axis input. For manual browser
validation, run the browser helper with `-KeepBrowserOpen`, or run
`examples/gamepad_adapter xseries --hold-seconds 60`, then open
`tools\windows\gamepad_adapter.exe xseries --hold-seconds 60`, then open
`https://hardwaretester.com/gamepad` in a normal desktop browser and press one
of the held virtual buttons if the browser needs a gamepad activation event.

The driver binary is a UMDF DLL installed through the Windows Driver Store, not
a libvirtualhid `.sys` copied into `C:\Windows\System32\drivers`. Windows still
uses its built-in `WUDFRd.sys` and VHF components under `System32\drivers`; the
libvirtualhid-specific sign that installation completed is the
`ROOT\LIBVIRTUALHID` device and the `\\.\LibVirtualHid` control device. The INF
The driver binary is a user-mode UMDF DLL installed through the Windows Driver
Store, not a libvirtualhid `.sys` copied into `C:\Windows\System32\drivers`.
Windows still uses its built-in `WUDFRd.sys` and VHF components under
`System32\drivers`; the libvirtualhid-specific sign that installation completed
is the `ROOT\LIBVIRTUALHID` device and the `\\.\LibVirtualHid` control device. The INF
includes the built-in `WUDFRd` install sections for the root `System` control
device, appends the VHF lower filter, sets `VhfMode=1` for the UMDF VHF source
stack, grants non-admin user-mode clients read/write access to the control
Expand Down
12 changes: 12 additions & 0 deletions cmake/packaging/windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,22 @@ set(LIBVIRTUALHID_DRIVER_TEST_CERTIFICATE "" CACHE FILEPATH
install(FILES
"${PROJECT_SOURCE_DIR}/scripts/windows/libvirtualhid-driver-common.ps1"
"${PROJECT_SOURCE_DIR}/scripts/windows/install-driver.ps1"
"${PROJECT_SOURCE_DIR}/scripts/windows/test-browser-gamepad.ps1"
"${PROJECT_SOURCE_DIR}/scripts/windows/test-installed-driver.ps1"
"${PROJECT_SOURCE_DIR}/scripts/windows/uninstall-driver.ps1"
DESTINATION "scripts/windows"
COMPONENT driver)

if(NOT TARGET gamepad_adapter)
message(FATAL_ERROR
"The Windows driver installer requires BUILD_EXAMPLES=ON so the "
"gamepad_adapter validation tool can be packaged.")
endif()

install(TARGETS gamepad_adapter
RUNTIME DESTINATION "tools/windows"
COMPONENT driver)

if(LIBVIRTUALHID_DRIVER_TEST_CERTIFICATE)
install(FILES "${LIBVIRTUALHID_DRIVER_TEST_CERTIFICATE}"
DESTINATION "certificates"
Expand Down
88 changes: 88 additions & 0 deletions docs/store-review-validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Microsoft Store Review Validation

These instructions are intended for Microsoft Store certification review of the
libvirtualhid Windows driver installer. The reviewer does not need to build the
project, install the Windows SDK/WDK, or write a consumer application.

The Windows package installs a user-mode UMDF/VHF virtual HID driver. The
libvirtualhid-specific driver binary is a UMDF DLL installed through the Windows
Driver Store. It is not a kernel-mode `.sys` driver.

## Submission Notes

Paste this into the Partner Center certification notes field:

```text
This package installs the libvirtualhid Windows user-mode UMDF/VHF virtual HID
driver. It has no standalone end-user UI; applications consume it through the
libvirtualhid client API.

A prebuilt validation tool and PowerShell validation scripts are installed by
the MSI so no programming, SDK setup, or driver build environment is required.
Please install the released, production-signed MSI, then run the validation
commands below from PowerShell.

Default install root:
C:\Program Files\libvirtualhid

Installed validation files:
C:\Program Files\libvirtualhid\scripts\windows\test-installed-driver.ps1
C:\Program Files\libvirtualhid\scripts\windows\test-browser-gamepad.ps1
C:\Program Files\libvirtualhid\tools\windows\gamepad_adapter.exe

Required validation:
$installRoot = Join-Path $env:ProgramFiles "libvirtualhid"
powershell -ExecutionPolicy Bypass -File "$installRoot\scripts\windows\test-installed-driver.ps1" `
-GamepadAdapterPath "$installRoot\tools\windows\gamepad_adapter.exe" `
-GamepadProfile xseries `
-Verbose

Expected result:
- The command exits successfully.
- The ROOT\LIBVIRTUALHID control device reports Status: Started.
- The \\.\LibVirtualHid control device opens successfully.
- A virtual HID gamepad child device starts, matching either
HID\VID_045E&PID_0B12&IG_00 or HID\VID_045E&PID_02FF&IG_00.

Optional browser validation:
$installRoot = Join-Path $env:ProgramFiles "libvirtualhid"
powershell -ExecutionPolicy Bypass -File "$installRoot\scripts\windows\test-browser-gamepad.ps1" `
-GamepadAdapterPath "$installRoot\tools\windows\gamepad_adapter.exe" `
-GamepadProfile xseries `
-KeepBrowserOpen

Expected result:
- Microsoft Edge or Google Chrome opens a gamepad test page.
- The browser Gamepad API sees an Xbox-compatible controller.
- Button and axis values change while the validation adapter is running.

The installed gamepad_adapter.exe is built with the static MSVC runtime, so it
does not require the Visual C++ Redistributable to be installed separately.
```

## Manual Review Steps

1. Install the released, production-signed
`libvirtualhid-Windows-Driver-installer.msi`.
2. Reboot only if Windows reports that a reboot is required.
3. Open PowerShell.
4. Run the required validation command from the submission notes.
5. Optionally run the browser validation command.

If the default install location was changed during MSI installation, replace
`$env:ProgramFiles\libvirtualhid` with the selected install directory.

The MSI writes the driver-install transcript to:

```text
C:\ProgramData\libvirtualhid\install-driver.log
```

## Scope Notes

The `x360` profile is not used for Store review. The Windows UMDF/VHF backend is
HID-only and intentionally does not emulate the Xbox 360 XUSB stack.

The reviewer-visible success signal is the installed `ROOT\LIBVIRTUALHID`
control device, the `\\.\LibVirtualHid` control path, and a started HID gamepad
child device while `gamepad_adapter.exe` is running.
5 changes: 5 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@ target_link_libraries(keyboard_mouse_adapter
PRIVATE
libvirtualhid::libvirtualhid)

if(MSVC AND LIBVIRTUALHID_BUILD_WINDOWS_DRIVER)
set_target_properties(gamepad_adapter keyboard_mouse_adapter PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()

libvirtualhid_copy_mingw_runtime(gamepad_adapter)
libvirtualhid_copy_mingw_runtime(keyboard_mouse_adapter)
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
set_target_properties(${PROJECT_NAME} PROPERTIES
EXPORT_NAME libvirtualhid
OUTPUT_NAME virtualhid)
if(MSVC AND LIBVIRTUALHID_BUILD_WINDOWS_DRIVER)
set_property(TARGET ${PROJECT_NAME} PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()

if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /W4)
Expand Down
Loading