diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a7185c..dd8cb1c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 ` @@ -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 diff --git a/README.md b/README.md index ec98ee1..316cc02 100644 --- a/README.md +++ b/README.md @@ -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 ``` @@ -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 @@ -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 diff --git a/cmake/packaging/windows.cmake b/cmake/packaging/windows.cmake index 197889a..d828f31 100644 --- a/cmake/packaging/windows.cmake +++ b/cmake/packaging/windows.cmake @@ -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" diff --git a/docs/store-review-validation.md b/docs/store-review-validation.md new file mode 100644 index 0000000..14a9a04 --- /dev/null +++ b/docs/store-review-validation.md @@ -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. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b560a9f..a17e05b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -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$<$:Debug>") +endif() + libvirtualhid_copy_mingw_runtime(gamepad_adapter) libvirtualhid_copy_mingw_runtime(keyboard_mouse_adapter) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index acccf7f..ca21f0e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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$<$:Debug>") +endif() if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4)