319 Commits

Author SHA1 Message Date
Benjamin Höglinger-Stelzer
d986e1d937 Update README.md 2023-09-08 22:14:01 +02:00
Benjamin Höglinger-Stelzer
b8ffdcfab9 Updated links 2023-09-08 21:51:30 +02:00
Benjamin Höglinger-Stelzer
79a4294fea Merge branch 'master' of https://github.com/ViGEm/ViGEmBus 2023-07-27 16:05:31 +02:00
Benjamin Höglinger-Stelzer
ede578ea01 Updated URLs 2023-07-27 16:05:20 +02:00
Benjamin Höglinger-Stelzer
b1182d5f04 Update README.md
Added NetJoy
Updated external links
2023-07-27 15:43:05 +02:00
Benjamin Höglinger-Stelzer
22835473d1 Merge pull request #167 from ViGEm/dependabot/github_actions/vedantmgoyal2009/winget-releaser-2
Bump vedantmgoyal2009/winget-releaser from 1 to 2
2023-02-13 12:18:52 +01:00
dependabot[bot]
b002422ec0 Bump vedantmgoyal2009/winget-releaser from 1 to 2
Bumps [vedantmgoyal2009/winget-releaser](https://github.com/vedantmgoyal2009/winget-releaser) from 1 to 2.
- [Release notes](https://github.com/vedantmgoyal2009/winget-releaser/releases)
- [Commits](https://github.com/vedantmgoyal2009/winget-releaser/compare/v1...v2)

---
updated-dependencies:
- dependency-name: vedantmgoyal2009/winget-releaser
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 10:19:09 +00:00
Benjamin Höglinger-Stelzer
68c75bdd0d Merge pull request #161 from ViGEm/dependabot/github_actions/dessant/support-requests-3
Bump dessant/support-requests from 2 to 3
2023-01-24 20:45:05 +01:00
Benjamin Höglinger-Stelzer
8cf6470f98 Update README.md
Replaced Twitter badge with Mastodon
Removed Rainway links
2023-01-11 13:13:49 +01:00
dependabot[bot]
6d83f69f0e Bump dessant/support-requests from 2 to 3
Bumps [dessant/support-requests](https://github.com/dessant/support-requests) from 2 to 3.
- [Release notes](https://github.com/dessant/support-requests/releases)
- [Changelog](https://github.com/dessant/support-requests/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dessant/support-requests/compare/v2...v3)

---
updated-dependencies:
- dependency-name: dessant/support-requests
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-05 09:16:04 +00:00
Benjamin Höglinger-Stelzer
dc1d1de1c5 Merge pull request #142 from sitiom/winget-releaser
Add Winget Releaser workflow
2022-10-24 10:59:52 +02:00
Benjamin Höglinger-Stelzer
a980f37ab7 Further README updates 2022-10-10 19:28:21 +02:00
Benjamin Höglinger-Stelzer
4c0335d52e Updated README 2022-10-10 19:27:08 +02:00
Benjamin Höglinger-Stelzer
e7b53fd366 Updated SDK 2022-10-10 19:21:11 +02:00
Benjamin Höglinger-Stelzer
c16a5a3f2d Updated SDK 2022-10-10 16:35:52 +02:00
Benjamin Höglinger-Stelzer
e3f80e100f Merge pull request #155 from ViGEm/nefarius/feature/compiler-settings
Updated and streamlined compiler settings
2022-10-09 22:06:23 +02:00
Benjamin Höglinger-Stelzer
8ffa5a6d42 Bumped setup version 2022-10-09 22:05:06 +02:00
sitiom
1e53a69a9d Add Dependabot 2022-09-29 20:40:08 +08:00
sitiom
11ab723e6b Update winget.yml 2022-09-29 20:36:21 +08:00
Benjamin Höglinger-Stelzer
fc4e2f0413 Updated setup 2022-08-30 12:47:18 +02:00
Benjamin Höglinger-Stelzer
d2ba1096d4 Unfixed the fix, ugh 2022-08-29 16:42:25 +02:00
Benjamin Höglinger-Stelzer
093fc4aa8d Minor fix 2022-08-29 16:31:12 +02:00
Benjamin Höglinger-Stelzer
f387b3c3c8 Cleaned up appveyor.yml 2022-08-29 16:28:35 +02:00
Benjamin Höglinger-Stelzer
1061feada4 Added git argument to suppress error message 2022-08-29 15:21:46 +02:00
Benjamin Höglinger-Stelzer
fb5424d39c Invalidated build cache 2022-08-29 14:30:21 +02:00
Benjamin Höglinger-Stelzer
91d14b0bfe Fixed conflicting patches 2022-08-29 14:29:12 +02:00
Benjamin Höglinger-Stelzer
e50d4d7915 Set static SDK/WDK version 2022-08-29 11:21:28 +02:00
Benjamin Höglinger-Stelzer
8275e58285 Removed unsupported Windows versions 2022-08-24 20:59:45 +02:00
Benjamin Höglinger-Stelzer
9ad2b37fa7 Updated setup
Updated copyright in resource file
2022-08-24 16:24:37 +02:00
Benjamin Höglinger-Stelzer
beb05ec5e3 Bumped version 2022-08-24 15:01:34 +02:00
Benjamin Höglinger-Stelzer
a70960c29b Updated project compiler settings 2022-08-24 14:23:13 +02:00
Benjamin Höglinger-Stelzer
b613e64d8e Fixed syntax error 2022-08-24 14:07:04 +02:00
Benjamin Höglinger-Stelzer
4ad341e63f Testing alternate compiler settings 2022-08-24 14:04:22 +02:00
Benjamin Höglinger-Stelzer
a67de546bb Updated SDK 2022-08-12 13:08:56 +02:00
Benjamin Höglinger-Stelzer
1236552dc4 Tested vigem_target_ds4_await_output_report_timeout 2022-08-12 12:49:59 +02:00
Benjamin Höglinger-Stelzer
54810aa9cc Updated SDK 2022-08-12 12:39:38 +02:00
Benjamin Höglinger-Stelzer
389218db04 Fixed error in test app 2022-08-12 12:33:28 +02:00
Benjamin Höglinger-Stelzer
dc9ad86b4c Merge remote-tracking branch 'remotes/origin/nefarius/feature/full-ds4-outrep' 2022-08-10 01:14:24 +02:00
Benjamin Höglinger-Stelzer
c3d0ee7283 Fixed setup
Fixed ARM64 INF version stamping
Removed obsolete files
2022-08-10 01:13:29 +02:00
Benjamin Höglinger-Stelzer
63660daf96 Merge pull request #147 from ViGEm/nefarius/feature/full-ds4-outrep
Implements full DS4 output report pass-back
2022-08-08 20:10:28 +02:00
Benjamin Höglinger-Stelzer
a52fbf18be Updated SDK 2022-08-06 20:27:19 +02:00
Benjamin Höglinger-Stelzer
4874c3ba91 Updated SDK 2022-08-06 20:22:37 +02:00
Benjamin Höglinger-Stelzer
0de1ea1a26 Updated SDK 2022-08-06 20:11:40 +02:00
Benjamin Höglinger-Stelzer
87f5365410 Updated SDK 2022-08-06 20:08:27 +02:00
Benjamin Höglinger-Stelzer
9c66a4a36b Updated SDK 2022-08-06 19:52:54 +02:00
Benjamin Höglinger-Stelzer
82502e1033 Updated SDK 2022-08-06 19:30:04 +02:00
Benjamin Höglinger-Stelzer
e022cfad03 Fixed bug in vigem_target_ds4_await_output_report
Added test console app
2022-08-06 19:29:39 +02:00
Benjamin Höglinger-Stelzer
52e232273e Updated SDK 2022-08-06 19:09:42 +02:00
Benjamin Höglinger-Stelzer
5d755baead Added missing logging 2022-08-06 19:02:02 +02:00
Benjamin Höglinger-Stelzer
4607dda9ca SDK update 2022-08-06 18:14:16 +02:00
Benjamin Höglinger-Stelzer
1ccf09c232 Bugfix 2022-08-06 17:41:02 +02:00
Benjamin Höglinger-Stelzer
bd5d07206b Bugfix 2022-08-06 17:10:20 +02:00
Benjamin Höglinger-Stelzer
0a2ff96e0c Bugfixes 2022-08-06 16:46:54 +02:00
Benjamin Höglinger-Stelzer
7d81cf3d76 Implemented new DS4 output report feature 2022-08-06 16:37:45 +02:00
Benjamin Höglinger-Stelzer
11603f6b13 Removed unused code 2022-08-06 13:50:13 +02:00
Benjamin Höglinger-Stelzer
dfac762b0c Updated SDK 2022-08-06 12:47:43 +02:00
Benjamin Höglinger-Stelzer
4332a35f9c Updated SDK 2022-08-06 12:43:09 +02:00
Benjamin Höglinger-Stelzer
770261ddc8 Updated dictionary 2022-08-06 12:29:59 +02:00
Benjamin Höglinger-Stelzer
e391dd09b4 Converted SDK to submodule 2022-08-06 12:26:52 +02:00
Benjamin Höglinger-Stelzer
b41de16d44 Minor fix 2022-08-06 12:19:51 +02:00
Benjamin Höglinger-Stelzer
e18a4cb721 Renamed variable 2022-08-06 12:16:33 +02:00
Benjamin Höglinger-Stelzer
d0052f95a5 Removed obsolete file 2022-08-06 12:10:12 +02:00
Benjamin Höglinger-Stelzer
af3117bd4e Removed crash handler code 2022-08-06 12:07:40 +02:00
Benjamin Höglinger-Stelzer
2842bc6a4f Updated copyright 2022-08-06 11:56:08 +02:00
Benjamin Höglinger-Stelzer
0d0648992f Minor fixes 2022-08-06 11:54:48 +02:00
Benjamin Höglinger-Stelzer
9441b25e0c Added IOCTL_DS4_AWAIT_OUTPUT
Added DMF support to PDO
2022-08-06 11:50:26 +02:00
Benjamin Höglinger-Stelzer
dbe41ff10f Updated README 2022-08-05 16:24:27 +02:00
Benjamin Höglinger-Stelzer
ac42c35816 Merge pull request #146 from ViGEm/refurbishing
Replaced default I/O queue and handlers with DMF equivalents
2022-08-05 16:09:06 +02:00
Benjamin Höglinger-Stelzer
c27138d354 Crash fix 2022-08-05 15:46:46 +02:00
Benjamin Höglinger-Stelzer
3a6d955500 Migrated I/O control handling to DMF 2022-08-05 14:52:28 +02:00
sitiom
84d384ed29 Add Winget Releaser workflow 2022-08-02 17:30:24 +08:00
Benjamin Höglinger-Stelzer
ebc7015315 Working on IOCTL module 2022-08-01 12:41:45 +02:00
Benjamin Höglinger-Stelzer
02354c2dba Replacing queue code with DMF module IOCTL handler 2022-07-13 21:33:56 +02:00
Benjamin Höglinger-Stelzer
59b8f0f8e9 Removed legacy instructions 2022-07-13 19:44:23 +02:00
Benjamin Höglinger-Stelzer
bb681cd29e Fixed missing preprocessor definitions for Single Binary Opt-In: POOL_NX_OPTIN (see https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/single-binary-opt-in-pool-nx-optin) 2022-07-13 19:02:06 +02:00
Benjamin Höglinger-Stelzer
7e9db0dac1 Switched off test signing for ARM64 2022-06-28 19:55:12 +02:00
Benjamin Höglinger-Stelzer
f0c34576dc Added ARM64 to stage0.ps1 2022-06-28 19:16:26 +02:00
Benjamin Höglinger-Stelzer
2d3bd13494 Removed old setup 2022-06-26 16:25:17 +02:00
Benjamin Höglinger-Stelzer
6f03e9c68d Added vpatch tool to build cache 2022-06-26 03:41:54 +02:00
Benjamin Höglinger-Stelzer
31e6b91706 Fixes #131 2022-06-26 03:19:28 +02:00
Benjamin Höglinger-Stelzer
ab8850e2ac Updated badges
Fixed project name
2022-06-26 02:07:56 +02:00
Benjamin Höglinger-Stelzer
0c32f7fc2d Added new setup 2022-06-25 22:52:25 +02:00
Benjamin Höglinger-Stelzer
4e669c3e6b Created ViGEmBus_ARM64.ddf 2022-06-25 22:15:05 +02:00
Benjamin Höglinger-Stelzer
f65bf6b22a More fixes 2022-06-25 19:58:59 +02:00
Benjamin Höglinger-Stelzer
318fe888af Added ARM64 to build script 2022-06-25 19:55:19 +02:00
Benjamin Höglinger-Stelzer
6b02661056 Uncheck some builds 2022-06-25 19:48:17 +02:00
Benjamin Höglinger-Stelzer
1e1191a247 Fixed appveyor.yml 2022-06-25 19:46:23 +02:00
Benjamin Höglinger-Stelzer
b134e6f1de Fixed DMF path 2022-06-25 19:45:33 +02:00
Benjamin Höglinger-Stelzer
1723e0ecd7 Added ARM64 2022-06-25 19:42:26 +02:00
Benjamin Höglinger-Stelzer
c63d68340a Added ARM64 build settings 2022-06-25 19:41:59 +02:00
Benjamin Höglinger-Stelzer
4cbb3357dc Changed DMF build instructions to speed up build 2022-06-25 17:49:05 +02:00
Benjamin Höglinger-Stelzer
efe14cd917 Updated tracing routines 2022-06-25 17:46:52 +02:00
Benjamin Höglinger-Stelzer
6942f17e36 Updated links in README.md 2022-06-25 15:20:24 +02:00
Benjamin Höglinger-Stelzer
ee83bbaa45 Updated to latest nuke 2022-06-25 15:18:14 +02:00
Benjamin Höglinger-Stelzer
83b89dc860 Fixed cache settings 2022-06-24 22:41:48 +02:00
Benjamin Höglinger-Stelzer
fa43acce66 Fixed appveyor.yml 2022-06-24 22:40:20 +02:00
Benjamin Höglinger-Stelzer
735ee2984f Added cache instruction 2022-06-24 22:38:29 +02:00
Benjamin Höglinger-Stelzer
10825759c8 Bumped version 2022-06-24 22:36:34 +02:00
Benjamin Höglinger-Stelzer
53673bda45 Updated to more secure memory allocation function 2022-06-24 22:34:02 +02:00
Benjamin Höglinger-Stelzer
da4b8419f5 Downgraded to WDK for Windows 10, version 2004 2022-06-24 12:36:04 +02:00
Benjamin Höglinger-Stelzer
01b9ebd75e Updated WDK in appveyor.yml 2022-06-24 12:06:48 +02:00
Benjamin Höglinger-Stelzer
a9e7d6b38b Create support.yml 2021-12-31 05:26:18 +01:00
Benjamin Höglinger-Stelzer
7411c4fee3 Typo fix 2021-09-20 11:27:53 +02:00
Benjamin Höglinger-Stelzer
816ebc524f Delete you-need-support.md 2021-08-17 09:40:18 +02:00
Benjamin Höglinger-Stelzer
4316457837 Create config.yml 2021-08-17 09:39:46 +02:00
Benjamin Höglinger-Stelzer
3102c94dfc Create use-this-for-problems-with-the-setup.md 2021-07-05 20:46:54 +02:00
Benjamin Höglinger
442ae3b856 Delete FUNDING.yml 2021-04-06 11:57:03 +02:00
Benjamin Höglinger-Stelzer
41cc4f8398 Merge branch 'master' of github.com:ViGEm/ViGEmBus 2021-01-08 22:16:34 +01:00
Benjamin Höglinger-Stelzer
a33e223774 Fixed build output formatting 2021-01-08 22:16:24 +01:00
Benjamin Höglinger
d24ab69f45 Merge pull request #70 from Filoppi/patch-1
Fix Y touchpad resolution comment
2021-01-07 19:54:03 +01:00
Filippo Tarpini
7d3027c7db Fix Y touchpad resolution comment 2021-01-07 19:24:28 +02:00
Benjamin Höglinger
a1b58be426 Added Windows Server versions to supported systems 2021-01-07 13:44:34 +01:00
Benjamin Höglinger-Stelzer
9fdbe34bac Fix for issue #65 2020-12-22 22:51:46 +01:00
Benjamin Höglinger-Stelzer
346548689d Added devcon binaries compiled with /MT 2020-12-21 16:36:18 +01:00
Benjamin Höglinger-Stelzer
111ff8e170 Added missing README.md 2020-12-17 16:21:54 +01:00
Benjamin Höglinger-Stelzer
c5ecfbdd03 Updated outdated links 2020-12-17 16:20:22 +01:00
Benjamin Höglinger-Stelzer
df39fe6ed3 Minor formatting update 2020-12-17 08:30:12 +01:00
Benjamin Höglinger-Stelzer
2b02e029c1 Updated test signing link 2020-12-17 08:28:41 +01:00
Benjamin Höglinger-Stelzer
dce6de1a6f Corrected version compatibility 2020-12-16 20:46:10 +01:00
Benjamin Höglinger-Stelzer
4ddf7639e3 Added Regame - Cloud Gaming Engine 2020-12-16 20:20:59 +01:00
Benjamin Höglinger-Stelzer
b4980ceb82 Updated build instructions 2020-12-16 20:19:41 +01:00
Benjamin Höglinger-Stelzer
23052bcb67 Fixed broken INF version stamping on release builds 2020-12-14 15:17:11 +01:00
Benjamin Höglinger-Stelzer
6ef839228d Added recursive switch to removal command 2020-12-14 14:12:53 +01:00
Benjamin Höglinger-Stelzer
40aa12d889 Turned off test-signing for release builds 2020-12-04 12:45:58 +01:00
Benjamin Höglinger-Stelzer
b22bb6b665 Removed searching for DLL artifacts 2020-12-04 12:42:57 +01:00
Benjamin Höglinger-Stelzer
8b8ba943b1 Removed co-installer reference from DDF files 2020-12-04 12:29:37 +01:00
Benjamin Höglinger-Stelzer
47a28733cd Removed outdated co-installer reference 2020-12-04 12:21:09 +01:00
Benjamin Höglinger-Stelzer
dc2feda23c Added missing project reference for setup project 2020-12-04 12:13:53 +01:00
Benjamin Höglinger-Stelzer
4001a9990b Fixed paths in setup project 2020-12-04 11:49:42 +01:00
Benjamin Höglinger-Stelzer
5861ea36f3 Added fix for 32-Bit build of DMF 2020-12-04 11:40:33 +01:00
Benjamin Höglinger-Stelzer
f14ba5db9c Added missing git command 2020-12-04 11:24:40 +01:00
Benjamin Höglinger-Stelzer
92e6937633 Updated build procedure to build DMF dependency via nuke 2020-12-04 11:22:08 +01:00
Benjamin Höglinger-Stelzer
2eb8a2e349 Added nuke to support CI build with DMF 2020-12-04 11:07:12 +01:00
Benjamin Höglinger-Stelzer
9f5247fd57 Fixed callback issue with DS4 notification 2020-12-04 10:55:20 +01:00
Benjamin Höglinger-Stelzer
ad1373248d Fixed rumble packet size handling in XUSB devices 2020-11-30 17:39:59 +01:00
Benjamin Höglinger-Stelzer
3fcdec87da Fixed incorrect NTSTATUS values in interrupt processing 2020-11-30 17:18:31 +01:00
Benjamin Höglinger-Stelzer
8567ee21b4 Added some more tracing 2020-11-26 22:11:35 +01:00
Benjamin Höglinger-Stelzer
a958721b44 Removed legacy code 2020-11-26 11:07:21 +01:00
Benjamin Höglinger-Stelzer
16fb8a2bb1 Implemented new queueing in Ds4Pdo.cpp 2020-11-23 23:22:29 +01:00
Benjamin Höglinger-Stelzer
97fd8fd9fa Finished new notification implementation for XusbPdo.cpp 2020-11-23 22:39:41 +01:00
Benjamin Höglinger-Stelzer
c3c4047cfa Implementing new notification logic 2020-11-23 22:23:48 +01:00
Benjamin Höglinger-Stelzer
703842c753 Fixed project file and build settings 2020-11-22 09:46:25 +01:00
Benjamin Höglinger-Stelzer
5d39f31a13 Clean-up 2020-11-21 14:18:10 +01:00
Benjamin Höglinger-Stelzer
a3c05a5aca More clean-up 2020-11-21 14:11:07 +01:00
Benjamin Höglinger-Stelzer
0afae253b8 More include clean-up 2020-11-21 14:08:30 +01:00
Benjamin Höglinger-Stelzer
8f1ddc86db Reworked includes
Added DMF include and library paths
2020-11-21 14:06:43 +01:00
Benjamin Höglinger-Stelzer
1a401ff65b Fixed issue with ViGEm::Bus::Core::EmulationTargetPDO::EnqueueWaitDeviceReady not reporting online children 2020-11-03 17:03:13 +01:00
Benjamin Höglinger-Stelzer
27555457a7 Setup now in-place upgrades from v1.16.x 2020-11-03 14:44:03 +01:00
Benjamin Höglinger-Stelzer
9adbb268ed Added minimal UI to setup 2020-11-03 14:07:30 +01:00
Benjamin Höglinger-Stelzer
a8dc03a661 Updated copyright year to 2020
Signed x86 build of devcon.exe
2020-10-07 22:26:06 +02:00
Benjamin Höglinger-Stelzer
75c007b4c4 Signed devcon binary 2020-10-07 22:20:06 +02:00
Benjamin Höglinger-Stelzer
9692ed6b3d Removed test signature from release builds 2020-10-07 17:22:24 +02:00
Benjamin Höglinger-Stelzer
a434b9a147 Added storing version to registry in setup 2020-10-06 20:13:33 +02:00
Benjamin Höglinger-Stelzer
0e66077ae0 Added Windows version check to MSI 2020-09-24 16:17:40 +02:00
Benjamin Höglinger-Stelzer
39437116fa Added compiled version of https://github.com/microsoft/Windows-driver-samples/tree/master/setup/devcon to comply with MS LICENSE and EULA of WDK redistribution
Added devcon-LICENSE
Updated Product.wxs to include devcon-LICENSE
2020-09-24 15:47:23 +02:00
Benjamin Höglinger-Stelzer
4a7d0f3a9a Added compatibility notes 2020-09-21 17:11:43 +02:00
Benjamin Höglinger-Stelzer
1b9af377d1 Added backwards compatibility error handling to vigem_target_ds4_update_ex 2020-09-21 16:44:14 +02:00
Benjamin Höglinger-Stelzer
d0fbad17d3 Reworked native API for extended DS4 report 2020-09-14 13:59:24 +02:00
Benjamin Höglinger-Stelzer
233b7e0b91 Added testsign back to Release config for CI 2020-09-14 11:30:25 +02:00
Benjamin Höglinger-Stelzer
75a56f347a Typo fix 2020-09-14 10:23:16 +02:00
Benjamin Höglinger-Stelzer
783c123e83 Added architecture to resulting MSI name 2020-09-11 21:28:03 +02:00
Benjamin Höglinger-Stelzer
60830f06ff Adapted setup output path for appveyor 2020-09-11 21:25:17 +02:00
Benjamin Höglinger-Stelzer
b85ef80bed Added AppVeyor support to setup 2020-09-11 21:21:28 +02:00
Benjamin Höglinger-Stelzer
dde3c526a5 Implemented vigem_target_ds4_update_ex 2020-09-10 18:05:26 +02:00
Benjamin Höglinger-Stelzer
f2ce0d1411 Changed download path for patching utility to GitHub release download URL 2020-09-10 16:59:52 +02:00
Benjamin Höglinger-Stelzer
18370652ae Fixed version in appveyor.yml 2020-09-10 16:46:43 +02:00
Benjamin Höglinger-Stelzer
8717bc34ac Added more comments
Added another backwards compatibility fix
2020-09-10 16:44:35 +02:00
Benjamin Höglinger-Stelzer
aa47747738 Disabled x86 build of setup in solution by default to keep CI builds working 2020-09-10 16:02:34 +02:00
Benjamin Höglinger-Stelzer
4a1ae258b5 Set version 2020-09-09 20:40:37 +02:00
Benjamin Höglinger-Stelzer
8b6d977285 Removed unused code 2020-09-09 20:36:46 +02:00
Benjamin Höglinger-Stelzer
09561e6922 Working setup
Updated driver settings to universal model
2020-09-09 20:35:39 +02:00
Benjamin Höglinger-Stelzer
5718b17e7d Added custom actions 2020-09-09 17:19:43 +02:00
Benjamin Höglinger-Stelzer
2c0a3426f2 Added new WiX based setup skeleton 2020-09-09 16:41:08 +02:00
Benjamin Höglinger-Stelzer
751772a856 Added docs 2020-09-07 21:55:05 +02:00
Benjamin Höglinger-Stelzer
929e2abbba Code clean-up 2020-09-07 21:52:29 +02:00
Benjamin Höglinger-Stelzer
5611bbd3fa Implemented new DS4_SUBMIT_REPORT_EX 2020-09-07 21:44:46 +02:00
Benjamin Höglinger-Stelzer
0c920602e7 Added struct _DS4_SUBMIT_REPORT_EX 2020-09-07 18:26:49 +02:00
Benjamin Höglinger-Stelzer
72af14c0ee Doc comment formatting fixes 2020-09-01 18:45:29 +02:00
Benjamin Höglinger-Stelzer
4e57a25f61 De-duplicated code 2020-09-01 15:23:32 +02:00
Benjamin Höglinger-Stelzer
f2f8301ad8 Fixed dangling device if wait call failed 2020-09-01 15:16:17 +02:00
Benjamin Höglinger-Stelzer
4527b0682d Refactored casts 2020-08-30 00:51:34 +02:00
Benjamin Höglinger-Stelzer
040ad7d846 Applied code formatting 2020-08-30 00:49:37 +02:00
Benjamin Höglinger-Stelzer
957cbbed6b De-duplicated code 2020-08-29 17:32:41 +02:00
Benjamin Höglinger-Stelzer
030715d5c3 Redesigned blocking device plugin 2020-08-29 15:52:39 +02:00
Benjamin Höglinger-Stelzer
7864dbabdb Adapted vigem_target_add to use IOCTL_VIGEM_WAIT_DEVICE_READY 2020-08-29 10:30:35 +02:00
Benjamin Höglinger-Stelzer
3841d0756f Added preprocessor switch to disable crash dump handler 2020-08-27 21:02:35 +02:00
Benjamin Höglinger-Stelzer
8618ab50ab Implemented IOCTL_VIGEM_WAIT_DEVICE_READY 2020-08-27 20:44:38 +02:00
Benjamin Höglinger-Stelzer
6b7b3840b1 Removed faulty plugin queueing 2020-08-27 20:33:09 +02:00
Benjamin Höglinger-Stelzer
b347783c43 Renamed some objects for new API 2020-08-27 20:30:12 +02:00
Benjamin Höglinger-Stelzer
6095de206e Added VIGEM_WAIT_DEVICE_READY 2020-08-27 20:17:18 +02:00
Benjamin Höglinger-Stelzer
288222f70f Fixed paths to decouple from solution file location 2020-08-27 19:44:13 +02:00
Benjamin Höglinger-Stelzer
bc520172d6 Added SDK project to solution 2020-08-27 19:40:51 +02:00
Benjamin Höglinger-Stelzer
5abf8e22ad Updated branding in the INF 2020-08-27 19:33:18 +02:00
Benjamin Höglinger-Stelzer
4245394452 Replaced submodule with git subtree usage
Added PnpLockdown=1 to ViGEmBus.inf
2020-08-27 16:41:43 +02:00
Benjamin Höglinger-Stelzer
4af240f54b Add 'sdk/' from commit '18c67764ae7cc9827095eb4e70d75aa52ac8b392'
git-subtree-dir: sdk
git-subtree-mainline: 0dbf810ad0
git-subtree-split: 18c67764ae
2020-08-27 16:39:09 +02:00
Benjamin Höglinger-Stelzer
0dbf810ad0 Removed submodule 2020-08-27 16:38:33 +02:00
Benjamin Höglinger-Stelzer
18c67764ae Removed tester console app 2020-08-24 11:29:02 +02:00
Benjamin Höglinger-Stelzer
ac6bab7eb8 More fixes 2020-08-23 16:18:51 +02:00
Benjamin Höglinger-Stelzer
3659ab648c More fixes 2020-08-23 16:17:50 +02:00
Benjamin Höglinger-Stelzer
f96d826352 Typo fixes 2020-08-23 16:14:39 +02:00
Benjamin Höglinger-Stelzer
88585583ff Added use case of notification callback 2020-08-23 16:10:45 +02:00
Benjamin Höglinger-Stelzer
e293709f94 Bugfix in sample code 2020-08-23 15:00:32 +02:00
Benjamin Höglinger-Stelzer
1e9e45e0ea Added sum docs 2020-08-23 14:56:35 +02:00
Benjamin Höglinger-Stelzer
eda3770917 Forgot to update this stupid file... 2020-06-17 22:43:25 +02:00
Benjamin Höglinger-Stelzer
a49bd54c00 Fixed missing rename 2020-05-23 16:17:46 +02:00
Benjamin Höglinger-Stelzer
9cbd4b65c2 Renamed busenum.h to Driver.h 2020-05-23 16:15:34 +02:00
Benjamin Höglinger-Stelzer
07228b3945 Added <WppKernelMode>true</WppKernelMode> to project file 2020-05-23 15:14:48 +02:00
Benjamin Höglinger-Stelzer
6f898b8053 Added duplicate device check 2020-05-22 21:57:43 +02:00
Benjamin Höglinger-Stelzer
dd74ccb1b8 Removed redundant default callback 2020-05-22 15:44:42 +02:00
Benjamin Höglinger-Stelzer
023e3507dd Updated README.md 2020-05-22 15:30:51 +02:00
Benjamin Höglinger-Stelzer
631003541f Settled on BSD-3-Clause license 2020-05-22 15:26:24 +02:00
Benjamin Höglinger-Stelzer
e5ad15f868 Added https://github.com/Davidobot/BetterJoy 2020-05-21 01:56:42 +02:00
Benjamin Höglinger-Stelzer
2dbf948fdb Removed unnecessary interfaces 2020-05-18 20:18:17 +02:00
Benjamin Höglinger-Stelzer
465736429b Removed XGIP bollocks 2020-05-08 11:28:59 +02:00
Benjamin Höglinger-Stelzer
ce064add9d Removed incomplete Microsoft Xbox One Controller (wired) enum member 2020-05-08 11:15:49 +02:00
Benjamin Höglinger
d466227688 Merge pull request #9 from jpflouret/master
Add user-data paramater to notification callback
2020-04-03 12:28:40 +02:00
JP Flouret
cbb94a3750 Moved user-data to last parameter of notification 2020-04-02 10:26:30 -07:00
JP Flouret
4ad5aa90e1 Add user-data parameter to Tester app 2020-04-01 15:39:55 -07:00
JP Flouret
f09f487a29 Add user-data paramater to notification callback 2020-04-01 15:35:48 -07:00
Benjamin Höglinger-Stelzer
371d9be90f Removed files ported over to own repository (https://github.com/ViGEm/ViGEmClient.vcpkg) 2020-02-17 19:45:59 +01:00
Benjamin Höglinger-Stelzer
971f7acd3d Minor fix in demo app 2020-02-02 17:42:28 +01:00
Benjamin Höglinger-Stelzer
c1283da949 Moved file 2020-02-01 20:44:54 +01:00
Benjamin Höglinger-Stelzer
c47bdc08ac Updated README.md 2020-02-01 20:41:28 +01:00
Benjamin Höglinger-Stelzer
86a781216a Updated appveyor.yml 2020-02-01 20:38:49 +01:00
Benjamin Höglinger-Stelzer
b022025642 Removed nuke
Added rc file
2020-02-01 20:34:41 +01:00
Jason Hart
52682b59c4 Update Licensing 2019-11-14 13:58:13 -05:00
Jason Hart
27516cb05e Fix a missed bug that causes errors when using 'Prefer 32-bit' 2019-11-14 13:18:58 -05:00
Benjamin Höglinger-Stelzer
9d2443ed00 Attempted to fix issue #5
Added basic DS4 test code to tester application
2019-11-14 18:46:02 +01:00
Benjamin Höglinger-Stelzer
20d6d75657 Improved crash dump handler 2019-11-11 21:37:14 +01:00
Benjamin Höglinger-Stelzer
593dc53d8e Fixed build settings for nuke
Added debug symbols to artifacts
2019-11-11 20:52:38 +01:00
Benjamin Höglinger-Stelzer
121a1b7f49 Checked for null parameter in vigem_target_x360_get_user_index
Added error code VIGEM_ERROR_INVALID_PARAMETER
2019-10-02 15:06:42 +02:00
Benjamin Höglinger-Stelzer
3ff5759bba Updated README.md 2019-08-27 15:45:29 -04:00
Benjamin Höglinger-Stelzer
6e597da2d2 Added lib files as build artifacts 2019-08-27 15:15:05 -04:00
Benjamin Höglinger-Stelzer
204b4b1891 Updated copyright information 2019-08-27 15:10:34 -04:00
Benjamin Höglinger-Stelzer
da35120a0f How can this be so broken... 2019-08-27 14:35:58 -04:00
Benjamin Höglinger-Stelzer
8331babf52 How did this ever work... 2019-08-27 14:32:04 -04:00
Benjamin Höglinger-Stelzer
f1086c0b93 Oops 2019-08-27 14:27:33 -04:00
Benjamin Höglinger-Stelzer
0fb762dfe3 Argh 2019-08-27 14:24:55 -04:00
Benjamin Höglinger-Stelzer
c134228cf1 Hopefully fixed stamping 2019-08-27 14:21:29 -04:00
Benjamin Höglinger-Stelzer
b75613cee3 Added GitVersion.CommandLine.DotNetCore 2019-08-27 14:14:23 -04:00
Benjamin Höglinger-Stelzer
4bf9e77e71 Removed GitVersion.CommandLine package 2019-08-27 14:12:13 -04:00
Benjamin Höglinger-Stelzer
ff2fd11726 Updated nuke dependencies
Removed outdated information from README.md
2019-08-27 14:06:48 -04:00
Benjamin Höglinger-Stelzer
7420261dc3 Removed obsolete files
Removed Vcpkg attributes from project file
Removed Vcpkg instructions and cache from appveyor.yml
2019-08-27 10:46:08 -04:00
Benjamin Höglinger
6790fbb40e Merge pull request #7 from mika-n/master
Removed NotificationPool and boost references. Created a new notification thread handler logic
2019-08-27 10:41:23 -04:00
mika-n
0b8756d522 Fine tuned notification background thread logic to make sure that received FFB events are passed on to a callback function in correct order (first-in, first-out). Also, the thread uses a ring buffer to pool IO requests and to make sure that at any time there is always at least one pending IO request ready to receive new FFB events from Vigem kernel driver. 2019-08-27 15:11:50 +03:00
mika-n
02552a5f24 Removed NotificationPool and boost references. Created a new notification thread handler logic, which is simpler and more straight forward than use of BOOST:ASIO library. At the same time fixed a thread cleanup bug in unregister_notification functions (sometimes the old code crashed when a notifications was unregistered. There was some multithread cleanup issue). 2019-08-19 04:12:14 +03:00
Jason Hart
1c1bf44896 Merge pull request #6 from ttsuki/issue/ViGEmClient/fix-NotificationRequestPool
Fixed crash on destructing NotificationRequestPool
2019-08-16 08:06:10 -04:00
ttsuki
ee90cef6ee Fixed crash on destructing NotificationRequestPool 2019-08-02 07:20:19 +09:00
Benjamin Höglinger
5799777c82 Update README.md 2019-07-26 00:16:04 +02:00
Benjamin Höglinger-Stelzer
f6f5e4daae Updated README.md 2019-05-28 21:22:39 +02:00
Benjamin Höglinger-Stelzer
6f616adf5c Fixed x360 notification clean-up 2019-05-28 21:18:33 +02:00
Benjamin Höglinger-Stelzer
267c0cc9d9 Removed unused variables 2019-05-28 21:06:15 +02:00
Benjamin Höglinger-Stelzer
435fa9750b Removed legacy functions 2019-05-28 18:02:41 +02:00
Benjamin Höglinger-Stelzer
0875d8ce38 Refactored code to make it more generic 2019-05-28 18:01:47 +02:00
Benjamin Höglinger-Stelzer
6b371f660b Added license header snippet 2019-05-28 16:44:26 +02:00
Benjamin Höglinger-Stelzer
7f4f579e88 De-cluttered includes 2019-05-28 16:41:52 +02:00
Benjamin Höglinger-Stelzer
fb3b55c5d5 Added cancel through ESC to tester 2019-05-28 15:43:45 +02:00
Benjamin Höglinger-Stelzer
88a325f520 Trying to generalize and tidy up this mess 2019-05-28 15:34:30 +02:00
Benjamin Höglinger-Stelzer
61b482a88a Removed VIGEM_INVERTED_CALL_THREAD_COUNT macro 2019-04-25 17:02:02 +02:00
Benjamin Höglinger-Stelzer
e4d313d8b1 Sylveonification, almost 2019-04-23 21:34:36 +02:00
Benjamin Höglinger-Stelzer
eddb75c0c4 Added comments 2019-04-22 19:14:26 +02:00
Benjamin Höglinger-Stelzer
ca441cf623 Fixed broken tester code 2019-04-22 14:11:06 +02:00
Benjamin Höglinger-Stelzer
ea63179aac Removed deprecated code 2019-04-22 14:08:28 +02:00
Benjamin Höglinger-Stelzer
3408227bb1 It appears to be working 2019-04-22 14:03:14 +02:00
Benjamin Höglinger-Stelzer
3f1286cbc9 No comment 2019-04-22 12:13:45 +02:00
Benjamin Höglinger-Stelzer
9071d6c3af Created class XusbNotificationRequest 2019-04-21 16:57:05 +02:00
Benjamin Höglinger-Stelzer
3acc340aa5 OMG 2019-04-16 20:05:37 +02:00
Benjamin Höglinger-Stelzer
c2d99b1f39 Another typo fix 2019-04-16 18:11:39 +02:00
Benjamin Höglinger-Stelzer
7d8a5248f0 Added tester console application
Typo fixes
Fixed a bug where bus handle wasn't checked correctly
2019-04-16 18:10:50 +02:00
Benjamin Höglinger-Stelzer
005a152323 Added build cache 2019-04-16 16:12:41 +02:00
Benjamin Höglinger-Stelzer
ca5a0c8c0d Redesigned X360 notification callback handling to use Boost ASIO and strands 2019-04-16 16:05:46 +02:00
Benjamin Höglinger-Stelzer
842c5ddd9d More threads! 2019-04-10 21:33:49 +02:00
Benjamin Höglinger-Stelzer
f6d635cde5 Merge branch 'master' into issue/vigembus/13 2019-04-10 21:20:20 +02:00
Benjamin Höglinger-Stelzer
5bf631e8f1 Added crash handler 2019-04-10 21:04:40 +02:00
Benjamin Höglinger-Stelzer
a24657a475 Addressed issue https://github.com/ViGEm/ViGEmBus/issues/13
Typo fixes
Added malloc return value check
2019-03-30 19:17:10 +01:00
Benjamin Höglinger-Stelzer
d315abe867 Fixed crash on 32-bit builds caused by calling convention mismatch 2019-03-27 14:48:06 +01:00
Benjamin Höglinger
47c04ecf40 Merge pull request #1 from bozbez/master
Update Util.h for cmake/vcpkg include directory structure
2018-12-29 10:33:04 +01:00
Benjamin Höglinger-Stelzer
f7a1c245c7 Fixed CLI Debug build complaining about locked DLL 2018-12-27 16:47:25 +01:00
Benjamin Höglinger-Stelzer
19c1a48c79 Added artifact filter 2018-12-26 22:58:15 +01:00
Benjamin Höglinger-Stelzer
ca0a5789f3 Build settings fixes 2018-12-26 22:55:01 +01:00
Benjamin Höglinger-Stelzer
9975c375c5 Fixed DLL not being compiled with static runtime 2018-12-26 22:11:47 +01:00
Joe Kaushal
f24c6b978c Update Util.h for cmake/vcpkg include directory structure 2018-12-07 19:33:50 +00:00
Benjamin Höglinger-Stelzer
000af269d1 Converted umlaut 2018-09-30 20:17:16 +02:00
Benjamin Höglinger-Stelzer
cb3d90f2fc Implemented version stamping in build script 2018-09-29 22:48:18 +02:00
Benjamin Höglinger-Stelzer
bca4337b06 Updated nuke to 0.9.1 2018-09-29 21:43:02 +02:00
Benjamin Höglinger-Stelzer
a9f05423c7 Merge branch 'master' of github.com:ViGEm/ViGEmClient 2018-09-27 16:59:06 +02:00
Benjamin Höglinger-Stelzer
5aa4fabeda Fixed version resource language and other properties 2018-09-27 16:58:52 +02:00
Benjamin Höglinger
2427959f08 Update README.md 2018-09-26 16:30:47 +02:00
Benjamin Höglinger-Stelzer
e8bbbe6e82 Decreased version again to test compatibility 2018-09-23 18:36:26 +02:00
Benjamin Höglinger-Stelzer
5090cba914 Fixed missing include file path 2018-09-23 15:02:35 +02:00
Benjamin Höglinger-Stelzer
bc722fec5f Finished implementation of "vigem_target_x360_get_user_index" 2018-09-23 14:58:25 +02:00
Benjamin Höglinger-Stelzer
a49b1ac113 Updated vcpkg build instructions & version 2018-09-23 12:51:42 +02:00
Benjamin Höglinger-Stelzer
894ccee273 Fixed header include instruction 2018-09-23 12:42:11 +02:00
Benjamin Höglinger-Stelzer
d371928137 Revert "Updated appveyor.yml to use vcpkg"
This reverts commit 5522b8ae32.

# Conflicts:
#	appveyor.yml
2018-09-22 21:36:43 +02:00
Benjamin Höglinger-Stelzer
aa8684ed43 Work pls 2018-09-22 21:24:33 +02:00
Benjamin Höglinger-Stelzer
0684093224 Derp 2018-09-22 21:21:03 +02:00
Benjamin Höglinger-Stelzer
f704b3eb9f Boop 2018-09-22 21:11:50 +02:00
Benjamin Höglinger-Stelzer
b7eff7e771 Test 2018-09-22 21:03:52 +02:00
Benjamin Höglinger-Stelzer
5522b8ae32 Updated appveyor.yml to use vcpkg 2018-09-22 20:48:47 +02:00
Benjamin Höglinger-Stelzer
a7018a373c Added vcpkg ports file 2018-09-22 16:05:28 +02:00
Benjamin Höglinger-Stelzer
c739f8ef90 Refactored include directory structure to comply with cmake/vcpkg 2018-09-22 14:21:04 +02:00
Benjamin Höglinger-Stelzer
9e91a124d1 Forgot to save :) 2018-09-22 13:51:31 +02:00
Benjamin Höglinger-Stelzer
69df51911c Fixed warning LNK4068: /MACHINE not specified; defaulting to X64 2018-09-22 13:47:29 +02:00
Benjamin Höglinger-Stelzer
3579f08f01 Updated nuke to 0.8.0
Excluded build project from solution
2018-09-22 12:44:28 +02:00
Benjamin Höglinger-Stelzer
c3f459704c Added build instructions 2018-09-02 20:12:24 +02:00
Benjamin Höglinger-Stelzer
af43119d7f Corrected runtime library settings 2018-09-02 16:37:09 +02:00
Benjamin Höglinger-Stelzer
7e6ccb7815 Refactored build configuration names
Updated .gitignore
2018-09-02 16:32:43 +02:00
Benjamin Höglinger-Stelzer
c0f72dedcf Corrected resource language to English 2018-08-26 15:58:53 +02:00
Benjamin Höglinger-Stelzer
8bd4ee8669 Added error code VIGEM_ERROR_XUSB_USERINDEX_OUT_OF_RANGE 2018-08-26 14:20:48 +02:00
Benjamin Höglinger-Stelzer
f9e92ca2fd Added error code VIGEM_ERROR_BUS_INVALID_HANDLE
Added some more NULL-pointer checks
Minor refactoring
2018-08-26 14:04:29 +02:00
Benjamin Höglinger-Stelzer
47e28ccd3a Fixed output directory on dynamic build 2018-08-25 23:08:46 +02:00
Benjamin Höglinger-Stelzer
4eec42f32d Fixed include path when referenced as submodule 2018-08-25 23:02:38 +02:00
Benjamin Höglinger-Stelzer
8129b70df7 Corrected title in README.md 2018-08-25 22:46:49 +02:00
Benjamin Höglinger-Stelzer
bd6c370bdc Fixed README.md 2018-08-25 22:45:41 +02:00
Benjamin Höglinger-Stelzer
8601e6a299 Corrected build configuration name 2018-08-25 22:35:30 +02:00
Benjamin Höglinger-Stelzer
c22d46fb1d Fixed appveyor.yml 2018-08-25 22:31:16 +02:00
Benjamin Höglinger-Stelzer
dbe1596398 Fixed solution settings 2018-08-25 22:30:37 +02:00
Benjamin Höglinger-Stelzer
65e2779a1b Fixed build script 2018-08-25 22:30:28 +02:00
Benjamin Höglinger-Stelzer
14011d6794 Ripped client parts out of bus project 2018-08-25 21:28:56 +02:00
59 changed files with 4804 additions and 1744 deletions

2
.github/FUNDING.yml vendored
View File

@@ -1,2 +0,0 @@
patreon: nefarius
custom: ["https://paypal.me/NefariusMaximus"]

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Community support
url: https://docs.nefarius.at/Community-Support/
about: Use these resources for support.
- name: 📖 Documentation
url: https://docs.nefarius.at/projects/
about: Extended documentation about the projects.
- name: ❓ Other issue?
url: https://discord.nefarius.at/
about: See you on Discord.

View File

@@ -0,0 +1,30 @@
---
name: Setup issues
about: Use this if you have problems with the setup
---
## README first
Before you report issues with the setup, make sure to check the following things **first**:
- Are you on anything older than Windows **10**? Windows XP/Vista/7/8/8.1 **are not supported** so don't report this as an issue, it is intentional.
- [Have you chosen the right setup for your CPU architecture?](https://vigem.org/research/How-to-check-architecture/)
- You **can not mix these**, make sure to download and run the correct setup.
- **ARM/ARM64** is **not supported**. See above link to check for yourself.
## I verified all that and am still stuck
Please provide the following **log files** and attach them to the issue. Failing to do so will result in the issue being closed without any further comment.
### Setup log
Run the setup from the command line (either old-school `cmd` or PowerShell) with the following additional arguments: `/L*V .\install.log`
This will generate the log file `install.log` in the same directory the setup resides in. Attach it once the setup is "done" failing.
Last but not least look for `C:\Windows\INF\setupapi.dev.log` and attach it as well.
Optionally compress both files down if it gives you troubles uploading.
Your compliance is appreciated! 😘

View File

@@ -1,7 +0,0 @@
---
name: You need support
about: This is the wrong place to ask for support
---
**Please don't abuse the issue tracker as a helpdesk!** We have a Discord server (linked in the README) where you can ask the lovely like-minded folks for assistance. Thank you for your compliance :smiley:

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

25
.github/workflows/support.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: 'Support Requests'
on:
issues:
types: [labeled, unlabeled, reopened]
permissions:
issues: write
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/support-requests@v3
with:
github-token: ${{ github.token }}
support-label: 'support'
issue-comment: >
:wave: @{issue-author}, we use the issue tracker exclusively
for bug reports and feature requests. However, this issue appears
to be a support request. Please use our support channels
to get help with the project.
close-issue: true
lock-issue: true
issue-lock-reason: 'off-topic'

13
.github/workflows/winget.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: Publish to WinGet
on:
release:
types: [released]
jobs:
publish:
runs-on: windows-latest
steps:
- uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: ViGEm.ViGEmBus
token: ${{ secrets.WINGET_TOKEN }}

7
.gitignore vendored
View File

@@ -361,3 +361,10 @@ FodyWeavers.xsd
/disk1/ViGEmBus_x64.cab
/setup.inf
/setup.rpt
/drivers
/_setup
/setup/Setup Files
/setup/ViGEmBus-cache
/setup/ViGEmBus.back.aip
/sdk
*.aip

4
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "client"]
path = client
[submodule "sdk"]
path = sdk
url = https://github.com/ViGEm/ViGEmClient.git

1
.nuke Normal file
View File

@@ -0,0 +1 @@
ViGEmBus.sln

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"dotnet.defaultSolution": "disable",
"cSpell.words": [
"Gamepads",
"helpdesk"
]
}

42
LICENSE
View File

@@ -1,21 +1,29 @@
MIT License
BSD 3-Clause License
Copyright (c) 2016-2019 Nefarius Software Solutions e.U. and Contributors
Copyright (c) 2016-2020, Nefarius Software Solutions e.U.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -2,16 +2,15 @@
Windows kernel-mode driver emulating well-known USB game controllers.
[![Build status](https://ci.appveyor.com/api/projects/status/rv74ufluwib52dq2?svg=true)](https://ci.appveyor.com/project/nefarius/vigembus) [![Discord](https://img.shields.io/discord/346756263763378176.svg)](https://discord.vigem.org) [![Website](https://img.shields.io/website-up-down-green-red/https/vigem.org.svg?label=ViGEm.org)](https://vigem.org/) [![GitHub followers](https://img.shields.io/github/followers/nefarius.svg?style=social&label=Follow)](https://github.com/nefarius) [![Twitter Follow](https://img.shields.io/twitter/follow/nefariusmaximus.svg?style=social&label=Follow)](https://twitter.com/nefariusmaximus)
[![Build status](https://ci.appveyor.com/api/projects/status/rv74ufluwib52dq2?svg=true)](https://ci.appveyor.com/project/nefarius/vigembus) [![GitHub All Releases](https://img.shields.io/github/downloads/ViGEm/ViGEmBus/total)](https://somsubhra.github.io/github-release-stats/?username=nefarius&repository=ViGEmBus) [![Discord](https://img.shields.io/discord/346756263763378176.svg)](https://discord.nefarius.at) [![Website](https://img.shields.io/website-up-down-green-red/https/vigem.org.svg?label=docs.nefarius.at)](https://docs.nefarius.at/) [![GitHub followers](https://img.shields.io/github/followers/nefarius.svg?style=social&label=Follow)](https://github.com/nefarius) [![Mastodon Follow](https://img.shields.io/mastodon/follow/109321120351128938?domain=https%3A%2F%2Ffosstodon.org%2F&style=social)](https://fosstodon.org/@Nefarius)
<sub>(This project is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using components of ViGEm, please consider reaching out.)</sub>
---
Businesses: support continued development via invoiced technical support, maintenance, sponsoring contracts:
<br>&nbsp;&nbsp;_E-mail: vigem @ nefarius dot at_
## 🧟 THIS PROJECT HAS BEEN RETIRED 🧟
Individuals: support continued maintenance and development via [PayPal](https://paypal.me/NefariusMaximus) donations.
Users of this software are encouraged to [read the end-of-life statement](https://docs.nefarius.at/projects/ViGEm/End-of-Life/). So long, cheers 🖖
----
---
## About
@@ -19,7 +18,7 @@ The `ViGEmBus` driver and `ViGEmClient` libraries represent the core of the Virt
### Emulated devices
Currently supports emulation of the following USB Gamepads:
Emulation of the following USB Gamepads is supported:
- [Microsoft Xbox 360 Controller](https://en.wikipedia.org/wiki/Xbox_360_controller)
- [Sony DualShock 4 Controller](https://en.wikipedia.org/wiki/DualShock#DualShock_4)
@@ -37,15 +36,34 @@ A few examples of the most common use cases for `ViGEm` are:
## Supported Systems
🛑 **Windows Server** might work but is **not supported** 🛑
Bug reports/support requests regarding running on a Server OS will be discarded.
### Version 1.16 and below
The driver is built for Windows 7/8.1/10 (x86 and amd64).
### Version 1.17 and above
The driver is built for Windows 10/11 only (x86, amd64 and ARM64).
## License
The ViGEm Bus Driver is licensed under the **BSD-3-Clause**, see [LICENSE](./LICENSE.md) for more information.
## How to build
[Install Visual Studio 2019 and WDK for Windows 10, version 1903](https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk#wdk-for-windows-10-version-1903).
### Prerequisites
- [Step 1: Install Visual Studio 2019](https://docs.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads#step-1-install-visual-studio)
- [Step 2: Install WDK for Windows 10, version 2004](https://docs.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads#step-2-install-the-wdk)
- [Step 3: Clone the Driver Module Framework (DMF)](https://github.com/microsoft/DMF) into the same parent directory.
- Build the `DmfK` project with Release and Debug configurations for all architectures (x64 and Win32).
You can build directly within Visual Studio.
Do bear in mind that you'll need to **sign** the driver to use it without [test mode](<https://technet.microsoft.com/en-us/ff553484(v=vs.96)>).
Do bear in mind that you'll need to **sign** the driver to use it without [test mode](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/the-testsigning-boot-configuration-option#enable-or-disable-use-of-test-signed-code).
## Contribute
@@ -53,23 +71,22 @@ Do bear in mind that you'll need to **sign** the driver to use it without [test
Found a bug and want it fixed? Open a detailed issue on the [GitHub issue tracker](../../issues)!
Have an idea for a new feature? Let's have a chat about your request on [Discord](https://discord.vigem.org) or the [community forums](https://forums.vigem.org).
Have an idea for a new feature? Let's have a chat about your request on [Discord](https://discord.nefarius.at).
### Questions & Support
Please respect that the GitHub issue tracker isn't a helpdesk. We offer a [Discord server](https://discord.vigem.org) and [forums](https://forums.vigem.org), where you're welcome to check out and engage in discussions!
Please respect that the GitHub issue tracker isn't a helpdesk. We offer a [range of support resources](https://docs.nefarius.at/Community-Support/) you're welcome to check out!
## Installation
To grab the latest signed binaries for use or redistribution [head over to releases](../../releases/latest) and download the latest setup. It will take care of everything.
Pre-built production-signed binaries **for Windows 10/11** are provided by `Nefarius Software Solutions e.U.` [as an all-in-one setup](../../releases/latest).
## Sponsors
Sponsors listed here have helped the project flourish by either financial support or by gifting licenses:
- [3dRudder](https://www.3drudder.com/)
- [Parsec](https://parsecgaming.com/)
- [Rainway, Inc](https://rainway.io/)
- [Parsec](https://parsec.app/)
- [JetBrains](https://www.jetbrains.com/resharper/)
- [Advanced Installer](https://www.advancedinstaller.com/)
- [ICAROS](https://www.icaros.com/)
@@ -81,21 +98,20 @@ A brief listing of projects/companies/vendors known to build upon the powers of
This list is non-exhaustive, if you'd like to see your project included, contact us!
- [3dRudder](https://www.3drudder.com/)
- [Parsec](https://parsecgaming.com/)
- [Parsec](https://parsec.app/)
- [GloSC](https://github.com/Alia5/GloSC)
- [UCR](https://github.com/Snoothy/UCR)
- [InputMapper](https://inputmapper.com/)
- [Oculus VR, LLC.](https://www.oculus.com/)
- [Rainway, Inc](https://rainway.io/)
- [WiimoteHook](https://forum.cemu.info/showthread.php/140-WiimoteHook-Nintendo-Wii-Remote-with-Motion-Rumble-and-Nunchuk-support)
- [XJoy](https://github.com/sam0x17/XJoy)
- [HP](https://www8.hp.com/us/en/campaigns/gamingpcs/overview.html)
- [HP](https://www8.hp.com/us/en/gaming/omen.html)
- [DS4Windows](https://ryochan7.github.io/ds4windows-site/)
- [XOutput](https://github.com/csutorasa/XOutput)
- [RdpGamepad](https://github.com/microsoft/RdpGamepad)
- [Touchmote](https://github.com/Ryochan7/Touchmote/tree/ryochan7)
- [Mi-ViGEm](https://github.com/grayver/mi-vigem)
## License
The `ViGEm` Bus Driver is licensed under the MIT License, see [LICENSE](./LICENSE.md) for more information.
- [BetterJoy](https://github.com/Davidobot/BetterJoy)
- [Regame](https://github.com/ksyun-kenc/liuguang)
- [NetInput](https://github.com/usertoroot/NetInput)
- [NetJoy](https://github.com/Qcent/NetJoy/)

View File

@@ -5,30 +5,183 @@ VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ViGEmBus", "sys\ViGEmBus.vcxproj", "{040101B0-EE5C-4EF1-99EE-9F81C795C001}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SDK", "SDK", "{733360FF-9D9F-4C67-86D1-B20881C17000}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{0182EE0E-A2FB-4525-9FEA-1910B12B21C8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ViGEmClient", "sdk\src\ViGEmClient.vcxproj", "{7DB06674-1F4F-464B-8E1C-172E9587F9DC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "App", "App", "{14E3C232-1A02-49B0-B9CE-4CA2023B7C3D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "app", "app\app.vcxproj", "{74584E9B-2D99-439B-AF9A-27FD10154B33}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_DLL|ARM64 = Debug_DLL|ARM64
Debug_DLL|x64 = Debug_DLL|x64
Debug_DLL|x86 = Debug_DLL|x86
Debug_LIB|ARM64 = Debug_LIB|ARM64
Debug_LIB|x64 = Debug_LIB|x64
Debug_LIB|x86 = Debug_LIB|x86
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release_DLL|ARM64 = Release_DLL|ARM64
Release_DLL|x64 = Release_DLL|x64
Release_DLL|x86 = Release_DLL|x86
Release_LIB|ARM64 = Release_LIB|ARM64
Release_LIB|x64 = Release_LIB|x64
Release_LIB|x86 = Release_LIB|x86
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|ARM64.ActiveCfg = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|ARM64.Build.0 = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|ARM64.Deploy.0 = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|x64.ActiveCfg = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|x64.Build.0 = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|x64.Deploy.0 = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|x86.ActiveCfg = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|x86.Build.0 = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_DLL|x86.Deploy.0 = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|ARM64.ActiveCfg = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|ARM64.Build.0 = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|ARM64.Deploy.0 = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|x64.ActiveCfg = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|x64.Build.0 = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|x64.Deploy.0 = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|x86.ActiveCfg = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|x86.Build.0 = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug_LIB|x86.Deploy.0 = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|ARM64.ActiveCfg = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|ARM64.Build.0 = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|ARM64.Deploy.0 = Debug|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|x64.ActiveCfg = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|x64.Build.0 = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|x64.Deploy.0 = Debug|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|x86.ActiveCfg = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|x86.Build.0 = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug|x86.Deploy.0 = Debug|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|ARM64.ActiveCfg = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|ARM64.Build.0 = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|ARM64.Deploy.0 = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|x64.ActiveCfg = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|x64.Build.0 = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|x64.Deploy.0 = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|x86.ActiveCfg = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|x86.Build.0 = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_DLL|x86.Deploy.0 = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|ARM64.ActiveCfg = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|ARM64.Build.0 = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|ARM64.Deploy.0 = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|x64.ActiveCfg = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|x64.Build.0 = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|x64.Deploy.0 = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|x86.ActiveCfg = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|x86.Build.0 = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release_LIB|x86.Deploy.0 = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|ARM64.ActiveCfg = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|ARM64.Build.0 = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|ARM64.Deploy.0 = Release|ARM64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|x64.ActiveCfg = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|x64.Build.0 = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|x64.Deploy.0 = Release|x64
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|x86.ActiveCfg = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|x86.Build.0 = Release|Win32
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Release|x86.Deploy.0 = Release|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_DLL|ARM64.ActiveCfg = Debug_DLL|ARM64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_DLL|ARM64.Build.0 = Debug_DLL|ARM64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_DLL|x64.ActiveCfg = Debug_DLL|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_DLL|x64.Build.0 = Debug_DLL|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_DLL|x86.ActiveCfg = Debug_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_DLL|x86.Build.0 = Debug_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_LIB|ARM64.ActiveCfg = Debug_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_LIB|ARM64.Build.0 = Debug_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_LIB|x64.ActiveCfg = Debug_LIB|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_LIB|x64.Build.0 = Debug_LIB|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_LIB|x86.ActiveCfg = Debug_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug_LIB|x86.Build.0 = Debug_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug|ARM64.ActiveCfg = Debug_LIB|ARM64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug|ARM64.Build.0 = Debug_LIB|ARM64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug|x64.ActiveCfg = Debug_DLL|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug|x64.Build.0 = Debug_DLL|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug|x86.ActiveCfg = Debug_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Debug|x86.Build.0 = Debug_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_DLL|ARM64.ActiveCfg = Release_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_DLL|ARM64.Build.0 = Release_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_DLL|x64.ActiveCfg = Release_DLL|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_DLL|x64.Build.0 = Release_DLL|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_DLL|x86.ActiveCfg = Release_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_DLL|x86.Build.0 = Release_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_LIB|ARM64.ActiveCfg = Release_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_LIB|ARM64.Build.0 = Release_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_LIB|x64.ActiveCfg = Release_LIB|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_LIB|x64.Build.0 = Release_LIB|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_LIB|x86.ActiveCfg = Release_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release_LIB|x86.Build.0 = Release_LIB|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release|ARM64.ActiveCfg = Release_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release|ARM64.Build.0 = Release_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release|x64.ActiveCfg = Release_LIB|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release|x64.Build.0 = Release_LIB|x64
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release|x86.ActiveCfg = Release_DLL|Win32
{7DB06674-1F4F-464B-8E1C-172E9587F9DC}.Release|x86.Build.0 = Release_DLL|Win32
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug_DLL|ARM64.ActiveCfg = Debug|ARM64
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug_DLL|x64.ActiveCfg = Debug|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug_DLL|x86.ActiveCfg = Debug|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug_LIB|ARM64.ActiveCfg = Debug|ARM64
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug_LIB|x64.ActiveCfg = Debug|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug_LIB|x86.ActiveCfg = Debug|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug|ARM64.ActiveCfg = Debug|ARM64
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug|x64.ActiveCfg = Debug|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Debug|x86.ActiveCfg = Debug|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release_DLL|ARM64.ActiveCfg = Release|ARM64
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release_DLL|x64.ActiveCfg = Release|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release_DLL|x86.ActiveCfg = Release|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release_LIB|ARM64.ActiveCfg = Release|ARM64
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release_LIB|x64.ActiveCfg = Release|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release_LIB|x86.ActiveCfg = Release|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release|ARM64.ActiveCfg = Release|ARM64
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release|x64.ActiveCfg = Release|Any CPU
{C2BA387E-D491-4FB7-8BEE-99D77E8949E7}.Release|x86.ActiveCfg = Release|Any CPU
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_DLL|ARM64.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_DLL|ARM64.Build.0 = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_DLL|x64.ActiveCfg = Debug|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_DLL|x64.Build.0 = Debug|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_DLL|x86.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_DLL|x86.Build.0 = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_LIB|ARM64.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_LIB|ARM64.Build.0 = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_LIB|x64.ActiveCfg = Debug|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_LIB|x64.Build.0 = Debug|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_LIB|x86.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug_LIB|x86.Build.0 = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug|ARM64.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug|x64.ActiveCfg = Debug|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug|x64.Build.0 = Debug|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug|x86.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Debug|x86.Build.0 = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release_DLL|ARM64.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release_DLL|x64.ActiveCfg = Release|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release_DLL|x86.ActiveCfg = Release|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release_LIB|ARM64.ActiveCfg = Debug|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release_LIB|x64.ActiveCfg = Release|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release_LIB|x86.ActiveCfg = Release|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release|ARM64.ActiveCfg = Release|Win32
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release|x64.ActiveCfg = Release|x64
{74584E9B-2D99-439B-AF9A-27FD10154B33}.Release|x86.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{040101B0-EE5C-4EF1-99EE-9F81C795C001} = {0182EE0E-A2FB-4525-9FEA-1910B12B21C8}
{7DB06674-1F4F-464B-8E1C-172E9587F9DC} = {733360FF-9D9F-4C67-86D1-B20881C17000}
{74584E9B-2D99-439B-AF9A-27FD10154B33} = {14E3C232-1A02-49B0-B9CE-4CA2023B7C3D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D5CD61FD-80BB-4E0E-840C-BAF66ABB1CF0}
EndGlobalSection

17
ViGEmBus.sln.DotSettings Normal file
View File

@@ -0,0 +1,17 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=DPAD/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=gamepad/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lightbar/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=megadrago/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NTSTATUS/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PEMULATION/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PPDO/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PVIGEM/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TOUCHPAD/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=unregister/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=USERINDEX/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=VIGEM/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=waitable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=WINAPI/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xbox/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xusb/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

18
ViGEmBus_ARM64.ddf Normal file
View File

@@ -0,0 +1,18 @@
; ViGEmBus cab file for attestation submission
.OPTION EXPLICIT
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0
.Set CompressionType=MSZIP
.Set Cabinet=on
.Set Compress=on
; ARM64
.Set CabinetNameTemplate=ViGEmBus_ARM64.cab
.Set DestinationDir=ViGEmBus_ARM64
LICENSE
bin\ARM64\ViGEmBus.pdb
bin\ARM64\ViGEmBus\ViGEmBus.inf
bin\ARM64\ViGEmBus\ViGEmBus.sys

View File

@@ -15,5 +15,4 @@
LICENSE
bin\x64\ViGEmBus.pdb
bin\x64\ViGEmBus\ViGEmBus.inf
bin\x64\ViGEmBus\ViGEmBus.sys
bin\x64\ViGEmBus\WdfCoinstaller01009.dll
bin\x64\ViGEmBus\ViGEmBus.sys

View File

@@ -15,5 +15,4 @@
LICENSE
bin\x86\ViGEmBus.pdb
bin\x86\ViGEmBus\ViGEmBus.inf
bin\x86\ViGEmBus\ViGEmBus.sys
bin\x86\ViGEmBus\WdfCoinstaller01009.dll
bin\x86\ViGEmBus\ViGEmBus.sys

53
app/app.cpp Normal file
View File

@@ -0,0 +1,53 @@
// app.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#define WIN32_LEAN_AND_MEAN
#include <iomanip>
#include <Windows.h>
#include <ViGEm/Client.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <thread>
#include <bitset>
#pragma comment(lib, "setupapi.lib")
static std::string hexStr(unsigned char* data, int len)
{
std::stringstream ss;
ss << std::hex;
for (int i = 0; i < len; ++i)
ss << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]) << ' ';
return ss.str();
}
int main()
{
const auto client = vigem_alloc();
auto error = vigem_connect(client);
const auto ds4 = vigem_target_ds4_alloc();
error = vigem_target_add(client, ds4);
DS4_OUTPUT_BUFFER out;
while (TRUE)
{
//error = vigem_target_ds4_await_output_report(client, ds4, &out);
error = vigem_target_ds4_await_output_report_timeout(client, ds4, 100, &out);
if (VIGEM_SUCCESS(error))
{
std::cout << hexStr(out.Buffer, sizeof(DS4_OUTPUT_BUFFER)) << std::endl;
}
else if (error != VIGEM_ERROR_TIMED_OUT)
{
auto win32 = GetLastError();
auto t = 0;
}
}
}

160
app/app.vcxproj Normal file
View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{74584e9b-2d99-439b-af9a-27fd10154b33}</ProjectGuid>
<RootNamespace>app</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)sdk\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)sdk\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)sdk\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)sdk\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="app.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sdk\src\ViGEmClient.vcxproj">
<Project>{7db06674-1f4f-464b-8e1c-172e9587f9dc}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

22
app/app.vcxproj.filters Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="app.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -1,24 +1,39 @@
version: 1.17.{build}.0
version: 1.21.{build}.0
image: Visual Studio 2019
skip_commits:
files:
- '**/*.md'
- '**/*.aip'
cache:
- C:\projects\DMF
- C:\projects\ViGEmBus\vpatch.exe
platform:
- x86
- x64
- ARM64
configuration:
- Release
environment:
DmfRootPath: C:\projects\DMF
install:
- cmd: git submodule -q update --init
- cmd: git clone -q https://github.com/microsoft/DMF.git C:\projects\DMF 2> nul || set ERRORLEVEL=0
- cmd: |
cd "C:\projects\DMF"
git pull > NUL
git apply --reject "%APPVEYOR_BUILD_FOLDER%\patches\dmf.diff
cd %appveyor_build_folder%
before_build:
- ps: Invoke-WebRequest "https://downloads.vigem.org/other/nefarius/vpatch/vpatch.exe" -OutFile vpatch.exe
- ps: Invoke-WebRequest "https://github.com/nefarius/vpatch/releases/latest/download/vpatch.exe" -OutFile vpatch.exe
- cmd: vpatch.exe --stamp-version "%APPVEYOR_BUILD_VERSION%" --target-file ".\sys\ViGEmBus.vcxproj" --vcxproj.inf-time-stamp
- cmd: vpatch.exe --stamp-version "%APPVEYOR_BUILD_VERSION%" --target-file ".\sys\ViGEmBus.rc" --resource.file-version --resource.product-version
build:
project: $(APPVEYOR_BUILD_FOLDER)\$(APPVEYOR_PROJECT_NAME).sln
build_script:
- cmd: .\build.cmd
after_build:
- cmd: makecab.exe /f ViGEmBus_%PLATFORM%.ddf
artifacts:
- path: 'bin**\$(APPVEYOR_PROJECT_NAME)\*.inf'
- path: 'bin**\$(APPVEYOR_PROJECT_NAME)\*.sys'
- path: 'bin**\$(APPVEYOR_PROJECT_NAME)\*.dll'
- path: 'bin**\*.pdb'
- path: 'disk1\*.cab'
deploy:

7
build.cmd Executable file
View File

@@ -0,0 +1,7 @@
:; set -eo pipefail
:; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
:; ${SCRIPT_DIR}/build.sh "$@"
:; exit $?
@ECHO OFF
powershell -ExecutionPolicy ByPass -NoProfile %0\..\build.ps1 %*

69
build.ps1 Normal file
View File

@@ -0,0 +1,69 @@
[CmdletBinding()]
Param(
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
[string[]]$BuildArguments
)
Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)"
Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 }
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
###########################################################################
# CONFIGURATION
###########################################################################
$BuildProjectFile = "$PSScriptRoot\build\_build.csproj"
$TempDirectory = "$PSScriptRoot\\.tmp"
$DotNetGlobalFile = "$PSScriptRoot\\global.json"
$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1"
$DotNetChannel = "Current"
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1
$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1
$env:DOTNET_MULTILEVEL_LOOKUP = 0
###########################################################################
# EXECUTION
###########################################################################
function ExecSafe([scriptblock] $cmd) {
& $cmd
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
# If dotnet CLI is installed globally and it matches requested version, use for execution
if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
$(dotnet --version) -and $LASTEXITCODE -eq 0) {
$env:DOTNET_EXE = (Get-Command "dotnet").Path
}
else {
# Download install script
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
# If global.json exists, load expected version
if (Test-Path $DotNetGlobalFile) {
$DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)
if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) {
$DotNetVersion = $DotNetGlobal.sdk.version
}
}
# Install by channel or version
$DotNetDirectory = "$TempDirectory\dotnet-win"
if (!(Test-Path variable:DotNetVersion)) {
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }
} else {
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
}
$env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
}
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }

62
build.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
bash --version 2>&1 | head -n 1
set -eo pipefail
SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
###########################################################################
# CONFIGURATION
###########################################################################
BUILD_PROJECT_FILE="$SCRIPT_DIR/build/_build.csproj"
TEMP_DIRECTORY="$SCRIPT_DIR//.tmp"
DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json"
DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh"
DOTNET_CHANNEL="Current"
export DOTNET_CLI_TELEMETRY_OPTOUT=1
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
export DOTNET_MULTILEVEL_LOOKUP=0
###########################################################################
# EXECUTION
###########################################################################
function FirstJsonValue {
perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}"
}
# If dotnet CLI is installed globally and it matches requested version, use for execution
if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then
export DOTNET_EXE="$(command -v dotnet)"
else
# Download install script
DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh"
mkdir -p "$TEMP_DIRECTORY"
curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL"
chmod +x "$DOTNET_INSTALL_FILE"
# If global.json exists, load expected version
if [[ -f "$DOTNET_GLOBAL_FILE" ]]; then
DOTNET_VERSION=$(FirstJsonValue "version" "$(cat "$DOTNET_GLOBAL_FILE")")
if [[ "$DOTNET_VERSION" == "" ]]; then
unset DOTNET_VERSION
fi
fi
# Install by channel or version
DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
if [[ -z ${DOTNET_VERSION+x} ]]; then
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path
else
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path
fi
export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
fi
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
"$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"

11
build/.editorconfig Normal file
View File

@@ -0,0 +1,11 @@
[*.cs]
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_qualification_for_method = false:warning
dotnet_style_qualification_for_event = false:warning
dotnet_style_require_accessibility_modifiers = never:warning
csharp_style_expression_bodied_methods = true:silent
csharp_style_expression_bodied_properties = true:warning
csharp_style_expression_bodied_indexers = true:warning
csharp_style_expression_bodied_accessors = true:warning

82
build/Build.cs Normal file
View File

@@ -0,0 +1,82 @@
using System;
using System.Linq;
using Nuke.Common;
using Nuke.Common.CI;
using Nuke.Common.CI.AppVeyor;
using Nuke.Common.Execution;
using Nuke.Common.Git;
using Nuke.Common.IO;
using Nuke.Common.ProjectModel;
using Nuke.Common.Tooling;
using Nuke.Common.Tools.MSBuild;
using Nuke.Common.Utilities.Collections;
using static Nuke.Common.EnvironmentInfo;
using static Nuke.Common.IO.FileSystemTasks;
using static Nuke.Common.IO.PathConstruction;
using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
[CheckBuildProjectConfigurations]
class Build : NukeBuild
{
/// Support plugins are available for:
/// - JetBrains ReSharper https://nuke.build/resharper
/// - JetBrains Rider https://nuke.build/rider
/// - Microsoft VisualStudio https://nuke.build/visualstudio
/// - Microsoft VSCode https://nuke.build/vscode
public static int Main () => Execute<Build>(x => x.Compile);
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
[Solution] readonly Solution Solution;
[GitRepository] readonly GitRepository GitRepository;
AbsolutePath DmfSolution => RootDirectory / "../DMF/Dmf.sln";
Target Restore => _ => _
.Executes(() =>
{
MSBuild(s => s
.SetTargetPath(Solution)
.SetTargets("Restore"));
});
Target BuildDmf => _ => _
.Executes(() =>
{
if (IsLocalBuild)
return;
Console.WriteLine($"DMF solution path: {DmfSolution}");
var platform = MSBuildTargetPlatform.x64;
if (AppVeyor.Instance.Platform is "x86")
platform = MSBuildTargetPlatform.Win32;
if (AppVeyor.Instance.Platform is "ARM64")
platform = (MSBuildTargetPlatform) "ARM64";
MSBuild(s => s
.SetTargetPath(DmfSolution)
.SetTargets("Build")
.SetConfiguration(Configuration)
.SetTargetPlatform(platform)
.SetMaxCpuCount(Environment.ProcessorCount)
.SetNodeReuse(IsLocalBuild));
});
Target Compile => _ => _
.DependsOn(BuildDmf)
.Executes(() =>
{
MSBuild(s => s
.SetTargetPath(Solution)
.SetTargets("Rebuild")
.SetConfiguration(Configuration)
.SetMaxCpuCount(Environment.ProcessorCount)
.SetNodeReuse(IsLocalBuild));
});
}

16
build/Configuration.cs Normal file
View File

@@ -0,0 +1,16 @@
using System;
using System.ComponentModel;
using System.Linq;
using Nuke.Common.Tooling;
[TypeConverter(typeof(TypeConverter<Configuration>))]
public class Configuration : Enumeration
{
public static Configuration Debug = new Configuration { Value = nameof(Debug) };
public static Configuration Release = new Configuration { Value = nameof(Release) };
public static implicit operator string(Configuration configuration)
{
return configuration.Value;
}
}

17
build/_build.csproj Normal file
View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace></RootNamespace>
<NoWarn>CS0649;CS0169</NoWarn>
<NukeRootDirectory>..</NukeRootDirectory>
<NukeScriptDirectory>..</NukeScriptDirectory>
<Platforms>AnyCPU;ARM64</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nuke.Common" Version="6.1.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,27 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=HeapView_002EDelegateAllocation/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VariableHidesOuterVariable/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassNeverInstantiated_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_INTERNAL_MODIFIER/@EntryValue">Implicit</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_PRIVATE_MODIFIER/@EntryValue">Implicit</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/METHOD_OR_OPERATOR_BODY/@EntryValue">ExpressionBody</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue">0</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_INVOCATION_LPAR/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ATTRIBUTE_LENGTH_FOR_SAME_LINE/@EntryValue">120</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">IF_OWNER_IS_SINGLE_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

1
client

Submodule client deleted from 465736429b

3
drivers/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Drivers directory
Place the attestation signed driver files into the corresponding sub-directories and locally build the setup and sign it afterwards for production release.

23
drivers/devcon-LICENSE Normal file
View File

@@ -0,0 +1,23 @@
The Microsoft Public License (MS-PL)
Copyright (c) 2015 Microsoft
This license governs use of the accompanying software. If you use the software, you
accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.

647
patches/dmf.diff Normal file
View File

@@ -0,0 +1,647 @@
Dmf/Solution/DmfK/DmfK.vcxproj | 28 +++++++++++++++++-----
Dmf/Solution/DmfKFramework/DmfKFramework.vcxproj | 28 +++++++++++++++++-----
.../DmfKModules.Library.vcxproj | 28 +++++++++++++++++-----
.../DmfKModules.Template.vcxproj | 28 +++++++++++++++++-----
Dmf/Solution/DmfU/DmfU.vcxproj | 18 +++++++++++++-
Dmf/Solution/DmfUFramework/DmfUFramework.vcxproj | 28 +++++++++++++++++-----
.../DmfUModules.Library.vcxproj | 28 +++++++++++++++++-----
.../DmfUModules.Template.vcxproj | 24 +++++++++++++++----
8 files changed, 169 insertions(+), 41 deletions(-)
diff --git a/Dmf/Solution/DmfK/DmfK.vcxproj b/Dmf/Solution/DmfK/DmfK.vcxproj
index 738397c..de0b165 100644
--- a/Dmf/Solution/DmfK/DmfK.vcxproj
+++ b/Dmf/Solution/DmfK/DmfK.vcxproj
@@ -44,37 +44,37 @@
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@@ -110,6 +110,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -139,6 +142,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -169,6 +175,8 @@
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -199,6 +207,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -228,6 +239,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -258,6 +272,8 @@
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
diff --git a/Dmf/Solution/DmfKFramework/DmfKFramework.vcxproj b/Dmf/Solution/DmfKFramework/DmfKFramework.vcxproj
index 13d2475..b2d481c 100644
--- a/Dmf/Solution/DmfKFramework/DmfKFramework.vcxproj
+++ b/Dmf/Solution/DmfKFramework/DmfKFramework.vcxproj
@@ -80,37 +80,37 @@
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@@ -147,6 +147,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -174,6 +177,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -202,6 +208,8 @@
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -230,6 +238,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -257,6 +268,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -285,6 +299,8 @@
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
diff --git a/Dmf/Solution/DmfKModules.Library/DmfKModules.Library.vcxproj b/Dmf/Solution/DmfKModules.Library/DmfKModules.Library.vcxproj
index 1ba20c5..ec7dbed 100644
--- a/Dmf/Solution/DmfKModules.Library/DmfKModules.Library.vcxproj
+++ b/Dmf/Solution/DmfKModules.Library/DmfKModules.Library.vcxproj
@@ -167,37 +167,37 @@
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@@ -234,6 +234,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -263,6 +266,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -293,6 +299,8 @@
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -323,6 +331,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -352,6 +363,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -382,6 +396,8 @@
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
diff --git a/Dmf/Solution/DmfKModules.Template/DmfKModules.Template.vcxproj b/Dmf/Solution/DmfKModules.Template/DmfKModules.Template.vcxproj
index 0d0ef4c..ce1f791 100644
--- a/Dmf/Solution/DmfKModules.Template/DmfKModules.Template.vcxproj
+++ b/Dmf/Solution/DmfKModules.Template/DmfKModules.Template.vcxproj
@@ -44,13 +44,13 @@
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@@ -84,6 +84,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -108,6 +111,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -132,13 +138,15 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
- <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'" >/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;cfgmgr32.lib;wpprecorder.lib;</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
- <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'" >/guard:delayloadsignret %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/guard:delayloadsignret %(AdditionalOptions)</AdditionalOptions>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
@@ -158,6 +166,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -182,6 +193,9 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -206,13 +220,15 @@
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<WppRecorderEnabled>true</WppRecorderEnabled>
- <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'" >/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;cfgmgr32.lib;wpprecorder.lib;</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
- <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'" >/guard:delayloadsignret %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/guard:delayloadsignret %(AdditionalOptions)</AdditionalOptions>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
diff --git a/Dmf/Solution/DmfU/DmfU.vcxproj b/Dmf/Solution/DmfU/DmfU.vcxproj
index 9b9dd48..521b273 100644
--- a/Dmf/Solution/DmfU/DmfU.vcxproj
+++ b/Dmf/Solution/DmfU/DmfU.vcxproj
@@ -46,7 +46,7 @@
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
<UseDebugLibraries Condition="'$(Configuration)'=='Release'">False</UseDebugLibraries>
<UseDebugLibraries Condition="'$(Configuration)'=='Debug'">True</UseDebugLibraries>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@@ -83,6 +83,22 @@
<WppFileExtensions>.c.C.cpp.CPP.h.H</WppFileExtensions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..;</AdditionalIncludeDirectories>
<WppRecorderEnabled>true</WppRecorderEnabled>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</WholeProgramOptimization>
</ClCompile>
<ClCompile Condition="'$(Platform)'=='ARM64'">
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
diff --git a/Dmf/Solution/DmfUFramework/DmfUFramework.vcxproj b/Dmf/Solution/DmfUFramework/DmfUFramework.vcxproj
index 7ba02d9..cc174c6 100644
--- a/Dmf/Solution/DmfUFramework/DmfUFramework.vcxproj
+++ b/Dmf/Solution/DmfUFramework/DmfUFramework.vcxproj
@@ -45,32 +45,32 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@@ -125,6 +125,22 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories);..\..\Framework;..\..\Framework\Modules.Core</AdditionalIncludeDirectories>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppEnabled>true</WppEnabled>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</WholeProgramOptimization>
</ClCompile>
<ClCompile Condition="'$(Platform)'=='ARM64'">
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
diff --git a/Dmf/Solution/DmfUModules.Library/DmfUModules.Library.vcxproj b/Dmf/Solution/DmfUModules.Library/DmfUModules.Library.vcxproj
index 214e8bb..d863a9b 100644
--- a/Dmf/Solution/DmfUModules.Library/DmfUModules.Library.vcxproj
+++ b/Dmf/Solution/DmfUModules.Library/DmfUModules.Library.vcxproj
@@ -45,32 +45,32 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@@ -141,6 +141,22 @@
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|x64'">stdcpp17</LanguageStandard>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</WholeProgramOptimization>
</ClCompile>
<ClCompile Condition="'$(Platform)'=='ARM64'">
<AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
diff --git a/Dmf/Solution/DmfUModules.Template/DmfUModules.Template.vcxproj b/Dmf/Solution/DmfUModules.Template/DmfUModules.Template.vcxproj
index 7c285cc..436bf4f 100644
--- a/Dmf/Solution/DmfUModules.Template/DmfUModules.Template.vcxproj
+++ b/Dmf/Solution/DmfUModules.Template/DmfUModules.Template.vcxproj
@@ -45,12 +45,12 @@
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
- <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
@@ -84,9 +84,25 @@
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppEnabled>true</WppEnabled>
<LanguageStandard>stdcpp17</LanguageStandard>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Speed</FavorSizeOrSpeed>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</WholeProgramOptimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Speed</FavorSizeOrSpeed>
+ <WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</WholeProgramOptimization>
</ClCompile>
<ClCompile Condition="'$(Platform)'=='ARM64'">
- <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'" >/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/d2guardsignret %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);hid.lib;setupapi.lib;cfgmgr32.lib;</AdditionalDependencies>
@@ -94,7 +110,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Platform)'=='ARM64'">
<Link>
- <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'" >/guard:delayloadsignret %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(_NT_TARGET_VERSION)'=='$(_NT_TARGET_VERSION_WIN10_CO)'">/guard:delayloadsignret %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

1
sdk Submodule

Submodule sdk added at cb8c9f4787

BIN
setup/LICENSE.rtf Normal file

Binary file not shown.

BIN
setup/ViGEm.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

357
setup/ViGEmBus.aip Normal file
View File

@@ -0,0 +1,357 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DOCUMENT Type="Advanced Installer" CreateVersion="19.5" version="20.6" Modules="enterprise" RootPath="." Language="en_GB" Id="{AF87FF38-9FCC-4C1C-9EB0-FFD1F6AE0A13}">
<COMPONENT cid="caphyon.advinst.msicomp.ProjectOptionsComponent">
<ROW Name="HiddenItems" Value="ActSyncAppComponent;CPLAppletComponent;AutorunComponent;GameUxComponent;SilverlightSlnComponent;SharePointSlnComponent;AppXAppDetailsComponent;FixupComponent;AppXCapabilitiesComponent;AppXDependenciesComponent;AppXProductDetailsComponent;AppXVisualAssetsComponent;AppXAppDeclarationsComponent;AppXUriRulesComponent;MsiXDiffComponent;MsixManifestEditorComponent"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
<ROW Property="AI_FINDEXE_TITLE" Value="Select the installation package for [|ProductName]" ValueLocId="AI.Property.FindExeTitle"/>
<ROW Property="ALLUSERS" Value="1"/>
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/>
<ROW Property="ARPHELPLINK" Value="https://vigem.org/projects/ViGEm/"/>
<ROW Property="ARPNOMODIFY" MultiBuildValue="DefaultBuild:1"/>
<ROW Property="ARPNOREPAIR" Value="1" MultiBuildValue="DefaultBuild:1"/>
<ROW Property="ARPPRODUCTICON" Value="ViGEm.exe" Type="8"/>
<ROW Property="ARPURLINFOABOUT" Value="https://vigem.org/Community-Support/"/>
<ROW Property="ARPURLUPDATEINFO" Value="https://github.com/ViGEm/ViGEmBus/releases"/>
<ROW Property="AiLicenseAgreementLink" Value="https://github.com/ViGEm/ViGEmBus/blob/master/LICENSE" Type="4"/>
<ROW Property="IAgree" Value="No" Type="4"/>
<ROW Property="Manufacturer" Value="Nefarius Software Solutions e.U."/>
<ROW Property="ProductCode" Value="2057:{9C581C76-2D68-40F8-AA6F-94D3C5215C05} " Type="16"/>
<ROW Property="ProductLanguage" Value="1033"/>
<ROW Property="ProductName" Value="ViGEm Bus Driver"/>
<ROW Property="ProductVersion" Value="1.21.442"/>
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND;AI_SETUPEXEPATH;SETUPEXEDIR;UPGRADE_1"/>
<ROW Property="UpgradeCode" Value="{67175F6C-AA18-43A7-AE60-2FC3FD10BF79}"/>
<ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
<ROW Property="WindowsType9XDisplay" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
<ROW Property="WindowsTypeNT" MultiBuildValue="DefaultBuild:Windows Vista x86, Windows Server 2008 x86, Windows 7 x86, Windows 8 x86, Windows 8.1 x86" ValueLocId="-"/>
<ROW Property="WindowsTypeNT40" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
<ROW Property="WindowsTypeNT40Display" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
<ROW Property="WindowsTypeNT50" MultiBuildValue="DefaultBuild:Windows 2000" ValueLocId="-"/>
<ROW Property="WindowsTypeNT50Display" MultiBuildValue="DefaultBuild:Windows 2000" ValueLocId="-"/>
<ROW Property="WindowsTypeNT5X" MultiBuildValue="DefaultBuild:Windows XP/2003" ValueLocId="-"/>
<ROW Property="WindowsTypeNT5XDisplay" MultiBuildValue="DefaultBuild:Windows XP/2003" ValueLocId="-"/>
<ROW Property="WindowsTypeNT64" MultiBuildValue="DefaultBuild:Windows Vista x64, Windows Server 2008 x64, Windows 7 x64, Windows Server 2008 R2 x64, Windows 8 x64, Windows Server 2012 x64, Windows 8.1 x64, Windows Server 2012 R2 x64, Windows Server x64" ValueLocId="-"/>
<ROW Property="WindowsTypeNT64Display" MultiBuildValue="DefaultBuild:Windows Vista x64, Windows Server 2008 x64, Windows 7 x64, Windows Server 2008 R2 x64, Windows 8 x64, Windows Server 2012 x64, Windows 8.1 x64, Windows Server 2012 R2 x64, Windows Server x64" ValueLocId="-"/>
<ROW Property="WindowsTypeNTDisplay" MultiBuildValue="DefaultBuild:Windows Vista x86, Windows Server 2008 x86, Windows 7 x86, Windows 8 x86, Windows 8.1 x86" ValueLocId="-"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
<ROW Directory="AI_Bin32_Dir" Directory_Parent="APPDIR" DefaultDir="32-bit"/>
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
<ROW Directory="ARM64_Dir" Directory_Parent="APPDIR" DefaultDir="ARM64"/>
<ROW Directory="SHORTCUTDIR" Directory_Parent="TARGETDIR" DefaultDir="SHORTC~1|SHORTCUTDIR" IsPseudoRoot="1"/>
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
<ROW Component="AI_ExePath" ComponentId="{756493E7-566A-49DE-8EC3-07AE9D1BD9C4}" Directory_="APPDIR" Attributes="4" KeyPath="AI_ExePath"/>
<ROW Component="APPDIR" ComponentId="{947691BF-6B7F-4A14-9027-3E1ECF87784A}" Directory_="APPDIR" Attributes="0"/>
<ROW Component="LICENSE" ComponentId="{60476948-DBD4-4515-B1B1-6EECCB99AE99}" Directory_="ARM64_Dir" Attributes="0" KeyPath="LICENSE_2" Type="0"/>
<ROW Component="ProductInformation" ComponentId="{E2F0A6FF-AB27-4BBA-AF65-9D70B244A328}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
<ROW Component="ViGEmBus.inf" ComponentId="{E79736E3-4F2D-4E11-9BED-7A17521333E7}" Directory_="ARM64_Dir" Attributes="0" Condition="AiArm64" KeyPath="ViGEmBus.inf_2"/>
<ROW Component="ViGEmBus.pdb" ComponentId="{965D6CDE-0142-4A0F-90B8-12D3322333BF}" Directory_="APPDIR" Attributes="0" KeyPath="ViGEmBus.pdb" Type="4"/>
<ROW Component="ViGEmBus.pdb_2" ComponentId="{58BB969A-1902-4F8A-AFCF-F4950E272E7C}" Directory_="ARM64_Dir" Attributes="0" KeyPath="ViGEmBus.pdb_2" Type="4"/>
<ROW Component="ViGEmBus.pdb_3" ComponentId="{EFCC2160-8010-43A3-B5A8-7C09A83C208B}" Directory_="AI_Bin32_Dir" Attributes="0" KeyPath="ViGEmBus.pdb_3" Type="4"/>
<ROW Component="ViGEmBus.sys" ComponentId="{DA974243-DAFB-49CF-8693-FF51C234CBD5}" Directory_="APPDIR" Attributes="256" Condition="VersionNT64 AND NOT AiArm64" KeyPath="ViGEmBus.sys" Type="0"/>
<ROW Component="nefconw.exe" ComponentId="{AEADABD6-0FA7-4BF5-A3F5-1043F5D911F9}" Directory_="APPDIR" Attributes="256" Condition="VersionNT64 AND NOT AiArm64" KeyPath="nefconw.exe"/>
<ROW Component="nefconw.exe_1" ComponentId="{E0BCC5D1-4762-490A-AD7E-9A36C8DF724C}" Directory_="AI_Bin32_Dir" Attributes="0" Condition="NOT VersionNT64 AND NOT AiArm64" KeyPath="nefconw.exe_1"/>
<ROW Component="nefconw.exe_2" ComponentId="{B25A0000-3F39-43D0-95F8-4B804DAB3DE5}" Directory_="ARM64_Dir" Attributes="256" Condition="AiArm64" KeyPath="nefconw.exe_2"/>
<ROW Component="updater.exe" ComponentId="{08EB2B6D-47C1-4EED-8A5C-FF31B6F28651}" Directory_="APPDIR" Attributes="0" KeyPath="updater.exe"/>
<ROW Component="vigembus.cat" ComponentId="{CEA011F4-933A-459C-B951-B1BC17E4E671}" Directory_="AI_Bin32_Dir" Attributes="0" Condition="NOT VersionNT64 AND NOT AiArm64" KeyPath="vigembus.cat_1" Type="0"/>
<ROW Component="vigembus.cat_1" ComponentId="{300845F0-6D4A-4954-A8BC-93B4345FCD3E}" Directory_="ARM64_Dir" Attributes="0" Condition="AiArm64" KeyPath="ViGEmBus.sys_2" Type="0"/>
<ROW Component="vigembus.cat_2" ComponentId="{E0F5FE8D-4431-42DE-B766-8E05D53D2672}" Directory_="ARM64_Dir" Attributes="0" Condition="AiArm64" KeyPath="vigembus.cat_2"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
<ROW Feature="AI32BitFiles" Title="32-bit" Description="32-bit Executables and Libraries" Display="5" Level="1" Directory_="APPDIR" Attributes="0"/>
<ROW Feature="AI64BitFiles" Title="64-bit" Description="64-bit Executables and Libraries" Display="3" Level="1" Directory_="APPDIR" Attributes="0"/>
<ROW Feature="ARM64" Title="ARM64" Description="ARM64" Display="7" Level="1" Directory_="APPDIR" Attributes="0"/>
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0"/>
<ATTRIBUTE name="CurrentFeature" value="ARM64"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
<ROW File="nefconw.exe" Component_="nefconw.exe" FileName="nefconw.exe" Attributes="0" SourcePath="..\drivers\x64\nefconw.exe" SelfReg="false"/>
<ROW File="ViGEmBus.sys" Component_="ViGEmBus.sys" FileName="ViGEmBus.sys" Attributes="0" SourcePath="..\drivers\x64\ViGEmBus.sys" SelfReg="false"/>
<ROW File="vigembus.cat" Component_="ViGEmBus.sys" FileName="vigembus.cat" Attributes="0" SourcePath="..\drivers\x64\vigembus.cat" SelfReg="false"/>
<ROW File="ViGEmBus.inf" Component_="ViGEmBus.sys" FileName="ViGEmBus.inf" Attributes="0" SourcePath="..\drivers\x64\ViGEmBus.inf" SelfReg="false"/>
<ROW File="LICENSE" Component_="ViGEmBus.sys" FileName="LICENSE" Attributes="0" SourcePath="..\drivers\x64\LICENSE" SelfReg="false"/>
<ROW File="nefconw.exe_1" Component_="nefconw.exe_1" FileName="nefconw.exe" Attributes="0" SourcePath="..\drivers\x86\nefconw.exe" SelfReg="false"/>
<ROW File="vigembus.cat_1" Component_="vigembus.cat" FileName="vigembus.cat" Attributes="0" SourcePath="..\drivers\x86\vigembus.cat" SelfReg="false"/>
<ROW File="ViGEmBus.inf_1" Component_="vigembus.cat" FileName="ViGEmBus.inf" Attributes="0" SourcePath="..\drivers\x86\ViGEmBus.inf" SelfReg="false"/>
<ROW File="ViGEmBus.sys_1" Component_="vigembus.cat" FileName="ViGEmBus.sys" Attributes="0" SourcePath="..\drivers\x86\ViGEmBus.sys" SelfReg="false"/>
<ROW File="LICENSE_1" Component_="vigembus.cat" FileName="LICENSE" Attributes="0" SourcePath="..\drivers\x86\LICENSE" SelfReg="false"/>
<ROW File="updater.exe" Component_="updater.exe" FileName="VIGEMB~1.EXE|ViGEmBus_Updater.exe" Version="65535.65535.65535.65535" Attributes="0" SourcePath="&lt;AI_STUBS&gt;updater.exe" SelfReg="false" DigSign="true"/>
<ROW File="nefconw.exe_2" Component_="nefconw.exe_2" FileName="nefconw.exe" Attributes="0" SourcePath="..\drivers\arm64\nefconw.exe" SelfReg="false"/>
<ROW File="vigembus.cat_2" Component_="vigembus.cat_2" FileName="vigembus.cat" Attributes="0" SourcePath="..\drivers\arm64\vigembus.cat" SelfReg="false"/>
<ROW File="ViGEmBus.inf_2" Component_="ViGEmBus.inf" FileName="ViGEmBus.inf" Attributes="0" SourcePath="..\drivers\arm64\ViGEmBus.inf" SelfReg="false"/>
<ROW File="ViGEmBus.sys_2" Component_="vigembus.cat_1" FileName="ViGEmBus.sys" Attributes="0" SourcePath="..\drivers\arm64\ViGEmBus.sys" SelfReg="false"/>
<ROW File="LICENSE_2" Component_="LICENSE" FileName="LICENSE" Attributes="0" SourcePath="..\drivers\arm64\LICENSE" SelfReg="false"/>
<ROW File="ViGEmBus.pdb_2" Component_="ViGEmBus.pdb_2" FileName="ViGEmBus.pdb" Attributes="0" SourcePath="..\artifacts\bin\arm64\ViGEmBus.pdb" SelfReg="false"/>
<ROW File="ViGEmBus.pdb_3" Component_="ViGEmBus.pdb_3" FileName="ViGEmBus.pdb" Attributes="0" SourcePath="..\artifacts\bin\x86\ViGEmBus.pdb" SelfReg="false"/>
<ROW File="ViGEmBus.pdb" Component_="ViGEmBus.pdb" FileName="ViGEmBus.pdb" Attributes="0" SourcePath="..\artifacts\bin\x64\ViGEmBus.pdb" SelfReg="false"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.BootstrOptComponent">
<ROW BootstrOptKey="GlobalOptions" DownloadFolder="[AppDataFolder][|Manufacturer]\[|ProductName]\prerequisites" Options="2"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="Setup Files" Languages="en_GB" InstallationType="2" CabsLocation="1" CompressCabs="false" UseLzma="true" LzmaMethod="2" LzmaCompressionLevel="4" PackageType="1" FilesInsideExe="true" ExeIconPath="ViGEm.ico" ExtractionFolder="[CommonAppDataFolder]Nefarius Software Solutions\[|ProductName] [|ProductVersion]\install" ExtUI="true" UseLargeSchema="true" ExeName="ViGEmBus_[|ProductVersion]_x64_x86_arm64" MsiPackageType="AI_ALL"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
<ROW Path="&lt;AI_DICTS&gt;ui.ail"/>
<ROW Path="&lt;AI_DICTS&gt;ui_en_GB.ail"/>
<ROW Path="&lt;AI_DICTS&gt;ui_en.ail"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.DigCertStoreComponent">
<ROW TimeStampUrl="http://timestamp.digicert.com" SignerDescription="[|ProductName]" SignOptions="7" SignTool="0" UseSha256="1" Thumbprint="f88a20d1f8f87c188c7b7d65a1f897332b26cae6 Subject: Nefarius Software Solutions e.U.&#10;Issuer: DigiCert Global G3 Code Signing ECC SHA384 2021 CA1&#10;Valid from 11/25/2021 to 02/13/2025&#10;User\MY" Subject="CN=Nefarius Software Solutions e.U., O=Nefarius Software Solutions e.U., L=Wels, C=AT, SERIALNUMBER=505039f, OID.1.3.6.1.4.1.311.60.2.1.1=Wels, OID.1.3.6.1.4.1.311.60.2.1.2=Oberösterreich, OID.1.3.6.1.4.1.311.60.2.1.3=AT, OID.2.5.4.15=Private Organization"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
<ROW Fragment="CommonUI.aip" Path="&lt;AI_FRAGS&gt;CommonUI.aip"/>
<ROW Fragment="InstallDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\InstallDlg.aip"/>
<ROW Fragment="LicenseAgreementDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\LicenseAgreementDlg.aip"/>
<ROW Fragment="MaintenanceTypeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\MaintenanceTypeDlg.aip"/>
<ROW Fragment="MaintenanceWelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\MaintenanceWelcomeDlg.aip"/>
<ROW Fragment="SequenceDialogs.aip" Path="&lt;AI_THEMES&gt;classic\fragments\SequenceDialogs.aip"/>
<ROW Fragment="Sequences.aip" Path="&lt;AI_FRAGS&gt;Sequences.aip"/>
<ROW Fragment="StaticUIStrings.aip" Path="&lt;AI_FRAGS&gt;StaticUIStrings.aip"/>
<ROW Fragment="Themes.aip" Path="&lt;AI_FRAGS&gt;Themes.aip"/>
<ROW Fragment="UI.aip" Path="&lt;AI_THEMES&gt;classic\fragments\UI.aip"/>
<ROW Fragment="Validation.aip" Path="&lt;AI_FRAGS&gt;Validation.aip"/>
<ROW Fragment="VerifyRemoveDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\VerifyRemoveDlg.aip"/>
<ROW Fragment="VerifyRepairDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\VerifyRepairDlg.aip"/>
<ROW Fragment="WelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\WelcomeDlg.aip"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
<ROW Action="AI_DeleteLzma" Description="Deleting files extracted from archive" DescriptionLocId="ActionText.Description.AI_DeleteLzma" TemplateLocId="-"/>
<ROW Action="AI_DeleteRLzma" Description="Deleting files extracted from archive" DescriptionLocId="ActionText.Description.AI_DeleteLzma" TemplateLocId="-"/>
<ROW Action="AI_ExtractFiles" Description="Extracting files from archive" DescriptionLocId="ActionText.Description.AI_ExtractLzma" TemplateLocId="-"/>
<ROW Action="AI_ExtractLzma" Description="Extracting files from archive" DescriptionLocId="ActionText.Description.AI_ExtractLzma" TemplateLocId="-"/>
<ROW Action="AI_ProcessTasks2" Description="Generating actions to schedule tasks on the local computer:" DescriptionLocId="ActionText.Description.AI_ProcessTasks" Template="Task Name: [1]" TemplateLocId="ActionText.Template.AI_ProcessTasks"/>
<ROW Action="AI_RemoveTasks2" Description="Removing scheduled task from the local computer" DescriptionLocId="ActionText.Description.AI_RemoveTasks" Template="Task Name: [1]" TemplateLocId="ActionText.Template.AI_RemoveTasks"/>
<ROW Action="AI_RollbackTasks2" Description="Rolling back scheduled task on the local computer" DescriptionLocId="ActionText.Description.AI_RollbackTasks" Template="Task Name: [1]" TemplateLocId="ActionText.Template.AI_RollbackTasks"/>
<ROW Action="AI_ScheduleTasks2" Description="Schedule task on the local computer" DescriptionLocId="ActionText.Description.AI_ScheduleTasks" Template="Task Name: [1]" TemplateLocId="ActionText.Template.AI_ScheduleTasks"/>
<ROW Action="AI_UninstallTasks2" Description="Generating actions to remove scheduled tasks from the local computer:" DescriptionLocId="ActionText.Description.AI_UninstallTasks"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiAppSearchComponent">
<ROW Property="AI_SETUPEXEPATH" Signature_="AI_EXE_PATH_LM" Builds="DefaultBuild"/>
<ROW Property="AI_SETUPEXEPATH" Signature_="AI_EXE_PATH_CU" Builds="DefaultBuild"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
<ROW Name="Prereq.dll" SourcePath="&lt;AI_CUSTACTS&gt;Prereq.dll"/>
<ROW Name="aicustact.dll" SourcePath="&lt;AI_CUSTACTS&gt;aicustact.dll"/>
<ROW Name="aischeduler2.dll" SourcePath="&lt;AI_CUSTACTS&gt;aischeduler2.dll"/>
<ROW Name="lzmaextractor.dll" SourcePath="&lt;AI_CUSTACTS&gt;lzmaextractor.dll"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiConditionComponent">
<ROW Feature_="AI64BitFiles" Level="0" Condition="NOT VersionNT64 OR AiArm64"/>
<ROW Feature_="AI32BitFiles" Level="0" Condition="VersionNT64 OR AiArm64"/>
<ROW Feature_="ARM64" Level="0" Condition="NOT AiArm64"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlComponent">
<ROW Dialog_="LicenseAgreementDlg" Control="AgreementText" Type="ScrollableText" X="20" Y="60" Width="330" Height="120" Attributes="7" Order="400" TextLocId="Control.Text.LicenseAgreementDlg#AgreementText" MsiKey="LicenseAgreementDlg#AgreementText"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="NewDialog" Argument="InstallDlg" Condition="AI_INSTALL" Ordering="1"/>
<ROW Dialog_="MaintenanceWelcomeDlg" Control_="Next" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="99"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_MAINT" Ordering="198"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="203"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="197"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="InstallDlg" Condition="AI_INSTALL" Ordering="201"/>
<ROW Dialog_="CustomizeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_MAINT" Ordering="101"/>
<ROW Dialog_="CustomizeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="1"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="ChangeButton" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="501"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceWelcomeDlg" Condition="AI_MAINT" Ordering="1"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="RemoveButton" Event="NewDialog" Argument="VerifyRemoveDlg" Condition="AI_MAINT AND InstallMode=&quot;Remove&quot;" Ordering="601"/>
<ROW Dialog_="VerifyRemoveDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode=&quot;Remove&quot;" Ordering="1"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="RepairButton" Event="NewDialog" Argument="VerifyRepairDlg" Condition="AI_MAINT AND InstallMode=&quot;Repair&quot;" Ordering="601"/>
<ROW Dialog_="VerifyRepairDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode=&quot;Repair&quot;" Ordering="1"/>
<ROW Dialog_="VerifyRepairDlg" Control_="Repair" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode=&quot;Repair&quot;" Ordering="399" Options="1"/>
<ROW Dialog_="VerifyRemoveDlg" Control_="Remove" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode=&quot;Remove&quot;" Ordering="299" Options="1"/>
<ROW Dialog_="PatchWelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_PATCH" Ordering="201"/>
<ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="204"/>
<ROW Dialog_="InstallDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_INSTALL" Ordering="201"/>
<ROW Dialog_="InstallDlg" Control_="Back" Event="NewDialog" Argument="WelcomeDlg" Condition="AI_INSTALL" Ordering="1"/>
<ROW Dialog_="InstallDlg" Control_="Hyperlink" Event="NewDialog" Argument="LicenseAgreementDlg" Condition="AI_INSTALL AND ReadLicense" Ordering="201"/>
<ROW Dialog_="LicenseAgreementDlg" Control_="Back" Event="NewDialog" Argument="InstallDlg" Condition="AI_INSTALL AND ReadLicense" Ordering="1"/>
<ROW Dialog_="LicenseAgreementDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_INSTALL AND ReadLicense" Ordering="1"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="LicenseAgreementDlg" Condition="AI_INSTALL AND ReadLicense" Ordering="202"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCreateFolderComponent">
<ROW Directory_="APPDIR" Component_="APPDIR" ManualDelete="true"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH_ORIGINAL" Target="[AI_SETUPEXEPATH]"/>
<ROW Action="AI_DATA_SETTER" Type="51" Source="CustomActionData" Target="[AI_SETUPEXEPATH]"/>
<ROW Action="AI_DOWNGRADE" Type="19" Target="4010"/>
<ROW Action="AI_DeleteCadLzma" Type="51" Source="AI_DeleteLzma" Target="[AI_SETUPEXEPATH]"/>
<ROW Action="AI_DeleteLzma" Type="1025" Source="lzmaextractor.dll" Target="DeleteLZMAFiles"/>
<ROW Action="AI_DeleteRCadLzma" Type="51" Source="AI_DeleteRLzma" Target="[AI_SETUPEXEPATH]"/>
<ROW Action="AI_DeleteRLzma" Type="1281" Source="lzmaextractor.dll" Target="DeleteLZMAFiles"/>
<ROW Action="AI_DpiContentScale" Type="1" Source="aicustact.dll" Target="DpiContentScale"/>
<ROW Action="AI_EnableDebugLog" Type="321" Source="aicustact.dll" Target="EnableDebugLog"/>
<ROW Action="AI_ExtractCadLzma" Type="51" Source="AI_ExtractLzma" Target="[AI_SETUPEXEPATH]"/>
<ROW Action="AI_ExtractFiles" Type="1" Source="Prereq.dll" Target="ExtractSourceFiles" AdditionalSeq="AI_DATA_SETTER"/>
<ROW Action="AI_ExtractLzma" Type="1025" Source="lzmaextractor.dll" Target="ExtractLZMAFiles"/>
<ROW Action="AI_FindExeLzma" Type="1" Source="lzmaextractor.dll" Target="FindEXE"/>
<ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/>
<ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/>
<ROW Action="AI_PRESERVE_INSTALL_TYPE" Type="65" Source="aicustact.dll" Target="PreserveInstallType"/>
<ROW Action="AI_ProcessTasks2" Type="1" Source="aischeduler2.dll" Target="ProcessTasks"/>
<ROW Action="AI_REDIRECT_32BIT_FOLDER" Type="51" Source="AI_Bin32_Dir" Target="[APPDIR]"/>
<ROW Action="AI_REDIRECT_32BIT_SH_FOLDER" Type="51" Source="AI_Sh32_Dir" Target="[SHORTCUTDIR]"/>
<ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH" Target="[AI_SETUPEXEPATH_ORIGINAL]"/>
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
<ROW Action="AI_RemoveTasks2" Type="11265" Source="aischeduler2.dll" Target="DeleteTasks" WithoutSeq="true"/>
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
<ROW Action="AI_RollbackTasks2" Type="11521" Source="aischeduler2.dll" Target="DeleteTasks" WithoutSeq="true"/>
<ROW Action="AI_SETPROGRAMFILES" Type="51" Source="AI_ProgramFiles" Target="[ProgramFilesFolder]"/>
<ROW Action="AI_SETPROGRAMFILES64" Type="51" Source="AI_ProgramFiles" Target="[ProgramFiles64Folder]"/>
<ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/>
<ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/>
<ROW Action="AI_ScheduleTasks2" Type="11265" Source="aischeduler2.dll" Target="ScheduleTasks" WithoutSeq="true"/>
<ROW Action="AI_UPDATER_UNINSTALL" Type="82" Source="updater.exe" Target="/clean silent"/>
<ROW Action="AI_UninstallTasks2" Type="1" Source="aischeduler2.dll" Target="UninstallTasks"/>
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[AI_ProgramFiles]Nefarius Software Solutions\[ProductName]"/>
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
<ROW Action="arm64_AddDeviceNode" Type="1106" Source="nefconw.exe_2" Target="--create-device-node --hardware-id Nefarius\ViGEmBus\Gen1 --class-name System --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="arm64_InstallDriver" Type="1106" Source="nefconw.exe_2" Target="--install-driver --inf-path &quot;[#ViGEmBus.inf_2]&quot;"/>
<ROW Action="arm64_UninstallDevice" Type="1106" Source="nefconw.exe_2" Target="--remove-device-node --hardware-id Nefarius\ViGEmBus\Gen1 --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="arm64_UninstallDriver" Type="1106" Source="nefconw.exe_2" Target="--uninstall-driver --inf-path &quot;[#ViGEmBus.inf]&quot;"/>
<ROW Action="x64_AddDeviceNode" Type="1106" Source="nefconw.exe" Target="--create-device-node --hardware-id Nefarius\ViGEmBus\Gen1 --class-name System --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="x64_InstallDriver" Type="1106" Source="nefconw.exe" Target="--install-driver --inf-path &quot;[#ViGEmBus.inf]&quot;"/>
<ROW Action="x64_UninstallDevice" Type="1106" Source="nefconw.exe" Target="--remove-device-node --hardware-id Nefarius\ViGEmBus\Gen1 --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="x64_UninstallDevice_Old" Type="1106" Source="nefconw.exe" Target="--remove-device-node --hardware-id Root\ViGEmBus --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="x64_UninstallDriver" Type="1106" Source="nefconw.exe" Target="--uninstall-driver --inf-path &quot;[#ViGEmBus.inf]&quot;"/>
<ROW Action="x86_AddDeviceNode" Type="1106" Source="nefconw.exe_1" Target="--create-device-node --hardware-id Nefarius\ViGEmBus\Gen1 --class-name System --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="x86_InstallDriver" Type="1106" Source="nefconw.exe_1" Target="--install-driver --inf-path &quot;[#ViGEmBus.inf_1]&quot;"/>
<ROW Action="x86_UninstallDevice" Type="1106" Source="nefconw.exe_1" Target="--remove-device-node --hardware-id Nefarius\ViGEmBus\Gen1 --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="x86_UninstallDevice_Old" Type="1106" Source="nefconw.exe_1" Target="--remove-device-node --hardware-id Root\ViGEmBus --class-guid 4D36E97D-E325-11CE-BFC1-08002BE10318"/>
<ROW Action="x86_UninstallDriver" Type="1106" Source="nefconw.exe_1" Target="--uninstall-driver --inf-path &quot;[#ViGEmBus.inf]&quot;"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatCompsComponent">
<ROW Feature_="MainFeature" Component_="APPDIR"/>
<ROW Feature_="MainFeature" Component_="ProductInformation"/>
<ROW Feature_="MainFeature" Component_="AI_ExePath"/>
<ROW Feature_="AI64BitFiles" Component_="nefconw.exe"/>
<ROW Feature_="AI64BitFiles" Component_="ViGEmBus.sys"/>
<ROW Feature_="AI32BitFiles" Component_="nefconw.exe_1"/>
<ROW Feature_="AI32BitFiles" Component_="vigembus.cat"/>
<ROW Feature_="MainFeature" Component_="updater.exe"/>
<ROW Feature_="ARM64" Component_="nefconw.exe_2"/>
<ROW Feature_="ARM64" Component_="vigembus.cat_2"/>
<ROW Feature_="ARM64" Component_="ViGEmBus.inf"/>
<ROW Feature_="ARM64" Component_="vigembus.cat_1"/>
<ROW Feature_="ARM64" Component_="LICENSE"/>
<ROW Feature_="ARM64" Component_="ViGEmBus.pdb_2"/>
<ROW Feature_="AI32BitFiles" Component_="ViGEmBus.pdb_3"/>
<ROW Feature_="AI64BitFiles" Component_="ViGEmBus.pdb"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
<ROW Name="ViGEm.exe" SourcePath="ViGEm.ico" Index="0"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiIniFileComponent">
<ROW IniFile="AppDir" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="AppDir" Value="[APPDIR]" Action="0" Component_="updater.exe"/>
<ROW IniFile="ApplicationName" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="ApplicationName" Value="[ProductName]" Action="0" Component_="updater.exe"/>
<ROW IniFile="ApplicationVersion" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="ApplicationVersion" Value="[ProductVersion]" Action="0" Component_="updater.exe"/>
<ROW IniFile="CheckFrequency" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="CheckFrequency" Value="2" Action="0" Component_="updater.exe"/>
<ROW IniFile="CompanyName" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="CompanyName" Value="[Manufacturer]" Action="0" Component_="updater.exe"/>
<ROW IniFile="DefaultCommandLine" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="DefaultCommandLine" Value="/checknow" Action="0" Component_="updater.exe"/>
<ROW IniFile="DownloadsFolder" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="DownloadsFolder" Value="[CommonAppDataFolder][Manufacturer]\[ProductName]\updates\" Action="0" Component_="updater.exe"/>
<ROW IniFile="Flags" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="Flags" Value="PerMachine|ShowConfigOptionsButton" Action="0" Component_="updater.exe"/>
<ROW IniFile="ID" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="ID" Value="[UpgradeCode]" Action="0" Component_="updater.exe"/>
<ROW IniFile="URL" FileName="VIGEMB~1.INI|ViGEmBus_Updater.ini" DirProperty="APPDIR" Section="General" Key="URL" Value="https://updates.vigem.org/api/github/ViGEm/ViGEmBus/updates" Action="0" Component_="updater.exe"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel &lt;&gt; 5)" Sequence="210"/>
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="747"/>
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1510"/>
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE=&quot;No&quot; AND (Not Installed)" Sequence="1397"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
<ROW Action="AI_EnableDebugLog" Sequence="51"/>
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Sequence="99" Builds="DefaultBuild"/>
<ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Condition="AI_SETUPEXEPATH_ORIGINAL" Sequence="101" Builds="DefaultBuild"/>
<ROW Action="AI_DeleteCadLzma" Condition="SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)" Sequence="199" Builds="DefaultBuild"/>
<ROW Action="AI_DeleteRCadLzma" Condition="SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)" Sequence="198" Builds="DefaultBuild"/>
<ROW Action="AI_ExtractCadLzma" Condition="SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)" Sequence="197" Builds="DefaultBuild"/>
<ROW Action="AI_FindExeLzma" Condition="SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)" Sequence="196" Builds="DefaultBuild"/>
<ROW Action="AI_ExtractLzma" Condition="SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)" Sequence="1549" Builds="DefaultBuild"/>
<ROW Action="AI_DeleteRLzma" Condition="SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)" Sequence="1548" Builds="DefaultBuild"/>
<ROW Action="AI_DeleteLzma" Condition="SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)" Sequence="6599" Builds="DefaultBuild"/>
<ROW Action="AI_ExtractFiles" Sequence="1399" Builds="DefaultBuild"/>
<ROW Action="AI_DATA_SETTER" Sequence="1398"/>
<ROW Action="AI_REDIRECT_32BIT_FOLDER" Condition="NOT VersionNT64 AND NOT AI_Disable32BitRedirection" Sequence="798"/>
<ROW Action="AI_REDIRECT_32BIT_SH_FOLDER" Condition="NOT VersionNT64 AND NOT AI_Disable32BitRedirection" Sequence="799"/>
<ROW Action="AI_SETPROGRAMFILES64" Condition="VersionNT64" Sequence="748"/>
<ROW Action="AI_SETPROGRAMFILES" Condition="NOT VersionNT64" Sequence="749"/>
<ROW Action="AI_UPDATER_UNINSTALL" Condition="($updater.exe = 2) AND (?updater.exe = 3) AND NOT (UPGRADINGPRODUCTCODE)" Sequence="1551"/>
<ROW Action="AI_ProcessTasks2" Condition="(VersionNT &gt;= 600) AND (REMOVE&lt;&gt;&quot;ALL&quot;)" Sequence="1624"/>
<ROW Action="AI_UninstallTasks2" Condition="(VersionNT &gt;= 600) AND (REMOVE=&quot;ALL&quot;)" Sequence="1699"/>
<ROW Action="ForceReboot" Condition="AI_UPGRADE&lt;&gt;&quot;No&quot; AND OLDPRODUCTS AND AFTERREBOOT&lt;&gt;1" Sequence="1501" SeqType="0"/>
<ROW Action="x64_AddDeviceNode" Condition="( NOT Installed ) AND ( VersionNT64 AND NOT AiArm64 )" Sequence="6401"/>
<ROW Action="x64_InstallDriver" Condition="( NOT Installed ) AND ( VersionNT64 AND NOT AiArm64 )" Sequence="6404"/>
<ROW Action="x64_UninstallDevice_Old" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( VersionNT64 AND NOT AiArm64 )" Sequence="1502"/>
<ROW Action="x64_UninstallDevice" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( VersionNT64 AND NOT AiArm64 )" Sequence="1504"/>
<ROW Action="x64_UninstallDriver" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( VersionNT64 AND NOT AiArm64 )" Sequence="1507"/>
<ROW Action="x86_UninstallDevice_Old" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( NOT VersionNT64 AND NOT AiArm64 )" Sequence="1503"/>
<ROW Action="x86_UninstallDevice" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( NOT VersionNT64 AND NOT AiArm64 )" Sequence="1505"/>
<ROW Action="x86_UninstallDriver" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( NOT VersionNT64 AND NOT AiArm64 )" Sequence="1508"/>
<ROW Action="x86_AddDeviceNode" Condition="( NOT Installed ) AND ( NOT VersionNT64 AND NOT AiArm64 )" Sequence="6402"/>
<ROW Action="x86_InstallDriver" Condition="( NOT Installed ) AND ( NOT VersionNT64 AND NOT AiArm64 )" Sequence="6405"/>
<ROW Action="arm64_AddDeviceNode" Condition="( NOT Installed ) AND ( AiArm64 )" Sequence="6403"/>
<ROW Action="arm64_InstallDriver" Condition="( NOT Installed ) AND ( AiArm64 )" Sequence="6406"/>
<ROW Action="arm64_UninstallDevice" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( AiArm64 )" Sequence="1506"/>
<ROW Action="arm64_UninstallDriver" Condition="( ( NOT Installed ) OR ( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) ) ) AND ( AiArm64 )" Sequence="1509"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="747"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
<ROW Action="AI_DpiContentScale" Sequence="52"/>
<ROW Action="AI_EnableDebugLog" Sequence="51"/>
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Sequence="99"/>
<ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Condition="AI_SETUPEXEPATH_ORIGINAL" Sequence="101"/>
<ROW Action="AI_SETPROGRAMFILES64" Condition="VersionNT64" Sequence="748"/>
<ROW Action="AI_SETPROGRAMFILES" Condition="NOT VersionNT64" Sequence="749"/>
<ROW Action="AI_PRESERVE_INSTALL_TYPE" Sequence="199"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
<ROW Condition="( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 &lt;&gt; 600) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 600) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 602) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 602) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 603) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 603) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 1000) OR (MsiNTProductType = 1)) ) )" Description="[ProductName] can not be installed on the following Windows versions: [WindowsTypeNT64Display]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT64" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="( Version9X OR VersionNT64 OR ( VersionNT AND ((VersionNT &lt;&gt; 600) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT &lt;&gt; 600) OR (MsiNTProductType = 1)) AND (VersionNT &lt;&gt; 601) AND (VersionNT &lt;&gt; 602) AND (VersionNT &lt;&gt; 603) ) )" Description="[ProductName] can not be installed on the following Windows versions: [WindowsTypeNTDisplay]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="((VersionNT &lt;&gt; 501) AND (VersionNT &lt;&gt; 502))" Description="[ProductName] cannot be installed on [WindowsTypeNT5XDisplay]." DescriptionLocId="AI.LaunchCondition.NoNT5X" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="(VersionNT &lt;&gt; 400)" Description="[ProductName] can not be installed on [WindowsTypeNT40Display]." DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="(VersionNT &lt;&gt; 500)" Description="[ProductName] can not be installed on [WindowsTypeNT50Display]." DescriptionLocId="AI.LaunchCondition.NoNT50" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="SETUPEXEDIR OR (REMOVE=&quot;ALL&quot;)" Description="This package can only be run from a bootstrapper." DescriptionLocId="AI.LaunchCondition.RequireBootstrapper" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="VersionNT" Description="[ProductName] can not be installed on [WindowsType9XDisplay]." DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegLocatorComponent">
<ROW Signature_="AI_EXE_PATH_CU" Root="1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="AI_ExePath" Type="2"/>
<ROW Signature_="AI_EXE_PATH_LM" Root="2" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="AI_ExePath" Type="2"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
<ROW Registry="AI_ExePath" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="AI_ExePath" Value="[AI_SETUPEXEPATH]" Component_="AI_ExePath"/>
<ROW Registry="AdvancedInstaller" Root="-1" Key="Software\Caphyon\Advanced Installer" Name="\"/>
<ROW Registry="Caphyon" Root="-1" Key="Software\Caphyon" Name="\"/>
<ROW Registry="LZMA" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA" Name="\"/>
<ROW Registry="Manufacturer" Root="-1" Key="Software\[Manufacturer]" Name="\"/>
<ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
<ROW Registry="ProductCode" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]" Name="\"/>
<ROW Registry="ProductName" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="\"/>
<ROW Registry="ProductVersion" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="\"/>
<ROW Registry="Software" Root="-1" Key="Software" Name="\"/>
<ROW Registry="Version" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
<ATTRIBUTE name="UsedTheme" value="classic"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiUpgradeComponent">
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="0.0.1" VersionMax="[|ProductVersion]" Attributes="257" ActionProperty="OLDPRODUCTS"/>
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/>
<ROW UpgradeCode="{0A4A02DE-0BE3-4BF4-91F0-1EA47AD26881}" VersionMax="1.17.333.0" Attributes="1541" ActionProperty="UPGRADE_1"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.ScheduledTasksComponent">
<ROW TaskId="AI_ViGEmBus_Updater" TaskName="ViGEmBus_Updater" Run="[#updater.exe]" CmdLine="/silent" WorkDir="[APPDIR]" UserProp="[%UserDomain]\[LogonUser]" Flags="24576" Trigger="1|1|1|1|0|0|0||20480|0|0" Settings="2|4320" Condition="1" TaskVersion="2.0"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.UpdaterComponent">
<ROW Updater="updater.exe" URL="URL" SearchFreq="CheckFrequency" DownloadsFolder="DownloadsFolder" ID="ID" TargetDir="AppDir" AppName="ApplicationName" AppVersion="ApplicationVersion" CompanyName="CompanyName" DefCommandLine="DefaultCommandLine" Flags="Flags" IconPath="ViGEm.ico" IconIndex="0" UnistallCASeq="AI_UPDATER_UNINSTALL" TaskId="AI_ViGEmBus_Updater" Description="[|UpdaterName] [|ProductVersion]"/>
</COMPONENT>
</DOCUMENT>

127
stage0.ps1 Normal file
View File

@@ -0,0 +1,127 @@
Param(
[Parameter(Mandatory=$true)]
[string]$BuildVersion,
[Parameter(Mandatory=$true)]
[string]$Token,
[Parameter(Mandatory=$false)]
[string]$Path = "./artifacts",
[Parameter(Mandatory=$false)]
[Switch]$NoSigning
) #end param
$signTool = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe"
$timestampUrl = "http://timestamp.digicert.com"
$certName = "Nefarius Software Solutions e.U."
function Get-AppVeyorArtifacts
{
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
param(
#The name of the account you wish to download artifacts from
[parameter(Mandatory = $true)]
[string]$Account,
#The name of the project you wish to download artifacts from
[parameter(Mandatory = $true)]
[string]$Project,
#Where to save the downloaded artifacts. Defaults to current directory.
[alias("DownloadDirectory")][string]$Path = '.',
[string]$Token,
#Filter to a specific branch or project directory. You can specify Branch as either branch name ("master") or build version ("0.1.29")
[string]$Branch,
#If you have multiple build jobs, specify which job you wish to retrieve the artifacts from
[string]$JobName,
#Download all files into a single directory, do not preserve any hierarchy that might exist in the artifacts
[switch]$Flat,
[string]$Proxy,
[switch]$ProxyUseDefaultCredentials,
#URL of Appveyor API. You normally shouldn't need to change this.
$apiUrl = 'https://ci.appveyor.com/api'
)
$headers = @{
'Content-type' = 'application/json'
}
if ($Token) {$headers.'Authorization' = "Bearer $token"}
# Prepare proxy args to splat to Invoke-RestMethod
$proxyArgs = @{}
if (-not [string]::IsNullOrEmpty($proxy)) {
$proxyArgs.Add('Proxy', $proxy)
}
if ($proxyUseDefaultCredentials.IsPresent) {
$proxyArgs.Add('ProxyUseDefaultCredentials', $proxyUseDefaultCredentials)
}
$errorActionPreference = 'Stop'
$projectURI = "$apiUrl/projects/$account/$project"
if ($Branch) {$projectURI = $projectURI + "/build/$Branch"}
$projectObject = Invoke-RestMethod -Method Get -Uri $projectURI `
-Headers $headers @proxyArgs
if (-not $projectObject.build.jobs) {throw "No jobs found for this project or the project and/or account name was incorrectly specified"}
if (($projectObject.build.jobs.count -gt 1) -and -not $jobName) {
throw "Multiple Jobs found for the latest build. Please specify the -JobName paramter to select which job you want the artifacts for"
}
if ($JobName) {
$jobid = ($projectObject.build.jobs | Where-Object name -eq "$JobName" | Select-Object -first 1).jobid
if (-not $jobId) {throw "Unable to find a job named $JobName within the latest specified build. Did you spell it correctly?"}
} else {
$jobid = $projectObject.build.jobs[0].jobid
}
$artifacts = Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts" `
-Headers $headers @proxyArgs
$artifacts `
| ? { $psCmdlet.ShouldProcess($_.fileName) } `
| % {
$type = $_.type
$localArtifactPath = $_.fileName -split '/' | % { [Uri]::UnescapeDataString($_) }
if ($flat.IsPresent) {
$localArtifactPath = ($localArtifactPath | select -Last 1)
} else {
$localArtifactPath = $localArtifactPath -join [IO.Path]::DirectorySeparatorChar
}
$localArtifactPath = Join-Path $path $localArtifactPath
$artifactUrl = "$apiUrl/buildjobs/$jobId/artifacts/$($_.fileName)"
Write-Verbose "Downloading $artifactUrl to $localArtifactPath"
New-Item -ItemType Directory -Force -Path (Split-Path -Path $localArtifactPath) | Out-Null
Invoke-RestMethod -Method Get -Uri $artifactUrl -OutFile $localArtifactPath -Headers $headers @proxyArgs
New-Object PSObject -Property @{
'Source' = $artifactUrl
'Type' = $type
'Target' = $localArtifactPath
}
}
}
# Download x64 binaries
Get-AppVeyorArtifacts -Account "nefarius" -Project "ViGemBus" -Path $Path -Token $Token -Branch $BuildVersion -JobName "Platform: x64"
# Download x86 binaries
Get-AppVeyorArtifacts -Account "nefarius" -Project "ViGemBus" -Path $Path -Token $Token -Branch $BuildVersion -JobName "Platform: x86"
# Download ARM64 binaries
Get-AppVeyorArtifacts -Account "nefarius" -Project "ViGemBus" -Path $Path -Token $Token -Branch $BuildVersion -JobName "Platform: ARM64"
# List of files to sign
$files = "`".\artifacts\disk1\*.cab`" "
if ($NoSigning -eq $false) {
# sign with only one certificate
Invoke-Expression "& `"$signTool`" sign /v /as /n `"$certName`" /tr $timestampUrl /fd sha256 /td sha256 $files"
}
# Print helper job names for sign portal
"ViGemBus x86 v$BuildVersion $(Get-Date -Format "dd.MM.yyyy")"
"ViGemBus x64 v$BuildVersion $(Get-Date -Format "dd.MM.yyyy")"
"ViGemBus ARM64 v$BuildVersion $(Get-Date -Format "dd.MM.yyyy")"

View File

@@ -1,29 +1,38 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2020, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
constexpr auto cpp_pool_tag = 'EGiV';
@@ -35,7 +44,7 @@ void* operator new
size_t size
)
{
return ExAllocatePoolWithTag(NonPagedPoolNx, size, cpp_pool_tag);
return ExAllocatePoolZero(NonPagedPoolNx, size, cpp_pool_tag);
}
void* operator new[]
@@ -43,7 +52,7 @@ void* operator new[]
size_t size
)
{
return ExAllocatePoolWithTag(NonPagedPoolNx, size, cpp_pool_tag);
return ExAllocatePoolZero(NonPagedPoolNx, size, cpp_pool_tag);
}
void operator delete
@@ -98,7 +107,7 @@ void* __CRTDECL operator new
size_t size
)
{
return ExAllocatePoolWithTag(NonPagedPoolNx, size, cpp_pool_tag);
return ExAllocatePoolZero(NonPagedPoolNx, size, cpp_pool_tag);
}
void* __CRTDECL operator new[]
@@ -106,7 +115,7 @@ void* __CRTDECL operator new[]
size_t size
)
{
return ExAllocatePoolWithTag(NonPagedPoolNx, size, cpp_pool_tag);
return ExAllocatePoolZero(NonPagedPoolNx, size, cpp_pool_tag);
}
void __CRTDECL operator delete

20
sys/Dmf.props Normal file
View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_PropertySheetDisplayName>Driver Module Framework</_PropertySheetDisplayName>
<!-- By default, look for DMF in parent root directory, otherwise use environment variable value -->
<DmfRootPath Condition="'$(DmfRootPath)' == ''">$(SolutionDir)..\</DmfRootPath>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(DmfRootPath)\DMF\Modules.Library;$(DmfRootPath)\DMF\Modules.Template;$(DmfRootPath)\DMF\Modules.Library.Tests;$(DmfRootPath)\DMF\Framework;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies Condition="'$(DriverType)'=='KMDF'">$(DmfRootPath)\$(Configuration)\$(PlatformName)\lib\DmfK\DmfK.lib;$(DmfRootPath)\$(Configuration)\$(PlatformName)\individual_libs\DmfKModules.Template\DmfKModules.Template.lib;%(AdditionalDependencies);</AdditionalDependencies>
<AdditionalDependencies Condition="'$(DriverType)'=='UMDF'">$(DmfRootPath)\$(Configuration)\$(PlatformName)\lib\DmfU\DmfU.lib;$(DmfRootPath)\$(Configuration)\$(PlatformName)\individual_libs\DmfUModules.Template\DmfUModules.Template.lib;%(AdditionalDependencies);</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View File

@@ -1,32 +1,41 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "busenum.h"
#include "driver.tmh"
#include "Driver.h"
#include "trace.h"
#include "Driver.tmh"
#include <wdmguid.h>
#ifdef ALLOC_PRAGMA
@@ -37,7 +46,7 @@
#pragma alloc_text (PAGE, Bus_EvtDriverContextCleanup)
#endif
#include "Queue.hpp"
#include "EmulationTargetPDO.hpp"
#include "XusbPdo.hpp"
#include "Ds4Pdo.hpp"
@@ -50,45 +59,61 @@ using ViGEm::Bus::Targets::EmulationTargetDS4;
EXTERN_C_START
IoctlHandler_IoctlRecord ViGEmBus_IoctlSpecification[] =
{
{IOCTL_VIGEM_CHECK_VERSION, sizeof(VIGEM_CHECK_VERSION), 0, Bus_CheckVersionHandler},
{IOCTL_VIGEM_WAIT_DEVICE_READY, sizeof(VIGEM_WAIT_DEVICE_READY), 0, Bus_WaitDeviceReadyHandler},
{IOCTL_VIGEM_PLUGIN_TARGET, sizeof(VIGEM_PLUGIN_TARGET), 0, Bus_PluginTargetHandler},
{IOCTL_VIGEM_UNPLUG_TARGET, sizeof(VIGEM_UNPLUG_TARGET), 0, Bus_UnplugTargetHandler},
{IOCTL_XUSB_SUBMIT_REPORT, sizeof(XUSB_SUBMIT_REPORT), 0, Bus_XusbSubmitReportHandler},
{IOCTL_XUSB_REQUEST_NOTIFICATION, sizeof(XUSB_REQUEST_NOTIFICATION), sizeof(XUSB_REQUEST_NOTIFICATION), Bus_XusbRequestNotificationHandler},
{IOCTL_DS4_SUBMIT_REPORT, sizeof(DS4_SUBMIT_REPORT), 0, Bus_Ds4SubmitReportHandler},
{IOCTL_DS4_REQUEST_NOTIFICATION, sizeof(DS4_REQUEST_NOTIFICATION), sizeof(DS4_REQUEST_NOTIFICATION), Bus_Ds4RequestNotificationHandler},
{IOCTL_XUSB_GET_USER_INDEX, sizeof(XUSB_GET_USER_INDEX), sizeof(XUSB_GET_USER_INDEX), Bus_XusbGetUserIndexHandler},
{IOCTL_DS4_AWAIT_OUTPUT_AVAILABLE, sizeof(DS4_AWAIT_OUTPUT), sizeof(DS4_AWAIT_OUTPUT), Bus_Ds4AwaitOutputHandler},
};
//
// Driver entry routine.
//
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDFDRIVER driver;
WDF_OBJECT_ATTRIBUTES attributes;
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDFDRIVER driver;
WDF_OBJECT_ATTRIBUTES attributes;
KdPrint((DRIVERNAME "Virtual Gamepad Emulation Bus Driver [built: %s %s]\n", __DATE__, __TIME__));
KdPrint((DRIVERNAME "Virtual Gamepad Emulation Bus Driver [built: %s %s]\n", __DATE__, __TIME__));
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING(DriverObject, RegistryPath);
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING(DriverObject, RegistryPath);
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"Loading Virtual Gamepad Emulation Bus Driver [built: %s %s]",
__DATE__, __TIME__);
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"Loading Virtual Gamepad Emulation Bus Driver"
);
//
// Register cleanup callback
//
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = Bus_EvtDriverContextCleanup;
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
WDF_DRIVER_CONFIG_INIT(&config, Bus_EvtDeviceAdd);
//
// Register cleanup callback
//
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = Bus_EvtDriverContextCleanup;
status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, &driver);
WDF_DRIVER_CONFIG_INIT(&config, Bus_EvtDeviceAdd);
if (!NT_SUCCESS(status))
{
WPP_CLEANUP(DriverObject);
KdPrint((DRIVERNAME "WdfDriverCreate failed with status 0x%x\n", status));
}
status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, &driver);
return status;
if (!NT_SUCCESS(status))
{
WPP_CLEANUP(DriverObject);
KdPrint((DRIVERNAME "WdfDriverCreate failed with status 0x%x\n", status));
}
return status;
}
//
@@ -96,190 +121,304 @@ NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING Registry
//
NTSTATUS Bus_EvtDeviceAdd(IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit)
{
WDF_CHILD_LIST_CONFIG config;
NTSTATUS status;
WDFDEVICE device;
WDF_IO_QUEUE_CONFIG queueConfig;
PNP_BUS_INFORMATION busInfo;
WDFQUEUE queue;
WDF_FILEOBJECT_CONFIG foConfig;
WDF_OBJECT_ATTRIBUTES fdoAttributes;
WDF_OBJECT_ATTRIBUTES fileHandleAttributes;
PFDO_DEVICE_DATA pFDOData;
WDF_CHILD_LIST_CONFIG config;
NTSTATUS status;
WDFDEVICE device = NULL;
PNP_BUS_INFORMATION busInfo;
WDF_FILEOBJECT_CONFIG foConfig;
WDF_OBJECT_ATTRIBUTES fdoAttributes;
WDF_OBJECT_ATTRIBUTES fileHandleAttributes;
PFDO_DEVICE_DATA pFDOData;
PWSTR pSymbolicNameList;
PDMFDEVICE_INIT dmfDeviceInit = NULL;
UNREFERENCED_PARAMETER(Driver);
UNREFERENCED_PARAMETER(Driver);
PAGED_CODE();
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
FuncEntry(TRACE_DRIVER);
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
// More than one process may talk to the bus at the same time
WdfDeviceInitSetExclusive(DeviceInit, FALSE);
// Bus is power policy owner over all PDOs
WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, TRUE);
#pragma region Check for duplicated FDO
//
// Note: this could be avoided if converted to non-PNP driver
// and use of named device object. Food for thought for future.
//
if (NT_SUCCESS(status = IoGetDeviceInterfaces(
&GUID_DEVINTERFACE_BUSENUM_VIGEM,
NULL,
0, // Important!
&pSymbolicNameList
)))
{
const bool deviceAlreadyExists = (0 != *pSymbolicNameList);
ExFreePool(pSymbolicNameList);
if (deviceAlreadyExists)
{
TraceError(
TRACE_DRIVER,
"Device with interface GUID {%!GUID!} already exists (%ws)",
&GUID_DEVINTERFACE_BUSENUM_VIGEM,
pSymbolicNameList
);
return STATUS_RESOURCE_IN_USE;
}
}
else
{
TraceEvents(TRACE_LEVEL_WARNING,
TRACE_DRIVER,
"IoGetDeviceInterfaces failed with status %!STATUS!",
status);
}
#pragma endregion
do
{
dmfDeviceInit = DMF_DmfDeviceInitAllocate(DeviceInit);
if (dmfDeviceInit == NULL)
{
TraceError(
TRACE_DRIVER,
"DMF_DmfDeviceInitAllocate failed"
);
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
DMF_DmfDeviceInitHookPnpPowerEventCallbacks(dmfDeviceInit, NULL);
DMF_DmfDeviceInitHookPowerPolicyEventCallbacks(dmfDeviceInit, NULL);
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
#pragma region Prepare child list
WDF_CHILD_LIST_CONFIG_INIT(&config, sizeof(PDO_IDENTIFICATION_DESCRIPTION), Bus_EvtDeviceListCreatePdo);
WDF_CHILD_LIST_CONFIG_INIT(&config, sizeof(PDO_IDENTIFICATION_DESCRIPTION), Bus_EvtDeviceListCreatePdo);
config.EvtChildListIdentificationDescriptionCompare = Bus_EvtChildListIdentificationDescriptionCompare;
config.EvtChildListIdentificationDescriptionCompare = EmulationTargetPDO::EvtChildListIdentificationDescriptionCompare;
WdfFdoInitSetDefaultChildListConfig(DeviceInit, &config, WDF_NO_OBJECT_ATTRIBUTES);
WdfFdoInitSetDefaultChildListConfig(DeviceInit, &config, WDF_NO_OBJECT_ATTRIBUTES);
#pragma endregion
#pragma region Assign File Object Configuration
WDF_FILEOBJECT_CONFIG_INIT(&foConfig, Bus_DeviceFileCreate, Bus_FileClose, NULL);
WDF_FILEOBJECT_CONFIG_INIT(&foConfig, Bus_DeviceFileCreate, Bus_FileClose, NULL);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fileHandleAttributes, FDO_FILE_DATA);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fileHandleAttributes, FDO_FILE_DATA);
WdfDeviceInitSetFileObjectConfig(DeviceInit, &foConfig, &fileHandleAttributes);
DMF_DmfDeviceInitHookFileObjectConfig(dmfDeviceInit, &foConfig);
WdfDeviceInitSetFileObjectConfig(DeviceInit, &foConfig, &fileHandleAttributes);
#pragma endregion
#pragma region Create FDO
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DEVICE_DATA);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DEVICE_DATA);
status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);
if (!NT_SUCCESS(status = WdfDeviceCreate(
&DeviceInit,
&fdoAttributes,
&device
)))
{
TraceError(
TRACE_DRIVER,
"WdfDeviceCreate failed with status %!STATUS!",
status);
break;
}
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"WdfDeviceCreate failed with status %!STATUS!",
status);
return status;
}
pFDOData = FdoGetData(device);
pFDOData = FdoGetData(device);
if (pFDOData == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"FdoGetData failed");
return STATUS_UNSUCCESSFUL;
}
pFDOData->InterfaceReferenceCounter = 0;
pFDOData->NextSessionId = FDO_FIRST_SESSION_ID;
#pragma endregion
#pragma region Create default I/O queue for FDO
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel);
queueConfig.EvtIoDeviceControl = Bus_EvtIoDeviceControl;
queueConfig.EvtIoDefault = Bus_EvtIoDefault;
__analysis_assume(queueConfig.EvtIoStop != 0);
status = WdfIoQueueCreate(device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue);
__analysis_assume(queueConfig.EvtIoStop == 0);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"WdfIoQueueCreate failed with status %!STATUS!",
status);
return status;
}
pFDOData->InterfaceReferenceCounter = 0;
pFDOData->NextSessionId = FDO_FIRST_SESSION_ID;
#pragma endregion
#pragma region Expose FDO interface
status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_BUSENUM_VIGEM, NULL);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"WdfDeviceCreateDeviceInterface failed with status %!STATUS!",
status);
return status;
}
if (!NT_SUCCESS(status = WdfDeviceCreateDeviceInterface(
device,
&GUID_DEVINTERFACE_BUSENUM_VIGEM,
NULL
)))
{
TraceError(
TRACE_DRIVER,
"WdfDeviceCreateDeviceInterface failed with status %!STATUS!",
status);
break;
}
#pragma endregion
#pragma region Set bus information
busInfo.BusTypeGuid = GUID_BUS_TYPE_USB;
busInfo.LegacyBusType = PNPBus;
busInfo.BusNumber = 0;
busInfo.BusTypeGuid = GUID_BUS_TYPE_USB;
busInfo.LegacyBusType = PNPBus;
busInfo.BusNumber = 0;
WdfDeviceSetBusInformationForChildren(device, &busInfo);
WdfDeviceSetBusInformationForChildren(device, &busInfo);
#pragma endregion
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit with status %!STATUS!", status);
//
// DMF Module initialization
//
DMF_EVENT_CALLBACKS dmfEventCallbacks;
DMF_EVENT_CALLBACKS_INIT(&dmfEventCallbacks);
dmfEventCallbacks.EvtDmfDeviceModulesAdd = DmfDeviceModulesAdd;
DMF_DmfDeviceInitSetEventCallbacks(
dmfDeviceInit,
&dmfEventCallbacks
);
return status;
status = DMF_ModulesCreate(device, &dmfDeviceInit);
if (!NT_SUCCESS(status))
{
TraceEvents(
TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"DMF_ModulesCreate failed with status %!STATUS!",
status
);
break;
}
} while (FALSE);
if (dmfDeviceInit != NULL)
{
DMF_DmfDeviceInitFree(&dmfDeviceInit);
}
if (!NT_SUCCESS(status) && device != NULL)
{
WdfObjectDelete(device);
}
FuncExit(TRACE_DRIVER, "status=%!STATUS!", status);
return status;
}
#pragma code_seg("PAGED")
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
DmfDeviceModulesAdd(
_In_ WDFDEVICE Device,
_In_ PDMFMODULE_INIT DmfModuleInit
)
{
FuncEntry(TRACE_DRIVER);
PFDO_DEVICE_DATA pDevCtx = FdoGetData(Device);
DMF_MODULE_ATTRIBUTES moduleAttributes;
DMF_CONFIG_IoctlHandler ioctlHandlerConfig;
DMF_CONFIG_IoctlHandler_AND_ATTRIBUTES_INIT(&ioctlHandlerConfig, &moduleAttributes);
ioctlHandlerConfig.DeviceInterfaceGuid = GUID_DEVINTERFACE_BUSENUM_VIGEM;
ioctlHandlerConfig.IoctlRecordCount = ARRAYSIZE(ViGEmBus_IoctlSpecification);
ioctlHandlerConfig.IoctlRecords = ViGEmBus_IoctlSpecification;
ioctlHandlerConfig.ForwardUnhandledRequests = FALSE;
DMF_DmfModuleAdd(
DmfModuleInit,
&moduleAttributes,
WDF_NO_OBJECT_ATTRIBUTES,
NULL
);
DMF_CONFIG_NotifyUserWithRequestMultiple notifyConfig;
DMF_CONFIG_NotifyUserWithRequestMultiple_AND_ATTRIBUTES_INIT(&notifyConfig, &moduleAttributes);
notifyConfig.MaximumNumberOfPendingRequests = 64 * 2;
notifyConfig.SizeOfDataBuffer = sizeof(DS4_AWAIT_OUTPUT);
notifyConfig.MaximumNumberOfPendingDataBuffers = 64;
notifyConfig.ModeType.Modes.ReplayLastMessageToNewClients = FALSE;
notifyConfig.CompletionCallback = Bus_EvtUserNotifyRequestComplete;
DMF_DmfModuleAdd(
DmfModuleInit,
&moduleAttributes,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevCtx->UserNotification
);
FuncExitNoReturn(TRACE_DRIVER);
}
#pragma code_seg()
// Gets called when the user-land process (or kernel driver) exits or closes the handle,
// and all IO has completed.
//
_Use_decl_annotations_
VOID
Bus_DeviceFileCreate(
_In_ WDFDEVICE Device,
_In_ WDFREQUEST Request,
_In_ WDFFILEOBJECT FileObject
_In_ WDFDEVICE Device,
_In_ WDFREQUEST Request,
_In_ WDFFILEOBJECT FileObject
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
PFDO_FILE_DATA pFileData = NULL;
PFDO_DEVICE_DATA pFDOData = NULL;
LONG refCount = 0;
LONG sessionId = 0;
NTSTATUS status = STATUS_INVALID_PARAMETER;
PFDO_FILE_DATA pFileData = NULL;
PFDO_DEVICE_DATA pFDOData = NULL;
LONG refCount = 0;
LONG sessionId = 0;
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(Request);
PAGED_CODE();
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
pFileData = FileObjectGetData(FileObject);
pFileData = FileObjectGetData(FileObject);
if (pFileData == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"FileObjectGetData failed to return file object from WDFFILEOBJECT 0x%p",
FileObject);
}
else
{
pFDOData = FdoGetData(Device);
if (pFDOData == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"FdoGetData failed");
status = STATUS_NO_SUCH_DEVICE;
}
else
{
refCount = InterlockedIncrement(&pFDOData->InterfaceReferenceCounter);
sessionId = InterlockedIncrement(&pFDOData->NextSessionId);
if (pFileData == NULL)
{
TraceError(
TRACE_DRIVER,
"FileObjectGetData failed to return file object from WDFFILEOBJECT 0x%p",
FileObject);
}
else
{
pFDOData = FdoGetData(Device);
if (pFDOData == NULL)
{
TraceError(
TRACE_DRIVER,
"FdoGetData failed");
status = STATUS_NO_SUCH_DEVICE;
}
else
{
refCount = InterlockedIncrement(&pFDOData->InterfaceReferenceCounter);
sessionId = InterlockedIncrement(&pFDOData->NextSessionId);
pFileData->SessionId = sessionId;
status = STATUS_SUCCESS;
pFileData->SessionId = sessionId;
status = STATUS_SUCCESS;
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"File/session id = %d, device ref. count = %d",
(int)sessionId, (int)refCount);
}
}
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"File/session id = %d, device ref. count = %d",
(int)sessionId, (int)refCount);
}
}
WdfRequestComplete(Request, status);
WdfRequestComplete(Request, status);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit with status %!STATUS!", status);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit with status %!STATUS!", status);
}
//
@@ -288,140 +427,209 @@ Bus_DeviceFileCreate(
_Use_decl_annotations_
VOID
Bus_FileClose(
WDFFILEOBJECT FileObject
WDFFILEOBJECT FileObject
)
{
WDFDEVICE device;
WDFDEVICE hChild;
NTSTATUS status;
WDFCHILDLIST list;
WDF_CHILD_LIST_ITERATOR iterator;
WDF_CHILD_RETRIEVE_INFO childInfo;
PDO_IDENTIFICATION_DESCRIPTION description;
PFDO_FILE_DATA pFileData = NULL;
PFDO_DEVICE_DATA pFDOData = NULL;
LONG refCount = 0;
WDFDEVICE device;
WDFDEVICE hChild;
NTSTATUS status;
WDFCHILDLIST list;
WDF_CHILD_LIST_ITERATOR iterator;
WDF_CHILD_RETRIEVE_INFO childInfo;
PDO_IDENTIFICATION_DESCRIPTION description;
PFDO_FILE_DATA pFileData = NULL;
PFDO_DEVICE_DATA pFDOData = NULL;
LONG refCount = 0;
PAGED_CODE();
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
// Check common context
pFileData = FileObjectGetData(FileObject);
if (pFileData == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"FileObjectGetData failed to return file object from WDFFILEOBJECT 0x%p",
FileObject);
return;
}
// Check common context
pFileData = FileObjectGetData(FileObject);
if (pFileData == NULL)
{
TraceError(
TRACE_DRIVER,
"FileObjectGetData failed to return file object from WDFFILEOBJECT 0x%p",
FileObject);
return;
}
device = WdfFileObjectGetDevice(FileObject);
device = WdfFileObjectGetDevice(FileObject);
pFDOData = FdoGetData(device);
if (pFDOData == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"FdoGetData failed");
status = STATUS_NO_SUCH_DEVICE;
}
else
{
refCount = InterlockedDecrement(&pFDOData->InterfaceReferenceCounter);
pFDOData = FdoGetData(device);
if (pFDOData == NULL)
{
TraceError(
TRACE_DRIVER,
"FdoGetData failed");
status = STATUS_NO_SUCH_DEVICE;
}
else
{
refCount = InterlockedDecrement(&pFDOData->InterfaceReferenceCounter);
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"Device ref. count = %d",
(int)refCount);
}
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"Device ref. count = %d",
(int)refCount);
}
list = WdfFdoGetDefaultChildList(device);
list = WdfFdoGetDefaultChildList(device);
WDF_CHILD_LIST_ITERATOR_INIT(&iterator, WdfRetrievePresentChildren);
WDF_CHILD_LIST_ITERATOR_INIT(&iterator, WdfRetrievePresentChildren);
WdfChildListBeginIteration(list, &iterator);
WdfChildListBeginIteration(list, &iterator);
for (;;)
{
WDF_CHILD_RETRIEVE_INFO_INIT(&childInfo, &description.Header);
WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
for (;;)
{
WDF_CHILD_RETRIEVE_INFO_INIT(&childInfo, &description.Header);
WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
status = WdfChildListRetrieveNextDevice(list, &iterator, &hChild, &childInfo);
if (!NT_SUCCESS(status) || status == STATUS_NO_MORE_ENTRIES)
{
break;
}
status = WdfChildListRetrieveNextDevice(list, &iterator, &hChild, &childInfo);
if (!NT_SUCCESS(status) || status == STATUS_NO_MORE_ENTRIES)
{
break;
}
//TraceEvents(TRACE_LEVEL_VERBOSE,
// TRACE_DRIVER,
// "PDO properties: status = %!STATUS!, pdoPID = %d, curPID = %d, pdoSID = %d, curSID = %d, internal = %d",
// (int)childInfo.Status,
// (int)description.OwnerProcessId,
// (int)CURRENT_PROCESS_ID(),
// (int)description.SessionId,
// (int)pFileData->SessionId,
// (int)description.OwnerIsDriver
//);
//TraceVerbose(
// TRACE_DRIVER,
// "PDO properties: status = %!STATUS!, pdoPID = %d, curPID = %d, pdoSID = %d, curSID = %d, internal = %d",
// (int)childInfo.Status,
// (int)description.OwnerProcessId,
// (int)CURRENT_PROCESS_ID(),
// (int)description.SessionId,
// (int)pFileData->SessionId,
// (int)description.OwnerIsDriver
//);
// Only unplug devices with matching session id
if (childInfo.Status == WdfChildListRetrieveDeviceSuccess
&& description.SessionId == pFileData->SessionId)
{
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"Unplugging device with serial %d",
description.SerialNo);
// Only unplug devices with matching session id
if (childInfo.Status == WdfChildListRetrieveDeviceSuccess
&& description.SessionId == pFileData->SessionId)
{
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DRIVER,
"Unplugging device with serial %d",
description.SerialNo);
// "Unplug" child
status = WdfChildListUpdateChildDescriptionAsMissing(list, &description.Header);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"WdfChildListUpdateChildDescriptionAsMissing failed with status %!STATUS!",
status);
}
}
}
// "Unplug" child
status = WdfChildListUpdateChildDescriptionAsMissing(list, &description.Header);
if (!NT_SUCCESS(status))
{
TraceError(
TRACE_DRIVER,
"WdfChildListUpdateChildDescriptionAsMissing failed with status %!STATUS!",
status);
}
}
}
WdfChildListEndIteration(list, &iterator);
WdfChildListEndIteration(list, &iterator);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit with status %!STATUS!", status);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit with status %!STATUS!", status);
}
VOID
Bus_EvtDriverContextCleanup(
_In_ WDFOBJECT DriverObject
_In_ WDFOBJECT DriverObject
)
/*++
Routine Description:
Free all the resources allocated in DriverEntry.
Free all the resources allocated in DriverEntry.
Arguments:
DriverObject - handle to a WDF Driver object.
DriverObject - handle to a WDF Driver object.
Return Value:
VOID.
VOID.
--*/
{
UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(DriverObject);
PAGED_CODE();
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
//
// Stop WPP Tracing
//
WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));
//
// Stop WPP Tracing
//
WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));
}
void Bus_EvtUserNotifyRequestComplete(
_In_ DMFMODULE DmfModule,
_In_ WDFREQUEST Request,
_In_opt_ ULONG_PTR Context,
_In_ NTSTATUS NtStatus
)
{
FuncEntry(TRACE_DRIVER);
UNREFERENCED_PARAMETER(DmfModule);
auto pOutput = reinterpret_cast<PDS4_AWAIT_OUTPUT>(Context);
PDS4_AWAIT_OUTPUT pNotify = NULL;
size_t length = 0;
if (NT_SUCCESS(WdfRequestRetrieveOutputBuffer(
Request,
sizeof(DS4_AWAIT_OUTPUT),
reinterpret_cast<PVOID*>(&pNotify),
&length)))
{
RtlCopyMemory(pNotify, pOutput, sizeof(DS4_AWAIT_OUTPUT));
Util_DumpAsHex("NOTIFY_COMPLETE", pNotify, sizeof(DS4_AWAIT_OUTPUT));
WdfRequestSetInformation(Request, sizeof(DS4_AWAIT_OUTPUT));
}
WdfRequestComplete(Request, NtStatus);
FuncExit(TRACE_DRIVER, "status=%!STATUS!", NtStatus);
}
void Util_DumpAsHex(PCSTR Prefix, PVOID Buffer, ULONG BufferLength)
{
#ifdef DBG
size_t dumpBufferLength = ((BufferLength * sizeof(CHAR)) * 2) + 1;
PSTR dumpBuffer = static_cast<PSTR>(ExAllocatePoolZero(
NonPagedPoolNx,
dumpBufferLength,
'1234'
));
if (dumpBuffer)
{
RtlZeroMemory(dumpBuffer, dumpBufferLength);
for (ULONG i = 0; i < BufferLength; i++)
{
sprintf(&dumpBuffer[i * 2], "%02X", static_cast<PUCHAR>(Buffer)[i]);
}
TraceVerbose(TRACE_BUSPDO,
"%s - Buffer length: %04d, buffer content: %s\n",
Prefix,
BufferLength,
dumpBuffer
);
ExFreePoolWithTag(dumpBuffer, '1234');
}
#else
UNREFERENCED_PARAMETER(Prefix);
UNREFERENCED_PARAMETER(Buffer);
UNREFERENCED_PARAMETER(BufferLength);
#endif
}
EXTERN_C_END

149
sys/Driver.h Normal file
View File

@@ -0,0 +1,149 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* BSD 3-Clause License
*
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#pragma warning(disable:5040)
#include <DmfModules.Library.h>
#pragma warning(default:5040)
#include <ntddk.h>
#include <wdf.h>
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
#pragma region Macros
#define DRIVERNAME "ViGEm: "
#pragma endregion
//
// FDO (bus device) context data
//
typedef struct _FDO_DEVICE_DATA
{
//
// Counter of interface references
//
LONG InterfaceReferenceCounter;
//
// Next SessionId to assign to a file handle
//
LONG NextSessionId;
//
// Notification DMF module
//
DMFMODULE UserNotification;
} FDO_DEVICE_DATA, * PFDO_DEVICE_DATA;
#define FDO_FIRST_SESSION_ID 100
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_DEVICE_DATA, FdoGetData)
//
// Context data associated with file objects created by user mode applications
//
typedef struct _FDO_FILE_DATA
{
//
// SessionId associated with file handle.
// Used to map file handles to emulated gamepad devices.
//
LONG SessionId;
} FDO_FILE_DATA, * PFDO_FILE_DATA;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_FILE_DATA, FileObjectGetData)
EXTERN_C_START
#pragma region WDF callback prototypes
DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD Bus_EvtDeviceAdd;
EVT_WDF_DEVICE_FILE_CREATE Bus_DeviceFileCreate;
EVT_WDF_FILE_CLOSE Bus_FileClose;
EVT_WDF_CHILD_LIST_CREATE_DEVICE Bus_EvtDeviceListCreatePdo;
EVT_WDF_OBJECT_CONTEXT_CLEANUP Bus_EvtDriverContextCleanup;
#pragma endregion
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
DmfDeviceModulesAdd(
_In_ WDFDEVICE Device,
_In_ PDMFMODULE_INIT DmfModuleInit
);
void Bus_EvtUserNotifyRequestComplete(
_In_ DMFMODULE DmfModule,
_In_ WDFREQUEST Request,
_In_opt_ ULONG_PTR Context,
_In_ NTSTATUS NtStatus
);
void Util_DumpAsHex(PCSTR Prefix, PVOID Buffer, ULONG BufferLength);
#pragma region Bus enumeration-specific functions
NTSTATUS
Bus_PlugInDevice(
_In_ WDFDEVICE Device,
_In_ WDFREQUEST Request,
_In_ BOOLEAN IsInternal,
_Out_ size_t* Transferred
);
NTSTATUS
Bus_UnPlugDevice(
_In_ WDFDEVICE Device,
_In_ WDFREQUEST Request,
_In_ BOOLEAN IsInternal,
_Out_ size_t* Transferred
);
#pragma endregion
EXTERN_C_END

View File

@@ -1,43 +1,51 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <ntifs.h>
#include "Ds4Pdo.hpp"
#include "trace.h"
#include "Ds4Pdo.tmh"
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
#include <hidclass.h>
PCWSTR ViGEm::Bus::Targets::EmulationTargetDS4::_deviceDescription = L"Virtual DualShock 4 Controller";
ViGEm::Bus::Targets::EmulationTargetDS4::EmulationTargetDS4(ULONG Serial, LONG SessionId, USHORT VendorId,
USHORT ProductId) : EmulationTargetPDO(
Serial, SessionId, VendorId, ProductId)
USHORT ProductId) : EmulationTargetPDO(
Serial, SessionId, VendorId, ProductId)
{
this->_TargetType = DualShock4Wired;
this->_UsbConfigurationDescriptionSize = DS4_DESCRIPTOR_SIZE;
@@ -64,7 +72,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareDevice(PWDFDEVICE_IN
status = RtlUnicodeStringInit(DeviceDescription, _deviceDescription);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_DS4,
"RtlUnicodeStringInit failed with status %!STATUS!",
status);
@@ -78,7 +86,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareDevice(PWDFDEVICE_IN
status = WdfPdoInitAddHardwareID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_DS4,
"WdfPdoInitAddHardwareID failed with status %!STATUS!",
status);
@@ -93,7 +101,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareDevice(PWDFDEVICE_IN
status = WdfPdoInitAddHardwareID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_DS4,
"WdfPdoInitAddHardwareID failed with status %!STATUS!",
status);
@@ -106,7 +114,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareDevice(PWDFDEVICE_IN
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_DS4,
"WdfPdoInitAddCompatibleID (#01) failed with status %!STATUS!",
status);
@@ -118,7 +126,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareDevice(PWDFDEVICE_IN
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_DS4,
"WdfPdoInitAddCompatibleID (#02) failed with status %!STATUS!",
status);
@@ -130,7 +138,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareDevice(PWDFDEVICE_IN
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_DS4,
"WdfPdoInitAddCompatibleID (#03) failed with status %!STATUS!",
status);
@@ -142,34 +150,6 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareDevice(PWDFDEVICE_IN
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareHardware()
{
WDF_QUERY_INTERFACE_CONFIG ifaceCfg;
INTERFACE devinterfaceHid;
devinterfaceHid.Size = sizeof(INTERFACE);
devinterfaceHid.Version = 1;
devinterfaceHid.Context = static_cast<PVOID>(this->_PdoDevice);
devinterfaceHid.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
devinterfaceHid.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
// Expose GUID_DEVINTERFACE_HID so HIDUSB can initialize
WDF_QUERY_INTERFACE_CONFIG_INIT(
&ifaceCfg,
(PINTERFACE)&devinterfaceHid,
&GUID_DEVINTERFACE_HID,
NULL
);
NTSTATUS status = WdfDeviceAddQueryInterface(this->_PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DS4,
"WdfDeviceAddQueryInterface failed with status %!STATUS!",
status);
return status;
}
// Set default HID input report (everything zero`d)
UCHAR DefaultHidReport[DS4_REPORT_SIZE] =
{
@@ -195,7 +175,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoPrepareHardware()
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoInitContext()
{
NTSTATUS status;
NTSTATUS status;
// Initialize periodic timer
WDF_TIMER_CONFIG timerConfig;
@@ -212,160 +192,160 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::PdoInitContext()
// PDO is parent
timerAttribs.ParentObject = this->_PdoDevice;
// Create timer
status = WdfTimerCreate(
&timerConfig,
&timerAttribs,
&this->_PendingUsbInRequestsTimer
);
if (!NT_SUCCESS(status))
do
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DS4,
"WdfTimerCreate failed with status %!STATUS!",
status);
return status;
}
// Create timer
if (!NT_SUCCESS(status = WdfTimerCreate(
&timerConfig,
&timerAttribs,
&this->_PendingUsbInRequestsTimer
)))
{
TraceError(
TRACE_DS4,
"WdfTimerCreate failed with status %!STATUS!",
status);
break;
}
// Load/generate MAC address
// Load/generate MAC address
// TODO: tidy up this region
//
// TODO: tidy up this region
//
WDFKEY keyParams, keyTargets, keyDS, keySerial;
UNICODE_STRING keyName, valueName;
WDFKEY keyParams, keyTargets, keyDS, keySerial;
UNICODE_STRING keyName, valueName;
status = WdfDriverOpenParametersRegistryKey(
WdfGetDriver(),
STANDARD_RIGHTS_ALL,
WDF_NO_OBJECT_ATTRIBUTES,
&keyParams
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DS4,
"WdfDriverOpenParametersRegistryKey failed with status %!STATUS!",
status);
return status;
}
if (!NT_SUCCESS(status = WdfDriverOpenParametersRegistryKey(
WdfGetDriver(),
STANDARD_RIGHTS_ALL,
WDF_NO_OBJECT_ATTRIBUTES,
&keyParams
)))
{
TraceError(
TRACE_DS4,
"WdfDriverOpenParametersRegistryKey failed with status %!STATUS!",
status);
break;
}
RtlUnicodeStringInit(&keyName, L"Targets");
RtlUnicodeStringInit(&keyName, L"Targets");
status = WdfRegistryCreateKey(
keyParams,
&keyName,
KEY_ALL_ACCESS,
REG_OPTION_NON_VOLATILE,
NULL,
WDF_NO_OBJECT_ATTRIBUTES,
&keyTargets
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DS4,
"WdfRegistryCreateKey failed with status %!STATUS!",
status);
return status;
}
if (!NT_SUCCESS(status = WdfRegistryCreateKey(
keyParams,
&keyName,
KEY_ALL_ACCESS,
REG_OPTION_NON_VOLATILE,
nullptr,
WDF_NO_OBJECT_ATTRIBUTES,
&keyTargets
)))
{
TraceError(
TRACE_DS4,
"WdfRegistryCreateKey failed with status %!STATUS!",
status);
break;
}
RtlUnicodeStringInit(&keyName, L"DualShock");
RtlUnicodeStringInit(&keyName, L"DualShock");
status = WdfRegistryCreateKey(
keyTargets,
&keyName,
KEY_ALL_ACCESS,
REG_OPTION_NON_VOLATILE,
NULL,
WDF_NO_OBJECT_ATTRIBUTES,
&keyDS
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DS4,
"WdfRegistryCreateKey failed with status %!STATUS!",
status);
return status;
}
if (!NT_SUCCESS(status = WdfRegistryCreateKey(
keyTargets,
&keyName,
KEY_ALL_ACCESS,
REG_OPTION_NON_VOLATILE,
nullptr,
WDF_NO_OBJECT_ATTRIBUTES,
&keyDS
)))
{
TraceError(
TRACE_DS4,
"WdfRegistryCreateKey failed with status %!STATUS!",
status);
break;
}
DECLARE_UNICODE_STRING_SIZE(serialPath, 4);
RtlUnicodeStringPrintf(&serialPath, L"%04d", this->_SerialNo);
DECLARE_UNICODE_STRING_SIZE(serialPath, 4);
RtlUnicodeStringPrintf(&serialPath, L"%04d", this->_SerialNo);
status = WdfRegistryCreateKey(
keyDS,
&serialPath,
KEY_ALL_ACCESS,
REG_OPTION_NON_VOLATILE,
NULL,
WDF_NO_OBJECT_ATTRIBUTES,
&keySerial
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DS4,
"WdfRegistryCreateKey failed with status %!STATUS!",
status);
return status;
}
if (!NT_SUCCESS(status = WdfRegistryCreateKey(
keyDS,
&serialPath,
KEY_ALL_ACCESS,
REG_OPTION_NON_VOLATILE,
nullptr,
WDF_NO_OBJECT_ATTRIBUTES,
&keySerial
)))
{
TraceError(
TRACE_DS4,
"WdfRegistryCreateKey failed with status %!STATUS!",
status);
break;
}
RtlUnicodeStringInit(&valueName, L"TargetMacAddress");
RtlUnicodeStringInit(&valueName, L"TargetMacAddress");
status = WdfRegistryQueryValue(
keySerial,
&valueName,
sizeof(MAC_ADDRESS),
&this->_TargetMacAddress,
NULL,
NULL
);
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DS4,
"MAC-Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
this->_TargetMacAddress.Vendor0,
this->_TargetMacAddress.Vendor1,
this->_TargetMacAddress.Vendor2,
this->_TargetMacAddress.Nic0,
this->_TargetMacAddress.Nic1,
this->_TargetMacAddress.Nic2);
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
{
GenerateRandomMacAddress(&this->_TargetMacAddress);
status = WdfRegistryAssignValue(
status = WdfRegistryQueryValue(
keySerial,
&valueName,
REG_BINARY,
sizeof(MAC_ADDRESS),
static_cast<PVOID>(&this->_TargetMacAddress)
&this->_TargetMacAddress,
nullptr,
nullptr
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DS4,
"WdfRegistryAssignValue failed with status %!STATUS!",
status);
return status;
}
}
else if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DS4,
"WdfRegistryQueryValue failed with status %!STATUS!",
status);
return status;
}
"MAC-Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
this->_TargetMacAddress.Vendor0,
this->_TargetMacAddress.Vendor1,
this->_TargetMacAddress.Vendor2,
this->_TargetMacAddress.Nic0,
this->_TargetMacAddress.Nic1,
this->_TargetMacAddress.Nic2);
WdfRegistryClose(keySerial);
WdfRegistryClose(keyDS);
WdfRegistryClose(keyTargets);
WdfRegistryClose(keyParams);
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
{
GenerateRandomMacAddress(&this->_TargetMacAddress);
return STATUS_SUCCESS;
if (!NT_SUCCESS(status = WdfRegistryAssignValue(
keySerial,
&valueName,
REG_BINARY,
sizeof(MAC_ADDRESS),
static_cast<PVOID>(&this->_TargetMacAddress)
)))
{
TraceError(
TRACE_DS4,
"WdfRegistryAssignValue failed with status %!STATUS!",
status);
break;
}
}
else if (!NT_SUCCESS(status))
{
TraceError(
TRACE_DS4,
"WdfRegistryQueryValue failed with status %!STATUS!",
status);
break;
}
WdfRegistryClose(keySerial);
WdfRegistryClose(keyDS);
WdfRegistryClose(keyTargets);
WdfRegistryClose(keyParams);
} while (FALSE);
return status;
}
VOID ViGEm::Bus::Targets::EmulationTargetDS4::GetConfigurationDescriptorType(PUCHAR Buffer, ULONG Length)
@@ -453,34 +433,34 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::SelectConfiguration(PURB Urb)
PUSBD_INTERFACE_INFORMATION pInfo = &Urb->UrbSelectConfiguration.Interface;
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_DS4,
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d",
(int)pInfo->Length,
(int)pInfo->InterfaceNumber,
(int)pInfo->AlternateSetting,
static_cast<int>(pInfo->Length),
static_cast<int>(pInfo->InterfaceNumber),
static_cast<int>(pInfo->AlternateSetting),
pInfo->NumberOfPipes);
pInfo->Class = 0x03; // HID
pInfo->SubClass = 0x00;
pInfo->Protocol = 0x00;
pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)0xFFFF0000;
pInfo->InterfaceHandle = reinterpret_cast<USBD_INTERFACE_HANDLE>(0xFFFF0000);
pInfo->Pipes[0].MaximumTransferSize = 0x00400000;
pInfo->Pipes[0].MaximumPacketSize = 0x40;
pInfo->Pipes[0].EndpointAddress = 0x84;
pInfo->Pipes[0].Interval = 0x05;
pInfo->Pipes[0].PipeType = (USBD_PIPE_TYPE)0x03;
pInfo->Pipes[0].PipeHandle = (USBD_PIPE_HANDLE)0xFFFF0084;
pInfo->Pipes[0].PipeType = static_cast<USBD_PIPE_TYPE>(0x03);
pInfo->Pipes[0].PipeHandle = reinterpret_cast<USBD_PIPE_HANDLE>(0xFFFF0084);
pInfo->Pipes[0].PipeFlags = 0x00;
pInfo->Pipes[1].MaximumTransferSize = 0x00400000;
pInfo->Pipes[1].MaximumPacketSize = 0x40;
pInfo->Pipes[1].EndpointAddress = 0x03;
pInfo->Pipes[1].Interval = 0x05;
pInfo->Pipes[1].PipeType = (USBD_PIPE_TYPE)0x03;
pInfo->Pipes[1].PipeHandle = (USBD_PIPE_HANDLE)0xFFFF0003;
pInfo->Pipes[1].PipeType = static_cast<USBD_PIPE_TYPE>(0x03);
pInfo->Pipes[1].PipeHandle = reinterpret_cast<USBD_PIPE_HANDLE>(0xFFFF0003);
pInfo->Pipes[1].PipeFlags = 0x00;
return STATUS_SUCCESS;
@@ -496,10 +476,10 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbClassInterface(PURB Urb)
{
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST* pRequest = &Urb->UrbControlVendorClassRequest;
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
">> >> >> URB_FUNCTION_CLASS_INTERFACE");
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
">> >> >> TransferFlags = 0x%X, Request = 0x%X, Value = 0x%X, Index = 0x%X, BufLen = %d",
pRequest->TransferFlags,
@@ -515,7 +495,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbClassInterface(PURB Urb)
UCHAR reportId = hid_get_report_id(pRequest);
UCHAR reportType = hid_get_report_type(pRequest);
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
">> >> >> >> GET_REPORT(%d): %d",
reportType, reportId);
@@ -602,7 +582,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbClassInterface(PURB Urb)
UCHAR reportId = hid_get_report_id(pRequest);
UCHAR reportType = hid_get_report_type(pRequest);
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
">> >> >> >> SET_REPORT(%d): %d",
reportType, reportId);
@@ -900,7 +880,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbGetDescriptorFromInterface(
struct _URB_CONTROL_DESCRIPTOR_REQUEST* pRequest = &Urb->UrbControlDescriptorRequest;
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
">> >> >> _URB_CONTROL_DESCRIPTOR_REQUEST: Buffer Length %d",
pRequest->TransferBufferLength);
@@ -928,7 +908,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbSelectInterface(PURB Urb)
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbGetStringDescriptorType(PURB Urb)
{
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
"Index = %d",
Urb->UrbControlDescriptorRequest.Index);
@@ -950,7 +930,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbGetStringDescriptorType(PUR
}
case 1:
{
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
"LanguageId = 0x%X",
Urb->UrbControlDescriptorRequest.LanguageId);
@@ -981,7 +961,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbGetStringDescriptorType(PUR
}
case 2:
{
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_USBPDO,
"LanguageId = 0x%X",
Urb->UrbControlDescriptorRequest.LanguageId);
@@ -1017,14 +997,14 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbGetStringDescriptorType(PUR
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbBulkOrInterruptTransfer(_URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer, WDFREQUEST Request)
{
NTSTATUS status;
WDFREQUEST notifyRequest;
NTSTATUS status = STATUS_SUCCESS;
WDFREQUEST notifyRequest;
// Data coming FROM us TO higher driver
if (pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN
&& pTransfer->PipeHandle == reinterpret_cast<USBD_PIPE_HANDLE>(0xFFFF0084))
{
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
">> >> >> Incoming request, queuing...");
@@ -1041,16 +1021,46 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbBulkOrInterruptTransfer(_UR
static_cast<PUCHAR>(pTransfer->TransferBuffer) + DS4_OUTPUT_BUFFER_OFFSET,
DS4_OUTPUT_BUFFER_LENGTH);
// Notify user-mode process that new data is available
status = WdfIoQueueRetrieveNextRequest(this->_PendingNotificationRequests, &notifyRequest);
if (NT_SUCCESS(status))
this->_AwaitOutputCache.Size = sizeof(DS4_AWAIT_OUTPUT);
this->_AwaitOutputCache.SerialNo = this->_SerialNo;
RtlCopyMemory(
this->_AwaitOutputCache.Report.Buffer,
pTransfer->TransferBuffer,
pTransfer->TransferBufferLength <= sizeof(DS4_OUTPUT_BUFFER)
? pTransfer->TransferBufferLength
: sizeof(DS4_OUTPUT_BUFFER)
);
DumpAsHex("!! XUSB_REQUEST_NOTIFICATION",
&this->_AwaitOutputCache,
sizeof(DS4_AWAIT_OUTPUT)
);
if (!NT_SUCCESS(status = DMF_NotifyUserWithRequestMultiple_DataBroadcast(
this->_OutputReportNotify,
&this->_AwaitOutputCache,
sizeof(DS4_AWAIT_OUTPUT),
STATUS_SUCCESS
)))
{
PDS4_REQUEST_NOTIFICATION notify = NULL;
TraceError(
TRACE_USBPDO,
"DMF_NotifyUserWithRequestMultiple_DataBroadcast failed with status %!STATUS!",
status
);
}
if (NT_SUCCESS(WdfIoQueueRetrieveNextRequest(
this->_PendingNotificationRequests,
&notifyRequest)))
{
PDS4_REQUEST_NOTIFICATION notify = nullptr;
status = WdfRequestRetrieveOutputBuffer(
notifyRequest,
sizeof(DS4_REQUEST_NOTIFICATION),
notifyRequest,
sizeof(DS4_REQUEST_NOTIFICATION),
reinterpret_cast<PVOID*>(&notify),
nullptr
);
@@ -1062,17 +1072,45 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbBulkOrInterruptTransfer(_UR
notify->SerialNo = this->_SerialNo;
notify->Report = this->_OutputReport;
DumpAsHex("!! XUSB_REQUEST_NOTIFICATION",
notify,
sizeof(DS4_REQUEST_NOTIFICATION)
);
WdfRequestCompleteWithInformation(notifyRequest, status, notify->Size);
}
else
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_USBPDO,
"WdfRequestRetrieveOutputBuffer failed with status %!STATUS!",
status);
}
}
else
{
PVOID clientBuffer, contextBuffer;
if (NT_SUCCESS(DMF_BufferQueue_Fetch(
this->_UsbInterruptOutBufferQueue,
&clientBuffer,
&contextBuffer
)))
{
RtlCopyMemory(
clientBuffer,
&this->_OutputReport,
DS4_OUTPUT_BUFFER_LENGTH
);
*static_cast<size_t*>(contextBuffer) = DS4_OUTPUT_BUFFER_LENGTH;
TraceVerbose(TRACE_USBPDO, "Queued %Iu bytes", DS4_OUTPUT_BUFFER_LENGTH);
DMF_BufferQueue_Enqueue(this->_UsbInterruptOutBufferQueue, clientBuffer);
}
}
return status;
}
@@ -1106,8 +1144,13 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::UsbControlTransfer(PURB Urb)
NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::SubmitReportImpl(PVOID NewReport)
{
NTSTATUS status;
WDFREQUEST usbRequest;
NTSTATUS status;
WDFREQUEST usbRequest;
/*
* The logic here is unusual to keep backwards compatibility with the
* original API that didn't allow submitting the full report.
*/
status = WdfIoQueueRetrieveNextRequest(this->_PendingUsbInRequests, &usbRequest);
@@ -1118,19 +1161,52 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::SubmitReportImpl(PVOID NewRepo
PIRP pendingIrp = WdfRequestWdmGetIrp(usbRequest);
// Get USB request block
PURB urb = static_cast<PURB>(URB_FROM_IRP(pendingIrp));
const auto urb = static_cast<PURB>(URB_FROM_IRP(pendingIrp));
// Get transfer buffer
auto Buffer = static_cast<PUCHAR>(urb->UrbBulkOrInterruptTransfer.TransferBuffer);
const auto buffer = static_cast<PUCHAR>(urb->UrbBulkOrInterruptTransfer.TransferBuffer);
// Set correct buffer size
urb->UrbBulkOrInterruptTransfer.TransferBufferLength = DS4_REPORT_SIZE;
/* Copy report to cache and transfer buffer
* Skip first byte as it contains the never changing report id */
RtlCopyBytes(this->_Report + 1, &(static_cast<PDS4_SUBMIT_REPORT>(NewReport))->Report, sizeof(DS4_REPORT));
// Cast to expected struct
const auto pSubmit = static_cast<PDS4_SUBMIT_REPORT>(NewReport);
if (Buffer)
RtlCopyBytes(Buffer, this->_Report, DS4_REPORT_SIZE);
/*
* Copy report to cache and transfer buffer
* Skip first byte as it contains the never changing report ID
*/
//
// "Old" API which only allows to update partial report
//
if (pSubmit->Size == sizeof(DS4_SUBMIT_REPORT))
{
TraceVerbose(TRACE_DS4, "Received DS4_SUBMIT_REPORT update");
RtlCopyBytes(
&this->_Report[1],
&(static_cast<PDS4_SUBMIT_REPORT>(NewReport))->Report,
sizeof((static_cast<PDS4_SUBMIT_REPORT>(NewReport))->Report)
);
}
//
// "Extended" API allowing complete report update
//
if (pSubmit->Size == sizeof(DS4_SUBMIT_REPORT_EX))
{
TraceVerbose(TRACE_DS4, "Received DS4_SUBMIT_REPORT_EX update");
RtlCopyBytes(
&this->_Report[1],
&(static_cast<PDS4_SUBMIT_REPORT_EX>(NewReport))->Report,
sizeof((static_cast<PDS4_SUBMIT_REPORT_EX>(NewReport))->Report)
);
}
if (buffer)
RtlCopyBytes(buffer, this->_Report, DS4_REPORT_SIZE);
// Complete pending request
WdfRequestComplete(usbRequest, status);
@@ -1140,8 +1216,8 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetDS4::SubmitReportImpl(PVOID NewRepo
VOID ViGEm::Bus::Targets::EmulationTargetDS4::ReverseByteArray(PUCHAR Array, INT Length)
{
const auto s = static_cast<PUCHAR>(ExAllocatePoolWithTag(
NonPagedPool,
const auto s = static_cast<PUCHAR>(ExAllocatePoolZero(
NonPagedPoolNx,
sizeof(UCHAR) * Length,
'U4SD'
));
@@ -1173,42 +1249,121 @@ VOID ViGEm::Bus::Targets::EmulationTargetDS4::GenerateRandomMacAddress(PMAC_ADDR
Address->Nic2 = RtlRandomEx(&seed) % 0xFF;
}
void ViGEm::Bus::Targets::EmulationTargetDS4::ProcessPendingNotification(WDFQUEUE Queue)
{
NTSTATUS status;
WDFREQUEST request;
PVOID clientBuffer, contextBuffer;
PDS4_REQUEST_NOTIFICATION notify = nullptr;
FuncEntry(TRACE_DS4);
//
// Loop through and drain all queued requests until buffer is empty
//
while (NT_SUCCESS(WdfIoQueueRetrieveNextRequest(Queue, &request)))
{
status = DMF_BufferQueue_Dequeue(
this->_UsbInterruptOutBufferQueue,
&clientBuffer,
&contextBuffer
);
//
// Shouldn't happen, but if so, error out
//
if (!NT_SUCCESS(status))
{
//
// Don't requeue request as we maya be out of order now
//
WdfRequestComplete(request, status);
continue;
}
if (NT_SUCCESS(WdfRequestRetrieveOutputBuffer(
request,
sizeof(DS4_REQUEST_NOTIFICATION),
reinterpret_cast<PVOID*>(&notify),
nullptr
)))
{
//
// Assign values to output buffer
//
notify->Size = sizeof(DS4_REQUEST_NOTIFICATION);
notify->SerialNo = this->_SerialNo;
notify->Report = *static_cast<PDS4_OUTPUT_REPORT>(clientBuffer);
DumpAsHex("!! XUSB_REQUEST_NOTIFICATION",
notify,
sizeof(DS4_REQUEST_NOTIFICATION)
);
WdfRequestCompleteWithInformation(request, status, notify->Size);
}
DMF_BufferQueue_Reuse(this->_UsbInterruptOutBufferQueue, clientBuffer);
//
// If no more buffer to process, exit loop and await next callback
//
if (DMF_BufferQueue_Count(this->_UsbInterruptOutBufferQueue) == 0)
{
break;
}
}
TraceVerbose(TRACE_USBPDO, "%!FUNC! Exit");
}
VOID ViGEm::Bus::Targets::EmulationTargetDS4::PendingUsbRequestsTimerFunc(
_In_ WDFTIMER Timer
)
{
auto ctx = reinterpret_cast<EmulationTargetDS4*>(Core::EmulationTargetPdoGetContext(WdfTimerGetParentObject(Timer))->Target);
const auto ctx = reinterpret_cast<EmulationTargetDS4*>(Core::EmulationTargetPdoGetContext(
WdfTimerGetParentObject(Timer))->Target);
WDFREQUEST usbRequest;
PIRP pendingIrp;
PIO_STACK_LOCATION irpStack;
WDFREQUEST usbRequest;
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DS4, "%!FUNC! Entry");
FuncEntry(TRACE_DS4);
// Get pending USB request
NTSTATUS status = WdfIoQueueRetrieveNextRequest(ctx->_PendingUsbInRequests, &usbRequest);
const auto status = WdfIoQueueRetrieveNextRequest(ctx->_PendingUsbInRequests, &usbRequest);
if (NT_SUCCESS(status))
{
// Get pending IRP
pendingIrp = WdfRequestWdmGetIrp(usbRequest);
irpStack = IoGetCurrentIrpStackLocation(pendingIrp);
const auto pendingIrp = WdfRequestWdmGetIrp(usbRequest);
const auto irpStack = IoGetCurrentIrpStackLocation(pendingIrp);
// Get USB request block
PURB urb = (PURB)irpStack->Parameters.Others.Argument1;
const auto urb = static_cast<PURB>(irpStack->Parameters.Others.Argument1);
// Get transfer buffer
PUCHAR Buffer = (PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer;
const auto buffer = static_cast<PUCHAR>(urb->UrbBulkOrInterruptTransfer.TransferBuffer);
// Set buffer length to report size
urb->UrbBulkOrInterruptTransfer.TransferBufferLength = DS4_REPORT_SIZE;
// Copy cached report to transfer buffer
if (Buffer)
RtlCopyBytes(Buffer, ctx->_Report, DS4_REPORT_SIZE);
if (buffer)
RtlCopyBytes(buffer, ctx->_Report, DS4_REPORT_SIZE);
// Complete pending request
WdfRequestComplete(usbRequest, status);
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DS4, "%!FUNC! Exit with status %!STATUS!", status);
TraceVerbose(TRACE_DS4, "%!FUNC! Exit with status %!STATUS!", status);
}
VOID ViGEm::Bus::Targets::EmulationTargetDS4::DmfDeviceModulesAdd(_In_ PDMFMODULE_INIT DmfModuleInit)
{
UNREFERENCED_PARAMETER(DmfModuleInit);
}
VOID ViGEm::Bus::Targets::EmulationTargetDS4::SetOutputReportNotifyModule(DMFMODULE Module)
{
this->_OutputReportNotify = Module;
}

View File

@@ -1,29 +1,38 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2020, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "EmulationTargetPDO.hpp"
@@ -44,7 +53,7 @@ namespace ViGEm::Bus::Targets
UCHAR Nic1;
UCHAR Nic2;
} MAC_ADDRESS, * PMAC_ADDRESS;
constexpr unsigned char hid_get_report_id(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST* pReq)
{
return pReq->Value & 0xFF;
@@ -61,8 +70,8 @@ namespace ViGEm::Bus::Targets
EmulationTargetDS4(ULONG Serial, LONG SessionId, USHORT VendorId = 0x054C, USHORT ProductId = 0x05C4);
NTSTATUS PdoPrepareDevice(PWDFDEVICE_INIT DeviceInit,
PUNICODE_STRING DeviceId,
PUNICODE_STRING DeviceDescription) override;
PUNICODE_STRING DeviceId,
PUNICODE_STRING DeviceDescription) override;
NTSTATUS PdoPrepareHardware() override;
@@ -75,28 +84,35 @@ namespace ViGEm::Bus::Targets
NTSTATUS SelectConfiguration(PURB Urb) override;
void AbortPipe() override;
NTSTATUS UsbClassInterface(PURB Urb) override;
NTSTATUS UsbGetDescriptorFromInterface(PURB Urb) override;
NTSTATUS UsbSelectInterface(PURB Urb) override;
NTSTATUS UsbGetStringDescriptorType(PURB Urb) override;
NTSTATUS UsbBulkOrInterruptTransfer(_URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer, WDFREQUEST Request) override;
NTSTATUS UsbControlTransfer(PURB Urb) override;
NTSTATUS SubmitReportImpl(PVOID NewReport) override;
VOID SetOutputReportNotifyModule(DMFMODULE Module);
private:
static EVT_WDF_TIMER PendingUsbRequestsTimerFunc;
static VOID ReverseByteArray(PUCHAR Array, INT Length);
static VOID GenerateRandomMacAddress(PMAC_ADDRESS Address);
protected:
void ProcessPendingNotification(WDFQUEUE Queue) override;
void DmfDeviceModulesAdd(_In_ PDMFMODULE_INIT DmfModuleInit) override;
private:
static PCWSTR _deviceDescription;
static const int HID_REQUEST_GET_REPORT = 0x01;
@@ -147,6 +163,16 @@ namespace ViGEm::Bus::Targets
//
// Default MAC address of the host (not used)
//
MAC_ADDRESS _HostMacAddress;
MAC_ADDRESS _HostMacAddress;
//
// User-mode notification on new output report
//
DMFMODULE _OutputReportNotify;
//
// Memory for full output report request
//
DS4_AWAIT_OUTPUT _AwaitOutputCache;
};
}

View File

@@ -1,29 +1,38 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "EmulationTargetPDO.hpp"
#include "CRTCPP.hpp"
#include "trace.h"
@@ -48,6 +57,8 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
WDF_IO_QUEUE_CONFIG usbInQueueConfig;
WDF_IO_QUEUE_CONFIG notificationsQueueConfig;
PEMULATION_TARGET_PDO_CONTEXT pPdoContext;
PDMFDEVICE_INIT dmfDeviceInit = NULL;
DMF_EVENT_CALLBACKS dmfEventCallbacks;
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_BUSPDO, "%!FUNC! Entry");
@@ -62,11 +73,25 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
// set device type
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
// Bus is power policy owner
WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, FALSE);
do
{
dmfDeviceInit = DMF_DmfDeviceInitAllocate(DeviceInit);
if (dmfDeviceInit == NULL)
{
TraceError(
TRACE_BUSPDO,
"DMF_DmfDeviceInitAllocate failed"
);
status = STATUS_NO_MEMORY;
break;
}
DMF_DmfDeviceInitHookPnpPowerEventCallbacks(dmfDeviceInit, NULL);
DMF_DmfDeviceInitHookFileObjectConfig(dmfDeviceInit, NULL);
DMF_DmfDeviceInitHookPowerPolicyEventCallbacks(dmfDeviceInit, NULL);
#pragma region Prepare PDO
status = this->PdoPrepareDevice(DeviceInit, &deviceId, &deviceDescription);
@@ -78,7 +103,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
status = WdfPdoInitAssignDeviceID(DeviceInit, &deviceId);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfPdoInitAssignDeviceID failed with status %!STATUS!",
status);
@@ -89,7 +114,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
status = RtlUnicodeStringPrintf(&buffer, L"%02d", this->_SerialNo);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"RtlUnicodeStringPrintf failed with status %!STATUS!",
status);
@@ -100,7 +125,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
status = WdfPdoInitAssignInstanceID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfPdoInitAssignInstanceID failed with status %!STATUS!",
status);
@@ -111,7 +136,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
status = WdfPdoInitAddDeviceText(DeviceInit, &deviceDescription, &deviceLocation, 0x409);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfPdoInitAddDeviceText failed with status %!STATUS!",
status);
@@ -119,7 +144,6 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
}
// default locale is English
// TODO: add more locales
WdfPdoInitSetDefaultLocale(DeviceInit, 0x409);
#pragma region PNP/Power event callbacks
@@ -132,9 +156,6 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
#pragma endregion
// NOTE: not utilized at the moment
WdfPdoInitAllowForwardingRequestToParent(DeviceInit);
#pragma endregion
#pragma region Create PDO
@@ -147,14 +168,14 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
status = WdfDeviceCreate(&DeviceInit, &pdoAttributes, &this->_PdoDevice);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfDeviceCreate failed with status %!STATUS!",
status);
break;
}
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
"Created PDO 0x%p",
this->_PdoDevice);
@@ -170,7 +191,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfDeviceCreateDeviceInterface failed with status %!STATUS!",
status);
@@ -191,7 +212,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"Couldn't initialize additional contexts: %!STATUS!",
status);
@@ -201,7 +222,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
#pragma endregion
#pragma region Create Queues & Locks
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = this->_PdoDevice;
@@ -216,7 +237,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfIoQueueCreate (PendingUsbInRequests) failed with status %!STATUS!",
status);
@@ -237,13 +258,27 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfIoQueueCreate (PendingNotificationRequests) failed with status %!STATUS!",
status);
break;
}
status = WdfIoQueueReadyNotify(
this->_PendingNotificationRequests,
EvtWdfIoPendingNotificationQueueState,
this
);
if (!NT_SUCCESS(status))
{
TraceError(
TRACE_BUSPDO,
"WdfIoQueueReadyNotify (PendingNotificationRequests) failed with status %!STATUS!",
status);
break;
}
#pragma endregion
#pragma region Default I/O queue setup
@@ -255,6 +290,8 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
defaultPdoQueueConfig.EvtIoInternalDeviceControl = EvtIoInternalDeviceControl;
DMF_DmfDeviceInitHookQueueConfig(dmfDeviceInit, &defaultPdoQueueConfig);
status = WdfIoQueueCreate(
this->_PdoDevice,
&defaultPdoQueueConfig,
@@ -263,7 +300,7 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfIoQueueCreate (Default) failed with status %!STATUS!",
status);
@@ -294,8 +331,41 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoCreateDevice(WDFDEVICE ParentD
WdfDeviceSetPowerCapabilities(this->_PdoDevice, &this->_PowerCapabilities);
#pragma endregion
#pragma region DMF Initialization
DMF_EVENT_CALLBACKS_INIT(&dmfEventCallbacks);
dmfEventCallbacks.EvtDmfDeviceModulesAdd = DmfDeviceModulesAdd;
DMF_DmfDeviceInitSetEventCallbacks(dmfDeviceInit, &dmfEventCallbacks);
if (!NT_SUCCESS(status = DMF_ModulesCreate(
this->_PdoDevice,
&dmfDeviceInit
)))
{
TraceEvents(
TRACE_LEVEL_ERROR,
TRACE_DS4,
"DMF_ModulesCreate failed with status %!STATUS!",
status
);
break;
}
#pragma endregion
} while (FALSE);
if (dmfDeviceInit)
{
DMF_DmfDeviceInitFree(&dmfDeviceInit);
}
if (!NT_SUCCESS(status) && this->_PdoDevice != nullptr)
{
WdfObjectDelete(this->_PdoDevice);
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_BUSPDO, "%!FUNC! Exit with status %!STATUS!", status);
return status;
@@ -305,23 +375,23 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtDeviceContextCleanup(
IN WDFOBJECT Device
)
{
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_BUSPDO, "%!FUNC! Entry");
TraceVerbose(TRACE_BUSPDO, "%!FUNC! Entry");
const auto ctx = EmulationTargetPdoGetContext(Device);
//
// This queues parent is the FDO so explicitly free memory
//
WdfIoQueuePurgeSynchronously(ctx->Target->_PendingPlugInRequests);
WdfObjectDelete(ctx->Target->_PendingPlugInRequests);
WdfIoQueuePurgeSynchronously(ctx->Target->_WaitDeviceReadyRequests);
WdfObjectDelete(ctx->Target->_WaitDeviceReadyRequests);
//
// Wait for thread to finish, if active
//
if (ctx->Target->_PluginRequestCompletionWorkerThreadHandle)
if (ctx->Target->_WaitDeviceReadyCompletionWorkerThreadHandle)
{
NTSTATUS status = KeWaitForSingleObject(
&ctx->Target->_PluginRequestCompletionWorkerThreadHandle,
&ctx->Target->_WaitDeviceReadyCompletionWorkerThreadHandle,
Executive,
KernelMode,
FALSE,
@@ -330,8 +400,8 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtDeviceContextCleanup(
if (NT_SUCCESS(status))
{
ZwClose(ctx->Target->_PluginRequestCompletionWorkerThreadHandle);
ctx->Target->_PluginRequestCompletionWorkerThreadHandle = nullptr;
ZwClose(ctx->Target->_WaitDeviceReadyCompletionWorkerThreadHandle);
ctx->Target->_WaitDeviceReadyCompletionWorkerThreadHandle = nullptr;
}
else
{
@@ -342,13 +412,13 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtDeviceContextCleanup(
);
}
}
//
// PDO device object getting disposed, free context object
//
delete ctx->Target;
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_BUSPDO, "%!FUNC! Exit");
TraceVerbose(TRACE_BUSPDO, "%!FUNC! Exit");
}
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::SubmitReport(PVOID NewReport)
@@ -375,20 +445,20 @@ VIGEM_TARGET_TYPE ViGEm::Bus::Core::EmulationTargetPDO::GetType() const
return this->_TargetType;
}
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EnqueuePlugin(WDFREQUEST Request)
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EnqueueWaitDeviceReady(WDFREQUEST Request)
{
NTSTATUS status;
if (!this->IsOwnerProcess())
return STATUS_ACCESS_DENIED;
if (!this->_PendingPlugInRequests)
if (!this->_WaitDeviceReadyRequests)
return STATUS_INVALID_DEVICE_STATE;
if (this->_PluginRequestCompletionWorkerThreadHandle)
if (this->_WaitDeviceReadyCompletionWorkerThreadHandle)
{
status = KeWaitForSingleObject(
&this->_PluginRequestCompletionWorkerThreadHandle,
&this->_WaitDeviceReadyCompletionWorkerThreadHandle,
Executive,
KernelMode,
FALSE,
@@ -397,27 +467,27 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EnqueuePlugin(WDFREQUEST Request)
if (NT_SUCCESS(status))
{
ZwClose(this->_PluginRequestCompletionWorkerThreadHandle);
this->_PluginRequestCompletionWorkerThreadHandle = nullptr;
ZwClose(this->_WaitDeviceReadyCompletionWorkerThreadHandle);
this->_WaitDeviceReadyCompletionWorkerThreadHandle = nullptr;
}
else
{
TraceEvents(TRACE_LEVEL_WARNING,
TRACE_BUSPDO,
"KeWaitForSingleObject failed with status %!STATUS!",
status
TRACE_BUSPDO,
"KeWaitForSingleObject failed with status %!STATUS!",
status
);
}
}
status = WdfRequestForwardToIoQueue(Request, this->_PendingPlugInRequests);
status = WdfRequestForwardToIoQueue(Request, this->_WaitDeviceReadyRequests);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"WdfRequestForwardToIoQueue failed with status %!STATUS!",
status
TraceError(
TRACE_BUSPDO,
"WdfRequestForwardToIoQueue failed with status %!STATUS!",
status
);
return status;
@@ -426,23 +496,23 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EnqueuePlugin(WDFREQUEST Request)
OBJECT_ATTRIBUTES threadOb;
InitializeObjectAttributes(&threadOb, NULL,
OBJ_KERNEL_HANDLE, NULL, NULL);
OBJ_KERNEL_HANDLE, NULL, NULL);
status = PsCreateSystemThread(&this->_PluginRequestCompletionWorkerThreadHandle,
static_cast<ACCESS_MASK>(0L),
&threadOb,
nullptr,
nullptr,
PluginRequestCompletionWorkerRoutine,
this
status = PsCreateSystemThread(&this->_WaitDeviceReadyCompletionWorkerThreadHandle,
static_cast<ACCESS_MASK>(0L),
&threadOb,
nullptr,
nullptr,
WaitDeviceReadyCompletionWorkerRoutine,
this
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_BUSPDO,
"PsCreateSystemThread failed with status %!STATUS!",
status
TraceError(
TRACE_BUSPDO,
"PsCreateSystemThread failed with status %!STATUS!",
status
);
}
@@ -454,7 +524,9 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoPrepare(WDFDEVICE ParentDevice
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
WDF_IO_QUEUE_CONFIG plugInQueueConfig;
DMF_MODULE_ATTRIBUTES moduleAttributes;
DMF_CONFIG_BufferQueue dmfBufferCfg;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = ParentDevice;
@@ -465,16 +537,51 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::PdoPrepare(WDFDEVICE ParentDevice
ParentDevice,
&plugInQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&this->_PendingPlugInRequests
&this->_WaitDeviceReadyRequests
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSPDO,
"WdfIoQueueCreate (PendingPlugInRequests) failed with status %!STATUS!",
status);
}
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = ParentDevice;
DMF_CONFIG_BufferQueue_AND_ATTRIBUTES_INIT(
&dmfBufferCfg,
&moduleAttributes
);
// Don't auto-grow; start dropping packets on overrun
dmfBufferCfg.SourceSettings.EnableLookAside = FALSE;
// Maximum number of buffers to be filled and kept queued
dmfBufferCfg.SourceSettings.BufferCount = MAX_OUT_BUFFER_QUEUE_COUNT;
// Maximum byte count per buffer
dmfBufferCfg.SourceSettings.BufferSize = MAX_OUT_BUFFER_QUEUE_SIZE;
// Field to store real buffer content length
dmfBufferCfg.SourceSettings.BufferContextSize = sizeof(size_t);
// "Expensive" memory ;)
dmfBufferCfg.SourceSettings.PoolType = NonPagedPoolNx;
status = DMF_BufferQueue_Create(
ParentDevice,
&moduleAttributes,
&attributes,
&this->_UsbInterruptOutBufferQueue
);
if (!NT_SUCCESS(status))
{
TraceError(
TRACE_BUSPDO,
"DMF_BufferQueue_Create failed with status %!STATUS!",
status
);
}
return status;
}
@@ -546,17 +653,17 @@ VOID USB_BUSIFFN ViGEm::Bus::Core::EmulationTargetPDO::UsbInterfaceGetUSBDIVersi
#pragma endregion
VOID ViGEm::Bus::Core::EmulationTargetPDO::PluginRequestCompletionWorkerRoutine(IN PVOID StartContext)
VOID ViGEm::Bus::Core::EmulationTargetPDO::WaitDeviceReadyCompletionWorkerRoutine(IN PVOID StartContext)
{
const auto ctx = static_cast<EmulationTargetPDO*>(StartContext);
WDFREQUEST pluginRequest;
WDFREQUEST waitRequest;
LARGE_INTEGER timeout;
timeout.QuadPart = WDF_REL_TIMEOUT_IN_SEC(1);
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_BUSPDO,
"Waiting for 1 second to complete PDO boot..."
TRACE_BUSPDO,
"Waiting for 1 second to complete PDO boot..."
);
NTSTATUS status = KeWaitForSingleObject(
@@ -572,11 +679,11 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::PluginRequestCompletionWorkerRoutine(
//
// Fetch pending request (there has to be one at this point)
//
if (!NT_SUCCESS(WdfIoQueueRetrieveNextRequest(ctx->_PendingPlugInRequests, &pluginRequest)))
if (!NT_SUCCESS(WdfIoQueueRetrieveNextRequest(ctx->_WaitDeviceReadyRequests, &waitRequest)))
{
TraceEvents(TRACE_LEVEL_WARNING,
TRACE_BUSPDO,
"No pending plugin request available"
TRACE_BUSPDO,
"No pending device wait request available"
);
break;
}
@@ -584,35 +691,34 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::PluginRequestCompletionWorkerRoutine(
if (status == STATUS_TIMEOUT)
{
TraceEvents(TRACE_LEVEL_WARNING,
TRACE_BUSPDO,
"Plugin request timed out, completing with error"
TRACE_BUSPDO,
"Device wait request timed out, completing with error"
);
//
// We haven't hit a path where the event gets signaled, report error
//
WdfRequestComplete(pluginRequest, STATUS_DEVICE_HARDWARE_ERROR);
WdfRequestComplete(waitRequest, STATUS_DEVICE_HARDWARE_ERROR);
break;
}
if (NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_BUSPDO,
"Plugin request completed successfully"
TRACE_BUSPDO,
"Device wait request completed successfully"
);
//
// Event triggered in time, complete with success
//
WdfRequestComplete(pluginRequest, STATUS_SUCCESS);
WdfRequestComplete(waitRequest, STATUS_SUCCESS);
break;
}
}
while (FALSE);
} while (FALSE);
ZwClose(ctx->_PluginRequestCompletionWorkerThreadHandle);
ctx->_PluginRequestCompletionWorkerThreadHandle = nullptr;
ZwClose(ctx->_WaitDeviceReadyCompletionWorkerThreadHandle);
ctx->_WaitDeviceReadyCompletionWorkerThreadHandle = nullptr;
KeClearEvent(&ctx->_PdoBootNotificationEvent);
(void)PsTerminateSystemThread(0);
}
@@ -622,7 +728,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::DumpAsHex(PCSTR Prefix, PVOID Buffer,
#ifdef DBG
size_t dumpBufferLength = ((BufferLength * sizeof(CHAR)) * 2) + 1;
PSTR dumpBuffer = static_cast<PSTR>(ExAllocatePoolWithTag(
PSTR dumpBuffer = static_cast<PSTR>(ExAllocatePoolZero(
NonPagedPoolNx,
dumpBufferLength,
'1234'
@@ -637,7 +743,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::DumpAsHex(PCSTR Prefix, PVOID Buffer,
sprintf(&dumpBuffer[i * 2], "%02X", static_cast<PUCHAR>(Buffer)[i]);
}
TraceDbg(TRACE_BUSPDO,
TraceVerbose(TRACE_BUSPDO,
"%s - Buffer length: %04d, buffer content: %s\n",
Prefix,
BufferLength,
@@ -689,14 +795,14 @@ NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::UsbGetConfigurationDescriptorType
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::UsbSelectConfiguration(PURB Urb)
{
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: TotalLength %d",
Urb->UrbHeader.Length);
if (Urb->UrbHeader.Length == sizeof(struct _URB_SELECT_CONFIGURATION))
{
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: NULL ConfigurationDescriptor");
return STATUS_SUCCESS;
@@ -752,13 +858,96 @@ bool ViGEm::Bus::Core::EmulationTargetPDO::GetPdoByTypeAndSerial(IN WDFDEVICE Pa
return (GetPdoBySerial(ParentDevice, SerialNo, Object) && (*Object)->GetType() == Type);
}
BOOLEAN ViGEm::Bus::Core::EmulationTargetPDO::EvtChildListIdentificationDescriptionCompare(
WDFCHILDLIST DeviceList,
PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER FirstIdentificationDescription,
PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER SecondIdentificationDescription)
{
ViGEm::Bus::Core::PPDO_IDENTIFICATION_DESCRIPTION lhs, rhs;
UNREFERENCED_PARAMETER(DeviceList);
lhs = CONTAINING_RECORD(FirstIdentificationDescription,
ViGEm::Bus::Core::PDO_IDENTIFICATION_DESCRIPTION,
Header);
rhs = CONTAINING_RECORD(SecondIdentificationDescription,
ViGEm::Bus::Core::PDO_IDENTIFICATION_DESCRIPTION,
Header);
return (lhs->SerialNo == rhs->SerialNo) ? TRUE : FALSE;
}
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EnqueueWaitDeviceReady(WDFDEVICE ParentDevice, ULONG SerialNo,
WDFREQUEST Request)
{
NTSTATUS status;
PDO_IDENTIFICATION_DESCRIPTION description;
WDF_CHILD_LIST_ITERATOR iterator;
WDF_CHILD_RETRIEVE_INFO childInfo;
WDFDEVICE childDevice;
FuncEntry(TRACE_BUSPDO);
const WDFCHILDLIST list = WdfFdoGetDefaultChildList(ParentDevice);
WDF_CHILD_LIST_ITERATOR_INIT(
&iterator,
WdfRetrieveAddedChildren // might not be online yet
);
WdfChildListBeginIteration(
list,
&iterator
);
WDF_CHILD_RETRIEVE_INFO_INIT(
&childInfo,
&description.Header
);
//
// Compare to find explicit PDO asked for (by serial)
//
childInfo.EvtChildListIdentificationDescriptionCompare = EvtChildListIdentificationDescriptionCompare;
WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(
&description.Header,
sizeof(description)
);
// ReSharper disable once CppAssignedValueIsNeverUsed
description.SerialNo = SerialNo;
status = WdfChildListRetrieveNextDevice(
list,
&iterator,
&childDevice, // is NULL due to WdfRetrievePendingChildren
&childInfo
);
if (NT_SUCCESS(status))
{
//
// Object pointer filled after successful retrieval
//
status = description.Target->EnqueueWaitDeviceReady(Request);
}
WdfChildListEndIteration(
list,
&iterator
);
TraceVerbose(TRACE_BUSPDO, "%!FUNC! Exit with status %!STATUS!", status);
return status;
}
NTSTATUS ViGEm::Bus::Core::EmulationTargetPDO::EvtDevicePrepareHardware(
_In_ WDFDEVICE Device,
_In_ WDFCMRESLIST ResourcesRaw,
_In_ WDFCMRESLIST ResourcesTranslated
)
{
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_BUSPDO, "%!FUNC! Entry");
FuncEntry(TRACE_BUSPDO);
UNREFERENCED_PARAMETER(ResourcesRaw);
UNREFERENCED_PARAMETER(ResourcesTranslated);
@@ -790,7 +979,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
PURB urb;
PIO_STACK_LOCATION irpStack;
TraceDbg(TRACE_BUSPDO, "%!FUNC! Entry");
FuncEntry(TRACE_BUSPDO);
// No help from the framework available from here on
irp = WdfRequestWdmGetIrp(Request);
@@ -800,7 +989,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
{
case IOCTL_INTERNAL_USB_SUBMIT_URB:
TraceDbg(
TraceVerbose(
TRACE_BUSPDO,
">> IOCTL_INTERNAL_USB_SUBMIT_URB");
@@ -810,7 +999,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
{
case URB_FUNCTION_CONTROL_TRANSFER:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_CONTROL_TRANSFER");
@@ -820,7 +1009,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_CONTROL_TRANSFER_EX:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_CONTROL_TRANSFER_EX");
@@ -830,7 +1019,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
TraceDbg(
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER");
@@ -840,7 +1029,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_SELECT_CONFIGURATION:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_SELECT_CONFIGURATION");
@@ -850,7 +1039,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_SELECT_INTERFACE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_SELECT_INTERFACE");
@@ -860,7 +1049,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE");
@@ -868,7 +1057,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
{
case USB_DEVICE_DESCRIPTOR_TYPE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> >> USB_DEVICE_DESCRIPTOR_TYPE");
@@ -879,7 +1068,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> >> USB_CONFIGURATION_DESCRIPTOR_TYPE");
@@ -889,7 +1078,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case USB_STRING_DESCRIPTOR_TYPE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> >> USB_STRING_DESCRIPTOR_TYPE");
@@ -899,14 +1088,14 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
default:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> >> Unknown descriptor type");
break;
}
TraceDbg(
TraceVerbose(
TRACE_BUSPDO,
"<< <<");
@@ -914,7 +1103,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_GET_STATUS_FROM_DEVICE");
@@ -925,7 +1114,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_ABORT_PIPE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_ABORT_PIPE");
@@ -935,7 +1124,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_CLASS_INTERFACE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_CLASS_INTERFACE");
@@ -945,7 +1134,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE");
@@ -955,7 +1144,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
default:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> >> Unknown function: 0x%X",
urb->UrbHeader.Function);
@@ -963,7 +1152,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
break;
}
TraceDbg(
TraceVerbose(
TRACE_BUSPDO,
"<<");
@@ -971,7 +1160,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> IOCTL_INTERNAL_USB_GET_PORT_STATUS");
@@ -984,7 +1173,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case IOCTL_INTERNAL_USB_RESET_PORT:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> IOCTL_INTERNAL_USB_RESET_PORT");
@@ -995,7 +1184,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION");
@@ -1007,7 +1196,7 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
default:
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSPDO,
">> Unknown I/O control code 0x%X",
IoControlCode);
@@ -1020,5 +1209,30 @@ VOID ViGEm::Bus::Core::EmulationTargetPDO::EvtIoInternalDeviceControl(
WdfRequestComplete(Request, status);
}
TraceDbg(TRACE_BUSPDO, "%!FUNC! Exit with status %!STATUS!", status);
TraceVerbose(TRACE_BUSPDO, "%!FUNC! Exit with status %!STATUS!", status);
}
void ViGEm::Bus::Core::EmulationTargetPDO::EvtWdfIoPendingNotificationQueueState(
WDFQUEUE Queue,
WDFCONTEXT Context
)
{
const auto pThis = static_cast<EmulationTargetPDO*>(Context);
//
// No buffer available to answer the request with, leave queued
//
if (DMF_BufferQueue_Count(pThis->_UsbInterruptOutBufferQueue) == 0)
{
return;
}
pThis->ProcessPendingNotification(Queue);
}
VOID ViGEm::Bus::Core::EmulationTargetPDO::DmfDeviceModulesAdd(_In_ WDFDEVICE Device, _In_ PDMFMODULE_INIT DmfModuleInit)
{
const auto pThis = static_cast<EmulationTargetPDO*>(EmulationTargetPdoGetContext(Device)->Target);
pThis->DmfDeviceModulesAdd(DmfModuleInit);
}

View File

@@ -1,31 +1,43 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2020, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#pragma warning(disable:5040)
#include <DmfModules.Library.h>
#pragma warning(default:5040)
#include <ntddk.h>
#include <wdf.h>
#include <ntintsafe.h>
@@ -34,7 +46,6 @@
#include <usbbusif.h>
#include <ViGEm/Common.h>
#include <initguid.h>
//
// Some insane macro-magic =3
@@ -53,24 +64,31 @@ namespace ViGEm::Bus::Core
EmulationTargetPDO(ULONG Serial, LONG SessionId, USHORT VendorId, USHORT ProductId);
virtual ~EmulationTargetPDO() = default;
static bool GetPdoByTypeAndSerial(
IN WDFDEVICE ParentDevice,
IN VIGEM_TARGET_TYPE Type,
IN ULONG SerialNo,
IN ULONG SerialNo,
OUT EmulationTargetPDO** Object
);
static NTSTATUS EnqueueWaitDeviceReady(
WDFDEVICE ParentDevice,
ULONG SerialNo,
WDFREQUEST Request);
static EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE EvtChildListIdentificationDescriptionCompare;
virtual NTSTATUS PdoPrepareDevice(PWDFDEVICE_INIT DeviceInit,
PUNICODE_STRING DeviceId,
PUNICODE_STRING DeviceDescription) = 0;
PUNICODE_STRING DeviceId,
PUNICODE_STRING DeviceDescription) = 0;
virtual NTSTATUS PdoPrepareHardware() = 0;
virtual NTSTATUS PdoInitContext() = 0;
NTSTATUS PdoCreateDevice(_In_ WDFDEVICE ParentDevice,
_In_ PWDFDEVICE_INIT DeviceInit);
_In_ PWDFDEVICE_INIT DeviceInit);
bool operator==(EmulationTargetPDO& other) const
{
@@ -94,7 +112,7 @@ namespace ViGEm::Bus::Core
virtual NTSTATUS UsbGetStringDescriptorType(PURB Urb) = 0;
virtual NTSTATUS UsbBulkOrInterruptTransfer(struct _URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer,
WDFREQUEST Request) = 0;
WDFREQUEST Request) = 0;
virtual NTSTATUS UsbControlTransfer(PURB Urb) = 0;
@@ -106,10 +124,8 @@ namespace ViGEm::Bus::Core
VIGEM_TARGET_TYPE GetType() const;
NTSTATUS EnqueuePlugin(WDFREQUEST Request);
NTSTATUS PdoPrepare(WDFDEVICE ParentDevice);
private:
static unsigned long current_process_id();
@@ -121,13 +137,19 @@ namespace ViGEm::Bus::Core
OUT EmulationTargetPDO** Object
);
HANDLE _PluginRequestCompletionWorkerThreadHandle{};
NTSTATUS EnqueueWaitDeviceReady(WDFREQUEST Request);
HANDLE _WaitDeviceReadyCompletionWorkerThreadHandle{};
protected:
static const ULONG _maxHardwareIdLength = 0xFF;
static const int MAX_INSTANCE_ID_LEN = 80;
static const size_t MAX_OUT_BUFFER_QUEUE_COUNT = 64;
static const size_t MAX_OUT_BUFFER_QUEUE_SIZE = 128;
static PCWSTR _deviceLocation;
static BOOLEAN USB_BUSIFFN UsbInterfaceIsDeviceHighSpeed(IN PVOID BusContext);
@@ -154,8 +176,14 @@ namespace ViGEm::Bus::Core
static EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL EvtIoInternalDeviceControl;
static VOID PluginRequestCompletionWorkerRoutine(IN PVOID StartContext);
static EVT_WDF_IO_QUEUE_STATE EvtWdfIoPendingNotificationQueueState;
static VOID WaitDeviceReadyCompletionWorkerRoutine(IN PVOID StartContext);
static VOID DumpAsHex(PCSTR Prefix, PVOID Buffer, ULONG BufferLength);
static VOID DmfDeviceModulesAdd(_In_ WDFDEVICE Device, _In_ PDMFMODULE_INIT DmfModuleInit);
virtual VOID GetConfigurationDescriptorType(PUCHAR Buffer, ULONG Length) = 0;
virtual NTSTATUS SelectConfiguration(PURB Urb) = 0;
@@ -164,7 +192,9 @@ namespace ViGEm::Bus::Core
virtual NTSTATUS SubmitReportImpl(PVOID NewReport) = 0;
static VOID DumpAsHex(PCSTR Prefix, PVOID Buffer, ULONG BufferLength);
virtual VOID ProcessPendingNotification(WDFQUEUE Queue) = 0;
virtual void DmfDeviceModulesAdd(_In_ PDMFMODULE_INIT DmfModuleInit) = 0;
//
// PNP Capabilities may differ from device to device
@@ -175,7 +205,7 @@ namespace ViGEm::Bus::Core
// Power Capabilities may differ from device to device
//
WDF_DEVICE_POWER_CAPABILITIES _PowerCapabilities;
//
// Unique serial number of the device on the bus
//
@@ -209,8 +239,8 @@ namespace ViGEm::Bus::Core
//
// Queue for blocking plugin requests
//
WDFQUEUE _PendingPlugInRequests{};
WDFQUEUE _WaitDeviceReadyRequests{};
//
// Queue for incoming data interrupt transfer
//
@@ -225,7 +255,7 @@ namespace ViGEm::Bus::Core
// This child objects' device object
//
WDFDEVICE _PdoDevice{};
//
// Configuration descriptor size (populated by derived class)
//
@@ -235,6 +265,11 @@ namespace ViGEm::Bus::Core
// Signals the bus that PDO is ready to receive data
//
KEVENT _PdoBootNotificationEvent;
//
// Queue for interrupt out requests delivered to user-land
//
DMFMODULE _UsbInterruptOutBufferQueue{};
};
typedef struct _PDO_IDENTIFICATION_DESCRIPTION
@@ -258,12 +293,12 @@ namespace ViGEm::Bus::Core
// Context object of PDO
//
EmulationTargetPDO* Target;
} PDO_IDENTIFICATION_DESCRIPTION, *PPDO_IDENTIFICATION_DESCRIPTION;
} PDO_IDENTIFICATION_DESCRIPTION, * PPDO_IDENTIFICATION_DESCRIPTION;
typedef struct _EMULATION_TARGET_PDO_CONTEXT
{
EmulationTargetPDO* Target;
} EMULATION_TARGET_PDO_CONTEXT, *PEMULATION_TARGET_PDO_CONTEXT;
} EMULATION_TARGET_PDO_CONTEXT, * PEMULATION_TARGET_PDO_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(EMULATION_TARGET_PDO_CONTEXT, EmulationTargetPdoGetContext)
}

View File

@@ -1,42 +1,46 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "busenum.h"
#include "queue.tmh"
#include "Driver.h"
#include "trace.h"
#include "Queue.tmh"
#include "EmulationTargetPDO.hpp"
#include "XusbPdo.hpp"
#include "Ds4Pdo.hpp"
#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, Bus_EvtIoDefault)
#endif
using ViGEm::Bus::Core::PDO_IDENTIFICATION_DESCRIPTION;
using ViGEm::Bus::Core::EmulationTargetPDO;
using ViGEm::Bus::Targets::EmulationTargetXUSB;
@@ -45,376 +49,483 @@ using ViGEm::Bus::Targets::EmulationTargetDS4;
EXTERN_C_START
//
// Responds to I/O control requests sent to the FDO.
//
VOID Bus_EvtIoDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
NTSTATUS
Bus_CheckVersionHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
WDFDEVICE Device;
size_t length = 0;
PXUSB_SUBMIT_REPORT xusbSubmit = nullptr;
PXUSB_REQUEST_NOTIFICATION xusbNotify = nullptr;
PDS4_SUBMIT_REPORT ds4Submit = nullptr;
PDS4_REQUEST_NOTIFICATION ds4Notify = nullptr;
PVIGEM_CHECK_VERSION pCheckVersion = nullptr;
PXUSB_GET_USER_INDEX pXusbGetUserIndex = nullptr;
EmulationTargetPDO* pdo;
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Queue);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
Device = WdfIoQueueGetDevice(Queue);
FuncEntry(TRACE_QUEUE);
TraceDbg(TRACE_QUEUE, "%!FUNC! Entry (device: 0x%p)", Device);
PVIGEM_CHECK_VERSION pCheckVersion = (PVIGEM_CHECK_VERSION)InputBuffer;
switch (IoControlCode)
{
#pragma region IOCTL_VIGEM_CHECK_VERSION
NTSTATUS status = (pCheckVersion->Version == VIGEM_COMMON_VERSION) ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED;
case IOCTL_VIGEM_CHECK_VERSION:
TraceVerbose(
TRACE_QUEUE,
"Requested version: 0x%04X, compiled version: 0x%04X",
pCheckVersion->Version, VIGEM_COMMON_VERSION);
TraceDbg(TRACE_QUEUE, "IOCTL_VIGEM_CHECK_VERSION");
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
status = WdfRequestRetrieveInputBuffer(
Request,
sizeof(VIGEM_CHECK_VERSION),
reinterpret_cast<PVOID*>(&pCheckVersion),
&length
);
if (!NT_SUCCESS(status) || length != sizeof(VIGEM_CHECK_VERSION))
{
status = STATUS_INVALID_PARAMETER;
break;
}
status = (pCheckVersion->Version == VIGEM_COMMON_VERSION) ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED;
TraceEvents(TRACE_LEVEL_VERBOSE,
TRACE_QUEUE,
"Requested version: 0x%04X, compiled version: 0x%04X",
pCheckVersion->Version, VIGEM_COMMON_VERSION);
break;
#pragma endregion
#pragma region IOCTL_VIGEM_PLUGIN_TARGET
case IOCTL_VIGEM_PLUGIN_TARGET:
TraceDbg(TRACE_QUEUE, "IOCTL_VIGEM_PLUGIN_TARGET");
status = Bus_PlugInDevice(Device, Request, FALSE, &length);
break;
#pragma endregion
#pragma region IOCTL_VIGEM_UNPLUG_TARGET
case IOCTL_VIGEM_UNPLUG_TARGET:
TraceDbg(TRACE_QUEUE, "IOCTL_VIGEM_UNPLUG_TARGET");
status = Bus_UnPlugDevice(Device, Request, FALSE, &length);
break;
#pragma endregion
#pragma region IOCTL_XUSB_SUBMIT_REPORT
case IOCTL_XUSB_SUBMIT_REPORT:
TraceDbg(TRACE_QUEUE, "IOCTL_XUSB_SUBMIT_REPORT");
status = WdfRequestRetrieveInputBuffer(
Request,
sizeof(XUSB_SUBMIT_REPORT),
reinterpret_cast<PVOID*>(&xusbSubmit),
&length
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"WdfRequestRetrieveInputBuffer failed with status %!STATUS!",
status);
break;
}
if ((sizeof(XUSB_SUBMIT_REPORT) == xusbSubmit->Size) && (length == InputBufferLength))
{
// This request only supports a single PDO at a time
if (xusbSubmit->SerialNo == 0)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
break;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(Device, Xbox360Wired, xusbSubmit->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
status = pdo->SubmitReport(xusbSubmit);
}
break;
#pragma endregion
#pragma region IOCTL_XUSB_REQUEST_NOTIFICATION
case IOCTL_XUSB_REQUEST_NOTIFICATION:
TraceDbg(TRACE_QUEUE, "IOCTL_XUSB_REQUEST_NOTIFICATION");
// Don't accept the request if the output buffer can't hold the results
if (OutputBufferLength < sizeof(XUSB_REQUEST_NOTIFICATION))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"Output buffer %d too small, require at least %d",
static_cast<int>(OutputBufferLength), static_cast<int>(sizeof(XUSB_REQUEST_NOTIFICATION)));
break;
}
status = WdfRequestRetrieveInputBuffer(
Request,
sizeof(XUSB_REQUEST_NOTIFICATION),
reinterpret_cast<PVOID*>(&xusbNotify),
&length
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"WdfRequestRetrieveInputBuffer failed with status %!STATUS!",
status);
break;
}
if ((sizeof(XUSB_REQUEST_NOTIFICATION) == xusbNotify->Size) && (length == InputBufferLength))
{
// This request only supports a single PDO at a time
if (xusbNotify->SerialNo == 0)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
break;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(Device, Xbox360Wired, xusbNotify->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
{
status = pdo->EnqueueNotification(Request);
status = (NT_SUCCESS(status)) ? STATUS_PENDING : status;
}
}
break;
#pragma endregion
#pragma region IOCTL_DS4_SUBMIT_REPORT
case IOCTL_DS4_SUBMIT_REPORT:
TraceDbg(TRACE_QUEUE, "IOCTL_DS4_SUBMIT_REPORT");
status = WdfRequestRetrieveInputBuffer(
Request,
sizeof(DS4_SUBMIT_REPORT),
reinterpret_cast<PVOID*>(&ds4Submit),
&length
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"WdfRequestRetrieveInputBuffer failed with status %!STATUS!",
status);
break;
}
if ((sizeof(DS4_SUBMIT_REPORT) == ds4Submit->Size) && (length == InputBufferLength))
{
// This request only supports a single PDO at a time
if (ds4Submit->SerialNo == 0)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
break;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(Device, DualShock4Wired, ds4Submit->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
status = pdo->SubmitReport(ds4Submit);
}
break;
#pragma endregion
#pragma region IOCTL_DS4_REQUEST_NOTIFICATION
case IOCTL_DS4_REQUEST_NOTIFICATION:
TraceDbg(TRACE_QUEUE, "IOCTL_DS4_REQUEST_NOTIFICATION");
// Don't accept the request if the output buffer can't hold the results
if (OutputBufferLength < sizeof(DS4_REQUEST_NOTIFICATION))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"Output buffer %d too small, require at least %d",
static_cast<int>(OutputBufferLength), static_cast<int>(sizeof(DS4_REQUEST_NOTIFICATION)));
break;
}
status = WdfRequestRetrieveInputBuffer(
Request,
sizeof(DS4_REQUEST_NOTIFICATION),
reinterpret_cast<PVOID*>(&ds4Notify),
&length
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"WdfRequestRetrieveInputBuffer failed with status %!STATUS!",
status);
break;
}
if ((sizeof(DS4_REQUEST_NOTIFICATION) == ds4Notify->Size) && (length == InputBufferLength))
{
// This request only supports a single PDO at a time
if (ds4Notify->SerialNo == 0)
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
break;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(Device, DualShock4Wired, ds4Notify->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
{
status = pdo->EnqueueNotification(Request);
status = (NT_SUCCESS(status)) ? STATUS_PENDING : status;
}
}
break;
#pragma endregion
#pragma region IOCTL_XUSB_GET_USER_INDEX
case IOCTL_XUSB_GET_USER_INDEX:
TraceDbg(TRACE_QUEUE, "IOCTL_XUSB_GET_USER_INDEX");
// Don't accept the request if the output buffer can't hold the results
if (OutputBufferLength < sizeof(XUSB_GET_USER_INDEX))
{
KdPrint((DRIVERNAME "IOCTL_XUSB_GET_USER_INDEX: output buffer too small: %ul\n", OutputBufferLength));
break;
}
status = WdfRequestRetrieveInputBuffer(
Request,
sizeof(XUSB_GET_USER_INDEX),
reinterpret_cast<PVOID*>(&pXusbGetUserIndex),
&length);
if (!NT_SUCCESS(status))
{
KdPrint((DRIVERNAME "WdfRequestRetrieveInputBuffer failed 0x%x\n", status));
break;
}
if ((sizeof(XUSB_GET_USER_INDEX) == pXusbGetUserIndex->Size) && (length == InputBufferLength))
{
// This request only supports a single PDO at a time
if (pXusbGetUserIndex->SerialNo == 0)
{
status = STATUS_INVALID_PARAMETER;
break;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(Device, Xbox360Wired, pXusbGetUserIndex->SerialNo, &pdo))
{
status = STATUS_DEVICE_DOES_NOT_EXIST;
break;
}
status = static_cast<EmulationTargetXUSB*>(pdo)->GetUserIndex(&pXusbGetUserIndex->UserIndex);
}
break;
#pragma endregion
default:
TraceEvents(TRACE_LEVEL_WARNING,
TRACE_QUEUE,
"Unknown I/O control code 0x%X", IoControlCode);
break; // default status is STATUS_INVALID_PARAMETER
}
if (status != STATUS_PENDING)
{
WdfRequestCompleteWithInformation(Request, status, length);
}
TraceDbg(TRACE_QUEUE, "%!FUNC! Exit with status %!STATUS!", status);
return status;
}
//
// Catches unsupported requests.
//
VOID Bus_EvtIoDefault(
NTSTATUS
Bus_WaitDeviceReadyHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
NTSTATUS status;
FuncEntry(TRACE_QUEUE);
PVIGEM_WAIT_DEVICE_READY pWaitDeviceReady = (PVIGEM_WAIT_DEVICE_READY)InputBuffer;
// This request only supports a single PDO at a time
if (pWaitDeviceReady->SerialNo == 0)
{
TraceError(
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
goto exit;
}
status = EmulationTargetPDO::EnqueueWaitDeviceReady(
WdfIoQueueGetDevice(Queue),
pWaitDeviceReady->SerialNo,
Request
);
status = NT_SUCCESS(status) ? STATUS_PENDING : STATUS_DEVICE_DOES_NOT_EXIST;
exit:
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_PluginTargetHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(InputBuffer);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
FuncEntry(TRACE_QUEUE);
NTSTATUS status = Bus_PlugInDevice(WdfIoQueueGetDevice(Queue), Request, FALSE, BytesReturned);
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_UnplugTargetHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(InputBuffer);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
FuncEntry(TRACE_QUEUE);
NTSTATUS status = Bus_UnPlugDevice(WdfIoQueueGetDevice(Queue), Request, FALSE, BytesReturned);
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_XusbSubmitReportHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(InputBuffer);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
FuncEntry(TRACE_QUEUE);
NTSTATUS status;
EmulationTargetPDO* pdo;
PXUSB_SUBMIT_REPORT xusbSubmit = (PXUSB_SUBMIT_REPORT)InputBuffer;
// This request only supports a single PDO at a time
if (xusbSubmit->SerialNo == 0)
{
TraceError(
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
goto exit;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(WdfIoQueueGetDevice(Queue), Xbox360Wired, xusbSubmit->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
status = pdo->SubmitReport(xusbSubmit);
exit:
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_XusbRequestNotificationHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(InputBuffer);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
FuncEntry(TRACE_QUEUE);
NTSTATUS status;
EmulationTargetPDO* pdo;
PXUSB_REQUEST_NOTIFICATION xusbNotify = (PXUSB_REQUEST_NOTIFICATION)InputBuffer;
// This request only supports a single PDO at a time
if (xusbNotify->SerialNo == 0)
{
TraceError(
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
goto exit;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(WdfIoQueueGetDevice(Queue), Xbox360Wired, xusbNotify->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
{
status = pdo->EnqueueNotification(Request);
status = (NT_SUCCESS(status)) ? STATUS_PENDING : status;
}
exit:
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_Ds4SubmitReportHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
FuncEntry(TRACE_QUEUE);
NTSTATUS status;
EmulationTargetPDO* pdo;
PDS4_SUBMIT_REPORT ds4Submit = (PDS4_SUBMIT_REPORT)InputBuffer;
//
// Check if buffer is within expected bounds
//
if (InputBufferSize < sizeof(DS4_SUBMIT_REPORT) || InputBufferSize > sizeof(DS4_SUBMIT_REPORT_EX))
{
TraceVerbose(
TRACE_QUEUE,
"Unexpected buffer size: %d",
static_cast<ULONG>(InputBufferSize)
);
status = STATUS_INVALID_BUFFER_SIZE;
goto exit;
}
//
// Check if this makes sense before passing it on
//
if (InputBufferSize != ds4Submit->Size)
{
TraceVerbose(
TRACE_QUEUE,
"Invalid buffer size: %d",
ds4Submit->Size
);
status = STATUS_INVALID_BUFFER_SIZE;
goto exit;
}
//
// This request only supports a single PDO at a time
//
if (ds4Submit->SerialNo == 0)
{
TraceError(
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
goto exit;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(WdfIoQueueGetDevice(Queue), DualShock4Wired, ds4Submit->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
status = pdo->SubmitReport(ds4Submit);
exit:
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_Ds4RequestNotificationHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
FuncEntry(TRACE_QUEUE);
NTSTATUS status;
EmulationTargetPDO* pdo;
PDS4_REQUEST_NOTIFICATION ds4Notify = (PDS4_REQUEST_NOTIFICATION)InputBuffer;
// This request only supports a single PDO at a time
if (ds4Notify->SerialNo == 0)
{
TraceError(
TRACE_QUEUE,
"Invalid serial 0 submitted");
status = STATUS_INVALID_PARAMETER;
goto exit;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(WdfIoQueueGetDevice(Queue), DualShock4Wired, ds4Notify->SerialNo, &pdo))
status = STATUS_DEVICE_DOES_NOT_EXIST;
else
{
status = pdo->EnqueueNotification(Request);
status = (NT_SUCCESS(status)) ? STATUS_PENDING : status;
}
exit:
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_XusbGetUserIndexHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(DmfModule);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
FuncEntry(TRACE_QUEUE);
NTSTATUS status;
EmulationTargetPDO* pdo;
PXUSB_GET_USER_INDEX pXusbGetUserIndex = (PXUSB_GET_USER_INDEX)InputBuffer;
// This request only supports a single PDO at a time
if (pXusbGetUserIndex->SerialNo == 0)
{
status = STATUS_INVALID_PARAMETER;
goto exit;
}
if (!EmulationTargetPDO::GetPdoByTypeAndSerial(WdfIoQueueGetDevice(Queue), Xbox360Wired, pXusbGetUserIndex->SerialNo, &pdo))
{
status = STATUS_DEVICE_DOES_NOT_EXIST;
goto exit;
}
status = static_cast<EmulationTargetXUSB*>(pdo)->GetUserIndex(&pXusbGetUserIndex->UserIndex);
exit:
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
NTSTATUS
Bus_Ds4AwaitOutputHandler(
_In_ DMFMODULE DmfModule,
_In_ WDFQUEUE Queue,
_In_ WDFREQUEST Request,
_In_ ULONG IoctlCode,
_In_reads_(InputBufferSize) VOID* InputBuffer,
_In_ size_t InputBufferSize,
_Out_writes_(OutputBufferSize) VOID* OutputBuffer,
_In_ size_t OutputBufferSize,
_Out_ size_t* BytesReturned
)
{
UNREFERENCED_PARAMETER(Queue);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(IoctlCode);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(InputBufferSize);
UNREFERENCED_PARAMETER(InputBuffer);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(BytesReturned);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Entry");
FuncEntry(TRACE_QUEUE);
WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
NTSTATUS status;
PFDO_DEVICE_DATA pDevCtx = FdoGetData(DMF_ParentDeviceGet(DmfModule));
if (!NT_SUCCESS(status = DMF_NotifyUserWithRequestMultiple_RequestProcess(
pDevCtx->UserNotification,
Request
)))
{
goto exit;
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Exit");
status = NT_SUCCESS(status) ? STATUS_PENDING : status;
exit:
FuncExit(TRACE_QUEUE, "status=%!STATUS!", status);
return status;
}
EXTERN_C_END

View File

@@ -1,27 +1,35 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2020, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -29,7 +37,15 @@
EXTERN_C_START
EVT_WDF_IO_QUEUE_IO_DEFAULT Bus_EvtIoDefault;
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL Bus_EvtIoDeviceControl;
EVT_DMF_IoctlHandler_Callback Bus_CheckVersionHandler;
EVT_DMF_IoctlHandler_Callback Bus_WaitDeviceReadyHandler;
EVT_DMF_IoctlHandler_Callback Bus_PluginTargetHandler;
EVT_DMF_IoctlHandler_Callback Bus_UnplugTargetHandler;
EVT_DMF_IoctlHandler_Callback Bus_XusbSubmitReportHandler;
EVT_DMF_IoctlHandler_Callback Bus_XusbRequestNotificationHandler;
EVT_DMF_IoctlHandler_Callback Bus_Ds4SubmitReportHandler;
EVT_DMF_IoctlHandler_Callback Bus_Ds4RequestNotificationHandler;
EVT_DMF_IoctlHandler_Callback Bus_XusbGetUserIndexHandler;
EVT_DMF_IoctlHandler_Callback Bus_Ds4AwaitOutputHandler;
EXTERN_C_END

View File

@@ -1,26 +1,34 @@
; Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
;
; MIT License
; BSD 3-Clause License
;
; Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
; Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
; All rights reserved.
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
;
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
; 1. Redistributions of source code must retain the above copyright notice, this
; list of conditions and the following disclaimer.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE.
; 2. Redistributions in binary form must reproduce the above copyright notice,
; this list of conditions and the following disclaimer in the documentation
; and/or other materials provided with the distribution.
;
; 3. Neither the name of the copyright holder nor the names of its
; contributors may be used to endorse or promote products derived from
; this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[Version]
@@ -30,6 +38,7 @@ ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}
Provider=%ManufacturerName%
CatalogFile=ViGEmBus.cat
DriverVer= ;
PnpLockdown=1
[DestinationDirs]
DefaultDestDir = 12
@@ -47,7 +56,7 @@ WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1
;*****************************************
[Manufacturer]
%ManufacturerName%=Standard,NTamd64,NTx86
%ManufacturerName%=Standard,NTamd64,NTx86,NTARM64
[Standard.NTamd64]
%ViGEmBus.DeviceDesc%=ViGEmBus_Device, Nefarius\ViGEmBus\Gen1
@@ -55,6 +64,9 @@ WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1
[Standard.NTx86]
%ViGEmBus.DeviceDesc%=ViGEmBus_Device, Nefarius\ViGEmBus\Gen1
[Standard.NTARM64]
%ViGEmBus.DeviceDesc%=ViGEmBus_Device, Nefarius\ViGEmBus\Gen1
[ViGEmBus_Device.NT]
CopyFiles=Drivers_Dir
@@ -69,7 +81,7 @@ AddService = ViGEmBus,%SPSVCINST_ASSOCSERVICE%, ViGEmBus_Service_Inst
[ViGEmBus_Service_Inst]
DisplayName = %ViGEmBus.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
StartType = 1 ; SERVICE_SYSTEM_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\ViGEmBus.sys
@@ -95,6 +107,6 @@ KmdfLibraryVersion = $KMDFVERSION$
[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="Nefarius Software Solutions e.U."
DiskName = "ViGEmBus Installation Disk"
ViGEmBus.DeviceDesc = "Virtual Gamepad Emulation Bus"
ViGEmBus.SVCDESC = "Virtual Gamepad Emulation Service"
DiskName = "Nefarius ViGEmBus Installation Disk"
ViGEmBus.DeviceDesc = "Nefarius Virtual Gamepad Emulation Bus"
ViGEmBus.SVCDESC = "Nefarius Virtual Gamepad Emulation Service"

View File

@@ -35,7 +35,7 @@ BEGIN
VALUE "FileDescription", "Virtual Gamepad Emulation Framework Bus Driver"
VALUE "FileVersion", "1.16.200.0"
VALUE "InternalName", "Virtual Gamepad Emulation Framework Bus Driver"
VALUE "LegalCopyright", "(C) 2016-2019 Nefarius Software Solutions e.U."
VALUE "LegalCopyright", "(C) 2016-2022 Nefarius Software Solutions e.U."
VALUE "OriginalFilename", "ViGEmBus.sys"
VALUE "ProductName", "Virtual Gamepad Emulation Framework Bus Driver"
VALUE "ProductVersion", "1.16.200.0"

View File

@@ -17,175 +17,29 @@
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{040101B0-EE5C-4EF1-99EE-9F81C795C001}</ProjectGuid>
<TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>ViGEmBus</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
<AppVeyorBuildVersion Condition=" '$(APPVEYOR_BUILD_VERSION)' == '' ">*</AppVeyorBuildVersion>
<AppVeyorBuildVersion Condition=" '$(APPVEYOR_BUILD_VERSION)' != '' ">$(APPVEYOR_BUILD_VERSION)</AppVeyorBuildVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<KMDF_VERSION_MINOR>9</KMDF_VERSION_MINOR>
<ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<KMDF_VERSION_MINOR>9</KMDF_VERSION_MINOR>
<ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
<SignMode>Off</SignMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<KMDF_VERSION_MINOR>9</KMDF_VERSION_MINOR>
<ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<KMDF_VERSION_MINOR>9</KMDF_VERSION_MINOR>
<ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
<SignMode>Off</SignMode>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(SolutionDir)client\include;$(IncludePath)</IncludePath>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<EnableInf2cat>true</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(SolutionDir)client\include;$(IncludePath)</IncludePath>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<OutDir>$(SolutionDir)bin\$(DDKPlatform)\</OutDir>
<EnableInf2cat>true</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(SolutionDir)client\include;$(IncludePath)</IncludePath>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<EnableInf2cat>true</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(SolutionDir)client\include;$(IncludePath)</IncludePath>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<OutDir>$(SolutionDir)bin\$(DDKPlatform)\</OutDir>
<EnableInf2cat>true</EnableInf2cat>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Inf>
<TimeStamp>$(AppVeyorBuildVersion)</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)ntstrsafe.lib;$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>trace.h</WppScanConfigurationData>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Inf>
<TimeStamp>$(AppVeyorBuildVersion)</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)ntstrsafe.lib;$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>trace.h</WppScanConfigurationData>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Inf>
<TimeStamp>$(AppVeyorBuildVersion)</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)ntstrsafe.lib;$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<ClCompile>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>trace.h</WppScanConfigurationData>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Inf>
<TimeStamp>$(AppVeyorBuildVersion)</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)ntstrsafe.lib;$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<ClCompile>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<ClCompile>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>trace.h</WppScanConfigurationData>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<Inf Include="ViGEmBus.inf" />
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\client\include\ViGEm\km\BusShared.h" />
<ClInclude Include="busenum.h" />
<ClInclude Include="..\sdk\include\ViGEm\km\BusShared.h" />
<ClInclude Include="Driver.h" />
<ClInclude Include="CRTCPP.hpp" />
<ClInclude Include="Ds4Pdo.hpp" />
<ClInclude Include="EmulationTargetPDO.hpp" />
@@ -206,6 +60,287 @@
<ClCompile Include="Queue.cpp" />
<ClCompile Include="XusbPdo.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{040101B0-EE5C-4EF1-99EE-9F81C795C001}</ProjectGuid>
<TemplateGuid>{8c0e3d8b-df43-455b-815a-4a0e72973bc6}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>ViGEmBus</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<AppVeyorBuildVersion Condition=" '$(APPVEYOR_BUILD_VERSION)' == '' ">*</AppVeyorBuildVersion>
<AppVeyorBuildVersion Condition=" '$(APPVEYOR_BUILD_VERSION)' != '' ">$(APPVEYOR_BUILD_VERSION)</AppVeyorBuildVersion>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<SignMode>Off</SignMode>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<SignMode>Off</SignMode>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
</PropertyGroup>
<PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<SignMode>Off</SignMode>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="DMF.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH)</IncludePath>
<OutDir>$(SolutionDir)bin\$(DDKPlatform)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<IncludePath>$(SolutionDir)include;$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH)</IncludePath>
<OutDir>$(SolutionDir)bin\$(DDKPlatform)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)bin\$(DDKPlatform)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)bin\$(DDKPlatform)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies);ntstrsafe.lib;usbdex.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies);ntstrsafe.lib;usbdex.lib</AdditionalDependencies>
</Link>
<Inf>
<TimeStamp>1.0.0.0</TimeStamp>
</Inf>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies);ntstrsafe.lib;usbdex.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)wdmsec.lib;%(AdditionalDependencies);ntstrsafe.lib;usbdex.lib</AdditionalDependencies>
</Link>
<Inf>
<TimeStamp>1.0.0.0</TimeStamp>
</Inf>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_ARM_;ARM;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);ntstrsafe.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_ARM_;ARM;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);ntstrsafe.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>5040;4064;4627;4627;4366;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);ntstrsafe.lib;usbdex.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)sdk\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>5040;4064;4627;4627;4366;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<PreprocessorDefinitions>POOL_NX_OPTIN=1;POOL_ZERO_DOWN_LEVEL_SUPPORT;_ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);ntstrsafe.lib;usbdex.lib</AdditionalDependencies>
</Link>
<Inf>
<TimeStamp>1.0.0.0</TimeStamp>
</Inf>
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@@ -30,15 +30,9 @@
</Inf>
</ItemGroup>
<ItemGroup>
<ClInclude Include="busenum.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="trace.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\client\include\ViGEm\km\BusShared.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -57,6 +51,12 @@
<ClInclude Include="Queue.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Driver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sdk\include\ViGEm\km\BusShared.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="XusbPdo.cpp">

View File

@@ -1,39 +1,48 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Driver.h"
#include "XusbPdo.hpp"
#include "trace.h"
#include "XusbPdo.tmh"
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
#include <wdmguid.h>
#include <initguid.h>
#include <usbbusif.h>
#include "busenum.h"
#include <ViGEm/km/BusShared.h>
PCWSTR ViGEm::Bus::Targets::EmulationTargetXUSB::_deviceDescription = L"Virtual Xbox 360 Controller";
@@ -77,7 +86,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareDevice(PWDFDEVICE_I
status = RtlUnicodeStringInit(DeviceDescription, _deviceDescription);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"RtlUnicodeStringInit failed with status %!STATUS!",
status);
@@ -92,7 +101,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareDevice(PWDFDEVICE_I
status = WdfPdoInitAddHardwareID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfPdoInitAddHardwareID failed with status %!STATUS!",
status);
@@ -106,7 +115,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareDevice(PWDFDEVICE_I
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfPdoInitAddCompatibleID #1 failed with status %!STATUS!",
status);
@@ -118,7 +127,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareDevice(PWDFDEVICE_I
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfPdoInitAddCompatibleID #2 failed with status %!STATUS!",
status);
@@ -130,7 +139,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareDevice(PWDFDEVICE_I
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfPdoInitAddCompatibleID #3 failed with status %!STATUS!",
status);
@@ -142,7 +151,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareDevice(PWDFDEVICE_I
status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfPdoInitAddCompatibleID #4 failed with status %!STATUS!",
status);
@@ -154,87 +163,13 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareDevice(PWDFDEVICE_I
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareHardware()
{
NTSTATUS status;
WDF_QUERY_INTERFACE_CONFIG ifaceCfg;
INTERFACE dummyIface;
dummyIface.Size = sizeof(INTERFACE);
dummyIface.Version = 1;
dummyIface.Context = static_cast<PVOID>(this->_PdoDevice);
dummyIface.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
dummyIface.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
/* XUSB.sys will query for the following three "dummy" interfaces
* BUT WONT USE IT so we just expose them to satisfy initialization. (TODO: Check if still valid!)
*/
// Dummy PNP_LOCATION
WDF_QUERY_INTERFACE_CONFIG_INIT(
&ifaceCfg,
static_cast<PINTERFACE>(&dummyIface),
&GUID_PNP_LOCATION_INTERFACE,
nullptr
);
NTSTATUS status = WdfDeviceAddQueryInterface(this->_PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_XUSB,
"Couldn't register PNP_LOCATION dummy interface %!GUID! (WdfDeviceAddQueryInterface failed with status %!STATUS!)",
&GUID_PNP_LOCATION_INTERFACE,
status);
return status;
}
// Dummy D3COLD_SUPPORT
WDF_QUERY_INTERFACE_CONFIG_INIT(
&ifaceCfg,
static_cast<PINTERFACE>(&dummyIface),
&GUID_D3COLD_SUPPORT_INTERFACE,
nullptr
);
status = WdfDeviceAddQueryInterface(this->_PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_XUSB,
"Couldn't register D3COLD_SUPPORT dummy interface %!GUID! (WdfDeviceAddQueryInterface failed with status %!STATUS!)",
&GUID_D3COLD_SUPPORT_INTERFACE,
status);
return status;
}
// Dummy REENUMERATE_SELF_INTERFACE_STANDARD
WDF_QUERY_INTERFACE_CONFIG_INIT(
&ifaceCfg,
static_cast<PINTERFACE>(&dummyIface),
&GUID_REENUMERATE_SELF_INTERFACE_STANDARD,
nullptr
);
status = WdfDeviceAddQueryInterface(this->_PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_XUSB,
"Couldn't register REENUM_SELF_STD dummy interface %!GUID! (WdfDeviceAddQueryInterface failed with status %!STATUS!)",
&GUID_REENUMERATE_SELF_INTERFACE_STANDARD,
status);
return status;
}
//
// Expose USB_BUS_INTERFACE_USBDI_GUID
//
// This interface actually IS used
USB_BUS_INTERFACE_USBDI_V1 xusbInterface;
xusbInterface.Size = sizeof(USB_BUS_INTERFACE_USBDI_V1);
@@ -260,7 +195,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoPrepareHardware()
status = WdfDeviceAddQueryInterface(this->_PdoDevice, &ifaceCfg);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfDeviceAddQueryInterface failed with status %!STATUS!",
status);
@@ -278,7 +213,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoInitContext()
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = this->_PdoDevice;
TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_XUSB, "Initializing XUSB context...");
TraceVerbose(TRACE_XUSB, "Initializing XUSB context...");
RtlZeroMemory(this->_Rumble, ARRAYSIZE(this->_Rumble));
@@ -304,7 +239,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoInitContext()
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfMemoryCreate failed with status %!STATUS!",
status);
@@ -347,7 +282,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::PdoInitContext()
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_XUSB,
"WdfIoQueueCreate (HoldingUsbInRequests) failed with status %!STATUS!",
status);
@@ -531,7 +466,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SelectConfiguration(PURB Urb)
PUSBD_INTERFACE_INFORMATION pInfo = &Urb->UrbSelectConfiguration.Interface;
TraceDbg(
TraceVerbose(
TRACE_XUSB,
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d",
(int)pInfo->Length,
@@ -563,7 +498,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SelectConfiguration(PURB Urb)
pInfo = (PUSBD_INTERFACE_INFORMATION)((PCHAR)pInfo + pInfo->Length);
TraceDbg(
TraceVerbose(
TRACE_XUSB,
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d",
(int)pInfo->Length,
@@ -611,7 +546,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SelectConfiguration(PURB Urb)
pInfo = (PUSBD_INTERFACE_INFORMATION)((PCHAR)pInfo + pInfo->Length);
TraceDbg(
TraceVerbose(
TRACE_XUSB,
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d",
(int)pInfo->Length,
@@ -635,7 +570,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SelectConfiguration(PURB Urb)
pInfo = (PUSBD_INTERFACE_INFORMATION)((PCHAR)pInfo + pInfo->Length);
TraceDbg(
TraceVerbose(
TRACE_XUSB,
">> >> >> URB_FUNCTION_SELECT_CONFIGURATION: Length %d, Interface %d, Alternate %d, Pipes %d",
(int)pInfo->Length,
@@ -674,7 +609,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbSelectInterface(PURB Urb)
{
PUSBD_INTERFACE_INFORMATION pInfo = &Urb->UrbSelectInterface.Interface;
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
">> >> >> URB_FUNCTION_SELECT_INTERFACE: Length %d, Interface %d, Alternate %d, Pipes %d",
(int)pInfo->Length,
@@ -682,7 +617,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbSelectInterface(PURB Urb)
(int)pInfo->AlternateSetting,
pInfo->NumberOfPipes);
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
">> >> >> URB_FUNCTION_SELECT_INTERFACE: Class %d, SubClass %d, Protocol %d",
(int)pInfo->Class,
@@ -765,13 +700,13 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbGetStringDescriptorType(PU
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer, WDFREQUEST Request)
{
NTSTATUS status;
NTSTATUS status = STATUS_SUCCESS;
WDFREQUEST notifyRequest;
// Data coming FROM us TO higher driver
if (pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
{
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
">> >> >> Incoming request, queuing...");
@@ -870,18 +805,20 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_U
}
// Data coming FROM the higher driver TO us
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
">> >> >> URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: Handle %p, Flags %X, Length %d",
pTransfer->PipeHandle,
pTransfer->TransferFlags,
pTransfer->TransferBufferLength);
#pragma region Cache values
if (pTransfer->TransferBufferLength == XUSB_LEDSET_SIZE) // Led
{
auto Buffer = static_cast<PUCHAR>(pTransfer->TransferBuffer);
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
"-- LED Buffer: %02X %02X %02X",
Buffer[0], Buffer[1], Buffer[2]);
@@ -894,16 +831,16 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_U
if (Buffer[2] == 0x04)this->_LedNumber = 2;
if (Buffer[2] == 0x05)this->_LedNumber = 3;
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
"-- LED Number: %d",
this->_LedNumber);
//
// Notify client library that PDO is ready
//
KeSetEvent(&this->_PdoBootNotificationEvent, 0, FALSE);
}
//
// Notify client library that PDO is ready
//
KeSetEvent(&this->_PdoBootNotificationEvent, 0, FALSE);
}
// Extract rumble (vibration) information
@@ -911,7 +848,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_U
{
auto Buffer = static_cast<PUCHAR>(pTransfer->TransferBuffer);
TraceDbg(
TraceVerbose(
TRACE_USBPDO,
"-- Rumble Buffer: %02X %02X %02X %02X %02X %02X %02X %02X",
Buffer[0],
@@ -926,12 +863,14 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_U
RtlCopyBytes(this->_Rumble, Buffer, pTransfer->TransferBufferLength);
}
// Notify user-mode process that new data is available
status = WdfIoQueueRetrieveNextRequest(this->_PendingNotificationRequests, &notifyRequest);
#pragma endregion
if (NT_SUCCESS(status))
if (NT_SUCCESS(WdfIoQueueRetrieveNextRequest(
this->_PendingNotificationRequests,
&notifyRequest
)))
{
PXUSB_REQUEST_NOTIFICATION notify = NULL;
PXUSB_REQUEST_NOTIFICATION notify = nullptr;
status = WdfRequestRetrieveOutputBuffer(
notifyRequest,
@@ -949,11 +888,16 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_U
notify->LargeMotor = this->_Rumble[3];
notify->SmallMotor = this->_Rumble[4];
DumpAsHex("!! XUSB_REQUEST_NOTIFICATION",
notify,
sizeof(XUSB_REQUEST_NOTIFICATION)
);
WdfRequestCompleteWithInformation(notifyRequest, status, notify->Size);
}
else
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_USBPDO,
"WdfRequestRetrieveOutputBuffer failed with status %!STATUS!",
status);
@@ -961,10 +905,26 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbBulkOrInterruptTransfer(_U
}
else
{
TraceEvents(TRACE_LEVEL_WARNING,
TRACE_USBPDO,
"!! WdfIoQueueRetrieveNextRequest failed with status %!STATUS!",
status);
PVOID clientBuffer, contextBuffer;
if (NT_SUCCESS(DMF_BufferQueue_Fetch(
this->_UsbInterruptOutBufferQueue,
&clientBuffer,
&contextBuffer
)) && pTransfer->TransferBufferLength <= MAX_OUT_BUFFER_QUEUE_SIZE)
{
RtlCopyMemory(
clientBuffer,
pTransfer->TransferBuffer,
pTransfer->TransferBufferLength
);
*static_cast<size_t*>(contextBuffer) = pTransfer->TransferBufferLength;
TraceVerbose(TRACE_USBPDO, "Queued %Iu bytes", pTransfer->TransferBufferLength);
DMF_BufferQueue_Enqueue(this->_UsbInterruptOutBufferQueue, clientBuffer);
}
}
return status;
@@ -1015,7 +975,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::UsbControlTransfer(PURB Urb)
NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SubmitReportImpl(PVOID NewReport)
{
TraceDbg(TRACE_BUSENUM, "%!FUNC! Entry");
FuncEntry(TRACE_BUSENUM);
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN changed;
@@ -1028,14 +988,14 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SubmitReportImpl(PVOID NewRep
// Don't waste pending IRP if input hasn't changed
if (!changed)
{
TraceDbg(
TraceVerbose(
TRACE_BUSENUM,
"Input report hasn't changed since last update, aborting with %!STATUS!",
status);
return status;
}
TraceDbg(
TraceVerbose(
TRACE_BUSENUM,
"Received new report, processing");
@@ -1063,7 +1023,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::SubmitReportImpl(PVOID NewRep
// Complete pending request
WdfRequestComplete(usbRequest, status);
TraceDbg(TRACE_BUSENUM, "%!FUNC! Exit with status %!STATUS!", status);
TraceVerbose(TRACE_BUSENUM, "%!FUNC! Exit with status %!STATUS!", status);
return status;
}
@@ -1075,7 +1035,7 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::GetUserIndex(PULONG UserIndex
if (!UserIndex)
return STATUS_INVALID_PARAMETER;
if (this->_LedNumber >= 0)
{
*UserIndex = static_cast<ULONG>(this->_LedNumber);
@@ -1086,3 +1046,100 @@ NTSTATUS ViGEm::Bus::Targets::EmulationTargetXUSB::GetUserIndex(PULONG UserIndex
// and need to fail this request with a distinct status.
return STATUS_INVALID_DEVICE_OBJECT_PARAMETER;
}
void ViGEm::Bus::Targets::EmulationTargetXUSB::ProcessPendingNotification(WDFQUEUE Queue)
{
NTSTATUS status;
WDFREQUEST request;
PVOID clientBuffer, contextBuffer;
size_t bufferLength;
PXUSB_REQUEST_NOTIFICATION notify = nullptr;
FuncEntry(TRACE_BUSENUM);
//
// Loop through and drain all queued requests until buffer is empty
//
while (NT_SUCCESS(WdfIoQueueRetrieveNextRequest(Queue, &request)))
{
status = DMF_BufferQueue_Dequeue(
this->_UsbInterruptOutBufferQueue,
&clientBuffer,
&contextBuffer
);
//
// Shouldn't happen, but if so, error out
//
if (!NT_SUCCESS(status))
{
//
// Don't requeue request as we maya be out of order now
//
WdfRequestComplete(request, status);
continue;
}
//
// Actual buffer length
//
bufferLength = *static_cast<size_t*>(contextBuffer);
//
// Validate packet
//
if (bufferLength != XUSB_RUMBLE_SIZE && bufferLength != XUSB_LEDSET_SIZE)
{
DMF_BufferQueue_Reuse(this->_UsbInterruptOutBufferQueue, clientBuffer);
WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
break; // await callback getting fired again
}
if (NT_SUCCESS(WdfRequestRetrieveOutputBuffer(
request,
sizeof(XUSB_REQUEST_NOTIFICATION),
reinterpret_cast<PVOID*>(&notify),
nullptr
)))
{
notify->Size = sizeof(XUSB_REQUEST_NOTIFICATION);
notify->SerialNo = this->_SerialNo;
notify->LedNumber = this->_LedNumber; // Report last cached value
if (bufferLength == XUSB_RUMBLE_SIZE)
{
notify->LargeMotor = static_cast<PUCHAR>(clientBuffer)[3];
notify->SmallMotor = static_cast<PUCHAR>(clientBuffer)[4];
}
else
{
notify->LargeMotor = this->_Rumble[3]; // Cached value
notify->SmallMotor = this->_Rumble[4]; // Cached value
}
DumpAsHex("!! XUSB_REQUEST_NOTIFICATION",
notify,
sizeof(XUSB_REQUEST_NOTIFICATION)
);
WdfRequestCompleteWithInformation(request, status, notify->Size);
}
DMF_BufferQueue_Reuse(this->_UsbInterruptOutBufferQueue, clientBuffer);
//
// If no more buffer to process, exit loop and await next callback
//
if (DMF_BufferQueue_Count(this->_UsbInterruptOutBufferQueue) == 0)
{
break;
}
}
TraceVerbose(TRACE_BUSENUM, "%!FUNC! Exit");
}
VOID ViGEm::Bus::Targets::EmulationTargetXUSB::DmfDeviceModulesAdd(_In_ PDMFMODULE_INIT DmfModuleInit)
{
UNREFERENCED_PARAMETER(DmfModuleInit);
}

View File

@@ -1,29 +1,38 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2020, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "EmulationTargetPDO.hpp"
@@ -87,7 +96,10 @@ namespace ViGEm::Bus::Targets
NTSTATUS SubmitReportImpl(PVOID NewReport) override;
NTSTATUS GetUserIndex(PULONG UserIndex) const;
protected:
void ProcessPendingNotification(WDFQUEUE Queue) override;
void DmfDeviceModulesAdd(_In_ PDMFMODULE_INIT DmfModuleInit) override;
private:
static PCWSTR _deviceDescription;

View File

@@ -1,31 +1,40 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "busenum.h"
#include "Driver.h"
#include "trace.h"
#include "busenum.tmh"
#include "EmulationTargetPDO.hpp"
@@ -73,7 +82,7 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"WdfRequestRetrieveInputBuffer failed with status %!STATUS!", status);
return status;
@@ -81,7 +90,7 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
if ((sizeof(VIGEM_PLUGIN_TARGET) != plugIn->Size) || (length != plugIn->Size))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"sizeof(VIGEM_PLUGIN_TARGET) buffer size mismatch [%d != %d]",
sizeof(VIGEM_PLUGIN_TARGET), plugIn->Size);
@@ -90,7 +99,7 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
if (plugIn->SerialNo == 0)
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"Serial no. 0 not allowed");
return STATUS_INVALID_PARAMETER;
@@ -101,7 +110,7 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
fileObject = WdfRequestGetFileObject(Request);
if (fileObject == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"WdfRequestGetFileObject failed to fetch WDFFILEOBJECT from request 0x%p",
Request);
@@ -111,7 +120,7 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
pFileData = FileObjectGetData(fileObject);
if (pFileData == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"FileObjectGetData failed to get context data for 0x%p",
fileObject);
@@ -180,6 +189,11 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
goto pluginEnd;
}
if (plugIn->TargetType == DualShock4Wired)
{
static_cast<EmulationTargetDS4*>(description.Target)->SetOutputReportNotifyModule(FdoGetData(Device)->UserNotification);
}
status = WdfChildListAddOrUpdateChildDescriptionAsPresent(
WdfFdoGetDefaultChildList(Device),
&description.Header,
@@ -188,7 +202,7 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"WdfChildListAddOrUpdateChildDescriptionAsPresent failed with status %!STATUS!",
status);
@@ -203,7 +217,7 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
{
status = STATUS_INVALID_PARAMETER;
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"The described PDO already exists (%!STATUS!)",
status);
@@ -211,10 +225,6 @@ EXTERN_C NTSTATUS Bus_PlugInDevice(
goto pluginEnd;
}
status = description.Target->EnqueuePlugin(Request);
status = NT_SUCCESS(status) ? STATUS_PENDING : status;
pluginEnd:
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_BUSENUM, "%!FUNC! Exit with status %!STATUS!", status);
@@ -256,7 +266,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"WdfRequestRetrieveInputBuffer failed with status %!STATUS!",
status);
@@ -265,7 +275,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
if ((sizeof(VIGEM_UNPLUG_TARGET) != unPlug->Size) || (length != unPlug->Size))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"sizeof(VIGEM_UNPLUG_TARGET) buffer size mismatch [%d != %d]",
sizeof(VIGEM_UNPLUG_TARGET), unPlug->Size);
@@ -278,7 +288,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
fileObject = WdfRequestGetFileObject(Request);
if (fileObject == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"WdfRequestGetFileObject failed to fetch WDFFILEOBJECT from request 0x%p",
Request);
@@ -288,14 +298,14 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
pFileData = FileObjectGetData(fileObject);
if (pFileData == NULL)
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"FileObjectGetData failed to get context data for 0x%p",
fileObject);
return STATUS_INVALID_PARAMETER;
}
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSENUM,
"Starting child list traversal");
@@ -315,7 +325,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
// Error or no more children, end loop
if (!NT_SUCCESS(status) || status == STATUS_NO_MORE_ENTRIES)
{
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSENUM,
"WdfChildListRetrieveNextDevice returned with status %!STATUS!",
status);
@@ -325,7 +335,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
// If unable to retrieve device
if (childInfo.Status != WdfChildListRetrieveDeviceSuccess)
{
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSENUM,
"childInfo.Status = %d",
childInfo.Status);
@@ -335,7 +345,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
// Child isn't the one we looked for, skip
if (!unplugAll && description.SerialNo != unPlug->SerialNo)
{
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSENUM,
"Seeking serial mismatch: %d != %d",
description.SerialNo,
@@ -343,7 +353,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
continue;
}
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSENUM,
"description.SessionId = %d, pFileData->SessionId = %d",
description.SessionId,
@@ -356,7 +366,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
status = WdfChildListUpdateChildDescriptionAsMissing(list, &description.Header);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR,
TraceError(
TRACE_BUSENUM,
"WdfChildListUpdateChildDescriptionAsMissing failed with status %!STATUS!",
status);
@@ -366,7 +376,7 @@ EXTERN_C NTSTATUS Bus_UnPlugDevice(
WdfChildListEndIteration(list, &iterator);
TraceEvents(TRACE_LEVEL_VERBOSE,
TraceVerbose(
TRACE_BUSENUM,
"Finished child list traversal");

View File

@@ -1,123 +0,0 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include "trace.h"
#include <ntddk.h>
#include <wdf.h>
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
#include <initguid.h>
#include <ViGEm/km/BusShared.h>
#include "Queue.hpp"
#pragma region Macros
#define DRIVERNAME "ViGEm: "
#pragma endregion
//
// FDO (bus device) context data
//
typedef struct _FDO_DEVICE_DATA
{
//
// Counter of interface references
//
LONG InterfaceReferenceCounter;
//
// Next SessionId to assign to a file handle
//
LONG NextSessionId;
} FDO_DEVICE_DATA, * PFDO_DEVICE_DATA;
#define FDO_FIRST_SESSION_ID 100
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_DEVICE_DATA, FdoGetData)
//
// Context data associated with file objects created by user mode applications
//
typedef struct _FDO_FILE_DATA
{
//
// SessionId associated with file handle. Used to map file handles to emulated gamepad devices
//
LONG SessionId;
} FDO_FILE_DATA, * PFDO_FILE_DATA;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_FILE_DATA, FileObjectGetData)
EXTERN_C_START
#pragma region WDF callback prototypes
DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD Bus_EvtDeviceAdd;
EVT_WDF_DEVICE_FILE_CREATE Bus_DeviceFileCreate;
EVT_WDF_FILE_CLOSE Bus_FileClose;
EVT_WDF_CHILD_LIST_CREATE_DEVICE Bus_EvtDeviceListCreatePdo;
EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE Bus_EvtChildListIdentificationDescriptionCompare;
EVT_WDF_OBJECT_CONTEXT_CLEANUP Bus_EvtDriverContextCleanup;
#pragma endregion
#pragma region Bus enumeration-specific functions
NTSTATUS
Bus_PlugInDevice(
_In_ WDFDEVICE Device,
_In_ WDFREQUEST Request,
_In_ BOOLEAN IsInternal,
_Out_ size_t* Transferred
);
NTSTATUS
Bus_UnPlugDevice(
_In_ WDFDEVICE Device,
_In_ WDFREQUEST Request,
_In_ BOOLEAN IsInternal,
_Out_ size_t* Transferred
);
#pragma endregion
EXTERN_C_END

View File

@@ -1,30 +1,39 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "busenum.h"
#include "Driver.h"
#include "EmulationTargetPDO.hpp"
#ifdef ALLOC_PRAGMA
@@ -44,25 +53,3 @@ EXTERN_C NTSTATUS Bus_EvtDeviceListCreatePdo(
return pDesc->Target->PdoCreateDevice(WdfChildListGetDevice(DeviceList), ChildInit);
}
//
// Compares two children on the bus based on their serial numbers.
//
EXTERN_C BOOLEAN Bus_EvtChildListIdentificationDescriptionCompare(
WDFCHILDLIST DeviceList,
PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER FirstIdentificationDescription,
PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER SecondIdentificationDescription)
{
ViGEm::Bus::Core::PPDO_IDENTIFICATION_DESCRIPTION lhs, rhs;
UNREFERENCED_PARAMETER(DeviceList);
lhs = CONTAINING_RECORD(FirstIdentificationDescription,
ViGEm::Bus::Core::PDO_IDENTIFICATION_DESCRIPTION,
Header);
rhs = CONTAINING_RECORD(SecondIdentificationDescription,
ViGEm::Bus::Core::PDO_IDENTIFICATION_DESCRIPTION,
Header);
return (lhs->SerialNo == rhs->SerialNo) ? TRUE : FALSE;
}

View File

@@ -1,27 +1,35 @@
/*
* Virtual Gamepad Emulation Framework - Windows kernel-mode bus driver
*
* MIT License
* BSD 3-Clause License
*
* Copyright (c) 2016-2020 Nefarius Software Solutions e.U. and Contributors
* Copyright (c) 2018-2022, Nefarius Software Solutions e.U. and Contributors
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -36,6 +44,7 @@
ViGEmBusTraceGuid, (c5ce18fe,27bd,4049,b0b4,8a47cab1dcd9), \
\
WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \
WPP_DEFINE_BIT(DMF_TRACE) \
WPP_DEFINE_BIT(TRACE_BUSENUM) \
WPP_DEFINE_BIT(TRACE_BUSPDO) \
WPP_DEFINE_BIT(TRACE_BYTEARRAY) \
@@ -65,9 +74,28 @@
// This comment block is scanned by the trace preprocessor to define our
// Trace function.
//
// USEPREFIX and USESUFFIX strip all trailing whitespace, so we need to surround
// FuncExit messages with brackets
//
// begin_wpp config
// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);
// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
// FUNC TraceDbg{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS, MSG, ...);
// FUNC FuncEntry{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS);
// FUNC FuncEntryArguments{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS, MSG, ...);
// FUNC FuncExit{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS, MSG, ...);
// FUNC FuncExitVoid{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS);
// FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR}(FLAGS, MSG, ...);
// FUNC TraceInformation{LEVEL=TRACE_LEVEL_INFORMATION}(FLAGS, MSG, ...);
// FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS, MSG, ...);
// FUNC FuncExitNoReturn{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS);
// USEPREFIX(FuncEntry, "%!STDPREFIX! [%!FUNC!] --> Entry");
// USEPREFIX(FuncEntryArguments, "%!STDPREFIX! [%!FUNC!] --> Entry <");
// USEPREFIX(FuncExit, "%!STDPREFIX! [%!FUNC!] <-- Exit <");
// USESUFFIX(FuncExit, ">");
// USEPREFIX(FuncExitVoid, "%!STDPREFIX! [%!FUNC!] <-- Exit");
// USEPREFIX(TraceError, "%!STDPREFIX! [%!FUNC!] ERROR:");
// USEPREFIX(TraceEvents, "%!STDPREFIX! [%!FUNC!] ");
// USEPREFIX(TraceInformation, "%!STDPREFIX! [%!FUNC!] ");
// USEPREFIX(TraceVerbose, "%!STDPREFIX! [%!FUNC!] ");
// USEPREFIX(FuncExitNoReturn, "%!STDPREFIX! [%!FUNC!] <--");
// end_wpp
//