├── VMultiDll
├── hid.lib
├── SetupAPI.Lib
├── hidclass.lib
├── hidparse.lib
├── targetver.h
├── LibPath.txt
├── stdafx.h
├── Dll.cpp
├── vmulticlient.h
├── VMultiDll.vcxproj.filters
├── vmulticommon.h
├── hidport.h
├── VMultiDll.vcxproj
└── client.c
├── VMultiTest
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── VMultiTest.csproj
└── Program.cs
├── VMultiDllWrapper
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ └── AssemblyInfo.cs
├── MultitouchReport.cs
├── JoystickReport.cs
├── VMultiDllWrapper.csproj
├── KeyboardReport.cs
└── VMulti.cs
├── README.md
├── .gitattributes
├── .gitignore
└── VMultiDll.sln
/VMultiDll/hid.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duzhi5368/FKHIDKeyboardSimTest/HEAD/VMultiDll/hid.lib
--------------------------------------------------------------------------------
/VMultiDll/SetupAPI.Lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duzhi5368/FKHIDKeyboardSimTest/HEAD/VMultiDll/SetupAPI.Lib
--------------------------------------------------------------------------------
/VMultiDll/hidclass.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duzhi5368/FKHIDKeyboardSimTest/HEAD/VMultiDll/hidclass.lib
--------------------------------------------------------------------------------
/VMultiDll/hidparse.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duzhi5368/FKHIDKeyboardSimTest/HEAD/VMultiDll/hidparse.lib
--------------------------------------------------------------------------------
/VMultiTest/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/VMultiDll/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | VMultiDll
2 | =========
3 | Dll client for [vmulti drivers](https://code.google.com/p/vmulti/). For C# implementations.
4 |
5 | Usage
6 | ---------
7 | Reference VMultiDllWrapper.dll to your C# project and use the VMulti class to update the vmulti devices.
8 | Keep both VMulti.dll and VMultiDllWrapper.dll next to your executable.
9 |
10 | License
11 | ---------
12 | MIT License
13 |
--------------------------------------------------------------------------------
/VMultiDll/LibPath.txt:
--------------------------------------------------------------------------------
1 | SetupAPI.Lib C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86
2 | Hid.lib C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86
3 |
4 | Hidclass.lib C:\Program Files (x86)\Windows Kits\10\Lib\win7\km\x86
5 | Hidparse.lib C:\Program Files (x86)\Windows Kits\10\Lib\win7\km\x86
6 |
7 | hidparse.sys C:\Windows\System32\drivers
8 | hid.dll C:\Windows\System32
9 | setupapi.dll C:\Windows\System32
10 | advapi32.dll C:\Windows\System32
--------------------------------------------------------------------------------
/VMultiDll/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 | #include "targetver.h"
9 |
10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
11 | // Windows Header Files:
12 | #include
13 |
14 |
15 |
16 | // TODO: reference additional headers your program requires here
17 |
--------------------------------------------------------------------------------
/VMultiDll/Dll.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include
3 |
4 | #pragma comment(lib, "hidparse.lib")
5 | #pragma comment(lib, "hidclass.lib")
6 | #pragma comment(lib, "hid.lib")
7 | #pragma comment(lib, "setupapi.lib")
8 |
9 | extern "C"
10 | {
11 | #include "vmulticlient.h"
12 | }
13 |
14 | extern "C"
15 | {
16 | __declspec(dllexport) void __stdcall MyHelloWorld()
17 | {
18 | printf ("Hello World !\n");
19 | }
20 | }
21 |
22 | extern "C" _declspec(dllexport) int __stdcall MySum(int a, int b)
23 | {
24 | return a + b;
25 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace VMultiDllWrapper.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/VMultiDll/vmulticlient.h:
--------------------------------------------------------------------------------
1 | #if !defined(_VMULTI_CLIENT_H_)
2 | #define _VMULTI_CLIENT_H_
3 |
4 | #include "vmulticommon.h"
5 |
6 | typedef struct _vmulti_client_t* pvmulti_client;
7 |
8 | __declspec(dllexport) pvmulti_client vmulti_alloc(void);
9 |
10 | __declspec(dllexport) void vmulti_free(pvmulti_client vmulti);
11 |
12 | __declspec(dllexport) BOOL vmulti_connect(pvmulti_client vmulti,int i);
13 |
14 | __declspec(dllexport) void vmulti_disconnect(pvmulti_client vmulti);
15 |
16 | __declspec(dllexport) BOOL vmulti_update_mouse(pvmulti_client vmulti, BYTE button, USHORT x, USHORT y, BYTE wheelPosition);
17 |
18 | __declspec(dllexport) BOOL vmulti_update_relative_mouse(pvmulti_client vmulti, BYTE button, BYTE x, BYTE y, BYTE wheelPosition);
19 |
20 | __declspec(dllexport) BOOL vmulti_update_digi(pvmulti_client vmulti, BYTE status, USHORT x, USHORT y);
21 |
22 | __declspec(dllexport) BOOL vmulti_update_multitouch(pvmulti_client vmulti, PTOUCH pTouch, BYTE actualCount,BYTE request_type,BYTE report_control_id);
23 |
24 | __declspec(dllexport) BOOL vmulti_update_joystick(pvmulti_client vmulti, USHORT buttons, BYTE hat, BYTE x, BYTE y, BYTE z, BYTE rz, BYTE throttle);
25 |
26 | __declspec(dllexport) BOOL vmulti_update_keyboard(pvmulti_client vmulti, BYTE shiftKeyFlags, BYTE keyCodes[KBD_KEY_CODES]);
27 |
28 | __declspec(dllexport) BOOL vmulti_write_message(pvmulti_client vmulti, VMultiMessageReport* pReport);
29 |
30 | __declspec(dllexport) BOOL vmulti_read_message(pvmulti_client vmulti, VMultiMessageReport* pReport);
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/VMultiTest/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("VMultiTest")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("VMultiTest")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("eaf44028-ee3c-4cc3-960a-02e7fa824cba")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("VMultiDllWrapper")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("VMultiDllWrapper")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("09ffe03e-bb91-4eda-b3c1-0b3a970fd98c")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/VMultiDll/VMultiDll.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 |
26 |
27 | Header Files
28 |
29 |
30 | Header Files
31 |
32 |
33 | Header Files
34 |
35 |
36 | Header Files
37 |
38 |
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 | [Dd]ebug/
46 | [Rr]elease/
47 | *_i.c
48 | *_p.c
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.vspscc
63 | .builds
64 | *.dotCover
65 |
66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
67 | #packages/
68 |
69 | # Visual C++ cache files
70 | ipch/
71 | *.aps
72 | *.ncb
73 | *.opensdf
74 | *.sdf
75 |
76 | # Visual Studio profiler
77 | *.psess
78 | *.vsp
79 |
80 | # ReSharper is a .NET coding add-in
81 | _ReSharper*
82 |
83 | # Installshield output folder
84 | [Ee]xpress
85 |
86 | # DocProject is a documentation generator add-in
87 | DocProject/buildhelp/
88 | DocProject/Help/*.HxT
89 | DocProject/Help/*.HxC
90 | DocProject/Help/*.hhc
91 | DocProject/Help/*.hhk
92 | DocProject/Help/*.hhp
93 | DocProject/Help/Html2
94 | DocProject/Help/html
95 |
96 | # Click-Once directory
97 | publish
98 |
99 | # Others
100 | [Bb]in
101 | [Oo]bj
102 | sql
103 | TestResults
104 | *.Cache
105 | ClientBin
106 | stylecop.*
107 | ~$*
108 | *.dbmdl
109 | Generated_Code #added for RIA/Silverlight projects
110 |
111 | # Backup & report files from converting an old project file to a newer
112 | # Visual Studio version. Backup files are not needed, because we have git ;-)
113 | _UpgradeReport_Files/
114 | Backup*/
115 | UpgradeLog*.XML
116 |
117 |
118 |
119 | ############
120 | ## Windows
121 | ############
122 |
123 | # Windows image file caches
124 | Thumbs.db
125 |
126 | # Folder config file
127 | Desktop.ini
128 |
129 |
130 | #############
131 | ## Python
132 | #############
133 |
134 | *.py[co]
135 |
136 | # Packages
137 | *.egg
138 | *.egg-info
139 | dist
140 | build
141 | eggs
142 | parts
143 | bin
144 | var
145 | sdist
146 | develop-eggs
147 | .installed.cfg
148 |
149 | # Installer logs
150 | pip-log.txt
151 |
152 | # Unit test / coverage reports
153 | .coverage
154 | .tox
155 |
156 | #Translations
157 | *.mo
158 |
159 | #Mr Developer
160 | .mr.developer.cfg
161 |
162 | # Mac crap
163 | .DS_Store
164 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/MultitouchReport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace VMultiDllWrapper
8 | {
9 |
10 | public class MultitouchPointerInfo
11 | {
12 | private const byte MULTI_TIPSWITCH_BIT = 1;
13 | private const byte MULTI_IN_RANGE_BIT = 2;
14 | private const byte MULTI_CONFIDENCE_BIT = 4;
15 |
16 | private const uint MULTI_MIN_COORDINATE = 0x0000;
17 | private const uint MULTI_MAX_COORDINATE = 0x7FFF;
18 |
19 | private const uint MULTI_MAX_COUNT = 20;
20 |
21 | public bool Down = false;
22 | public bool Hover = false;
23 | public byte ID = 0;
24 | public double X = 0;
25 | public double Y = 0;
26 |
27 | public MultitouchPointerInfoRaw getPointerInfoRaw()
28 | {
29 | MultitouchPointerInfoRaw info = new MultitouchPointerInfoRaw();
30 | if (Down)
31 | {
32 | info.Status = MULTI_TIPSWITCH_BIT | MULTI_IN_RANGE_BIT | MULTI_CONFIDENCE_BIT;
33 | }
34 | else if(Hover)
35 | {
36 | info.Status = MULTI_IN_RANGE_BIT | MULTI_CONFIDENCE_BIT;
37 | }
38 | else
39 | {
40 | info.Status = 0;
41 | }
42 |
43 | info.ContactID = this.ID;
44 | info.XValue = (ushort)(X * (double)MULTI_MAX_COORDINATE);
45 | info.YValue = (ushort)(Y * (double)MULTI_MAX_COORDINATE);
46 | info.Width = 20;
47 | info.Height = 30;
48 |
49 | return info;
50 | }
51 | }
52 |
53 | public struct MultitouchPointerInfoRaw
54 | {
55 | public byte Status;
56 | public byte ContactID;
57 | public ushort XValue;
58 | public ushort YValue;
59 | public ushort Width;
60 | public ushort Height;
61 | }
62 |
63 |
64 | public class MultitouchReport
65 | {
66 | private List touches;
67 |
68 | public MultitouchReport(List touches)
69 | {
70 | this.touches = touches;
71 | }
72 |
73 | public MultitouchPointerInfoRaw[] getTouchesRaw()
74 | {
75 | MultitouchPointerInfoRaw[] allTouches = new MultitouchPointerInfoRaw[touches.Count];
76 | for (int i = 0; i < touches.Count; i++ )
77 | {
78 | allTouches[i] = touches[i].getPointerInfoRaw();
79 | }
80 | return allTouches;
81 | }
82 |
83 | public byte getTouchesCountRaw()
84 | {
85 | return (byte)touches.Count;
86 | }
87 |
88 | public byte getRequestType()
89 | {
90 | return 0x01; //REPORTID_MTOUCH
91 | }
92 |
93 | public byte getReportControlId()
94 | {
95 | return 0x40; //REPORTID_CONTROL
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/JoystickReport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace VMultiDllWrapper
8 | {
9 | public struct JoystickButtonState
10 | {
11 | public bool A;
12 | public bool B;
13 | public bool X;
14 | public bool Y;
15 | public bool L;
16 | public bool R;
17 | public bool L2;
18 | public bool R2;
19 | public bool Start;
20 | public bool Select;
21 |
22 | public bool Extra1;
23 | public bool Extra2;
24 | public bool Extra3;
25 | public bool Extra4;
26 | public bool Extra5;
27 | public bool Extra6;
28 |
29 | public bool Left;
30 | public bool Right;
31 | public bool Up;
32 | public bool Down;
33 | }
34 |
35 | public class JoystickReport
36 | {
37 | private JoystickButtonState buttonState;
38 |
39 | private double joystickX;
40 | private double joystickY;
41 |
42 | public JoystickReport(JoystickButtonState buttonState, double joystickX, double joystickY)
43 | {
44 | this.buttonState = buttonState;
45 | if (joystickX > 1)
46 | {
47 | joystickX = 1.0;
48 | }
49 | else if (joystickX < -1)
50 | {
51 | joystickX = -1.0;
52 | }
53 | if (joystickY > 1)
54 | {
55 | joystickY = 1.0;
56 | }
57 | else if (joystickY < -1)
58 | {
59 | joystickY = -1.0;
60 | }
61 | this.joystickX = joystickX;
62 | this.joystickY = joystickY;
63 | }
64 |
65 | public ushort getButtonsRaw()
66 | {
67 | ushort result = 0;
68 | if (buttonState.A)
69 | {
70 | result |= 1 << 1;
71 | }
72 | if (buttonState.B)
73 | {
74 | result |= 1 << 2;
75 | }
76 | if (buttonState.X)
77 | {
78 | result |= 1 << 3;
79 | }
80 | if (buttonState.Y)
81 | {
82 | result |= 1 << 4;
83 | }
84 | if (buttonState.L)
85 | {
86 | result |= 1 << 5;
87 | }
88 | if (buttonState.R)
89 | {
90 | result |= 1 << 6;
91 | }
92 |
93 | return result;
94 | }
95 |
96 | public byte getPOVRaw()
97 | {
98 | byte result = 0;
99 |
100 | /*
101 | if (buttonState.Left)
102 | {
103 | result = 129;
104 | }*/
105 |
106 | return result;
107 | }
108 |
109 | public byte getJoystickXRaw()
110 | {
111 | return (byte)(joystickX * 127);
112 | }
113 |
114 | public byte getJoystickYRaw()
115 | {
116 | return (byte)(joystickY * 127);
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/VMultiDllWrapper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {22020466-69C1-488D-B0EB-93DB380F2871}
8 | Library
9 | Properties
10 | VMultiDllWrapper
11 | VMultiDllWrapper
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | ..\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 | true
34 | ..\Debug\
35 | DEBUG;TRACE
36 | full
37 | x86
38 | prompt
39 | MinimumRecommendedRules.ruleset
40 |
41 |
42 | ..\Release\
43 | TRACE
44 | true
45 | pdbonly
46 | x86
47 | prompt
48 | MinimumRecommendedRules.ruleset
49 |
50 |
51 | true
52 | ..\Debug\
53 | DEBUG;TRACE
54 | full
55 | x64
56 | prompt
57 | MinimumRecommendedRules.ruleset
58 |
59 |
60 | ..\x64\Release\
61 | TRACE
62 | true
63 | pdbonly
64 | x64
65 | prompt
66 | MinimumRecommendedRules.ruleset
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | True
83 | True
84 | Settings.settings
85 |
86 |
87 |
88 |
89 |
90 |
91 | SettingsSingleFileGenerator
92 | Settings.Designer.cs
93 |
94 |
95 |
96 |
103 |
--------------------------------------------------------------------------------
/VMultiTest/VMultiTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {2C96C636-972D-4251-A350-52FB606AF440}
8 | Exe
9 | Properties
10 | VMultiTest
11 | VMultiTest
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | ..\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | ..\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 | true
36 | ..\Debug\
37 | DEBUG;TRACE
38 | full
39 | x86
40 | prompt
41 | MinimumRecommendedRules.ruleset
42 | true
43 |
44 |
45 | ..\Release\
46 | TRACE
47 | true
48 | pdbonly
49 | x86
50 | prompt
51 | MinimumRecommendedRules.ruleset
52 | true
53 |
54 |
55 | true
56 | ..\Debug\
57 | DEBUG;TRACE
58 | full
59 | x64
60 | prompt
61 | MinimumRecommendedRules.ruleset
62 | true
63 |
64 |
65 | ..\x64\Release\
66 | TRACE
67 | true
68 | pdbonly
69 | x64
70 | prompt
71 | MinimumRecommendedRules.ruleset
72 | true
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | {22020466-69c1-488d-b0eb-93db380f2871}
95 | VMultiDllWrapper
96 |
97 |
98 |
99 |
106 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/KeyboardReport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace VMultiDllWrapper
8 | {
9 | public enum KeyboardKey : byte
10 | {
11 | A = 0x04,
12 | B = 0x05,
13 | C = 0x06,
14 | D = 0x07,
15 | E = 0x08,
16 | F = 0x09,
17 | G = 0x0A,
18 | H = 0x0B,
19 | I = 0x0C,
20 | J = 0x0D,
21 | K = 0x0E,
22 | L = 0x0F,
23 | M = 0x10,
24 | N = 0x11,
25 | O = 0x12,
26 | P = 0x13,
27 | Q = 0x14,
28 | R = 0x15,
29 | S = 0x16,
30 | T = 0x17,
31 | U = 0x18,
32 | V = 0x19,
33 | W = 0x1A,
34 | X = 0x1B,
35 | Y = 0x1C,
36 | Z = 0x1D,
37 |
38 |
39 | Number1 = 0x1e,
40 | Number2 = 0x1f,
41 | Number3 = 0x20,
42 | Number4 = 0x21,
43 | Number5 = 0x22,
44 | Number6 = 0x23,
45 | Number7 = 0x24,
46 | Number8 = 0x25,
47 | Number9 = 0x26,
48 | Number0 = 0x27,
49 |
50 | Enter = 0x28,
51 | Escape = 0x29,
52 | Backspace = 0x2A,
53 | Tab = 0x2B,
54 | Spacebar = 0x2C,
55 | Subtract = 0x2D, //non-keypad
56 | Equals = 0x2E, //means "="
57 | OpenBrace = 0x2F,
58 | CloseBrace = 0x30,
59 | Backslash = 0x31, //non-keypad
60 | Hash = 0x32,
61 | Semicolon = 0x33,
62 | Quote = 0x34,
63 | Tilde = 0x35, //
64 | Comma = 0x36,
65 | Dot = 0x37,
66 | ForwardSlash= 0x38,
67 | CapsLock = 0x39,
68 |
69 | F1 = 0x3A,
70 | F2 = 0x3B,
71 | F3 = 0x3C,
72 | F4 = 0x3D,
73 | F5 = 0x3E,
74 | F6 = 0x3F,
75 | F7 = 0x40,
76 | F8 = 0x41,
77 | F9 = 0x42,
78 | F10 = 0x43,
79 | F11 = 0x44,
80 | F12 = 0x45,
81 |
82 | PrintScreen = 0x46,
83 | ScrollLock = 0x47,
84 | Pause = 0x48,
85 | Insert = 0x49,
86 | Home = 0x4A,
87 | PageUp = 0x4B,
88 | Delete = 0x4C,
89 | End = 0x4D,
90 | PageDown = 0x4E,
91 | RightArrow = 0x4F, // is "Arrow" needed?
92 | LeftArrow = 0x50,
93 | DownArrow = 0x51,
94 | UpArrow = 0x52,
95 | NumLock = 0x53,
96 | KeypadDivide = 0x54,
97 | KeypadMultiply = 0x55,
98 | KeypadSubtract = 0x56,
99 | KeypadAdd = 0x57,
100 | KeypadEnter = 0x58,
101 | Keypad1 = 0x59,
102 | Keypad2 = 0x5A,
103 | Keypad3 = 0x5B,
104 | Keypad4 = 0x5C,
105 | Keypad5 = 0x5D,
106 | Keypad6 = 0x5E,
107 | Keypad7 = 0x5F,
108 | Keypad8 = 0x60,
109 | Keypad9 = 0x61,
110 | Keypad0 = 0x62,
111 | KeypadDecimal = 0x63,
112 | KeypadSeparator = 0x64,
113 | KeypadApplication= 0x65
114 |
115 | }
116 |
117 | public enum KeyboardModifier : byte
118 | {
119 | LControl = 1,
120 | LShift = 2,
121 | LAlt = 4,
122 | LWin = 8,
123 | RControl = 16,
124 | RShift = 32,
125 | RAlt = 64,
126 | RWin = 128
127 | }
128 |
129 | public class KeyboardReport
130 | {
131 | private const byte KBD_KEY_CODES = 6;
132 | private HashSet modifiers;
133 | private HashSet pressedKeys;
134 |
135 | public KeyboardReport()
136 | {
137 | modifiers = new HashSet();
138 | pressedKeys = new HashSet();
139 | }
140 |
141 | public KeyboardReport(IEnumerable modifiers, IEnumerable pressedKeys)
142 | {
143 | }
144 |
145 | public void keyDown(KeyboardModifier modifier)
146 | {
147 | modifiers.Add(modifier);
148 | }
149 |
150 | public void keyDown(KeyboardKey key)
151 | {
152 | pressedKeys.Add(key);
153 | }
154 |
155 | public void keyUp(KeyboardModifier modifier)
156 | {
157 | modifiers.Remove(modifier);
158 | }
159 |
160 | public void keyUp(KeyboardKey key)
161 | {
162 | pressedKeys.Remove(key);
163 | }
164 |
165 | public byte getRawShiftKeyFlags()
166 | {
167 | byte shiftKeys = 0;
168 | foreach(KeyboardModifier modifier in modifiers)
169 | {
170 | shiftKeys |= (byte)modifier;
171 | }
172 | return shiftKeys;
173 | }
174 | public byte[] getRawKeyCodes()
175 | {
176 | byte[] keyCodes = new byte[KBD_KEY_CODES];
177 | byte i = 0;
178 | foreach (KeyboardKey key in pressedKeys)
179 | {
180 | if(i<=6)
181 | {
182 | keyCodes[i++] = (byte)key;
183 | }
184 | }
185 | return keyCodes;
186 | }
187 | }
188 |
189 | }
190 |
--------------------------------------------------------------------------------
/VMultiTest/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows.Forms;
9 | using System.Windows.Input;
10 | using VMultiDllWrapper;
11 |
12 | namespace VMultiTest
13 | {
14 | class Program
15 | {
16 | static void Main(string[] args)
17 | {
18 |
19 | VMulti vmulti = new VMulti("D:\\Work\\CSharpWork\\VMultiDll-master\\VMultiDll-master\\Debug\\VMultiDll.dll");
20 | Console.WriteLine("Connect: " + vmulti.connect());
21 |
22 | System.Threading.Thread.Sleep(3000);
23 |
24 | keyboardTest(vmulti);
25 |
26 | vmulti.disconnect();
27 |
28 | Console.ReadKey();
29 | }
30 |
31 | [DllImport("USER32.dll")]
32 | static extern short GetKeyState(int nVirtKey);
33 |
34 | private static void keyboardTest(VMulti vmulti)
35 | {
36 | System.Diagnostics.Process.Start("notepad.exe");
37 |
38 | System.Threading.Thread.Sleep(3000);
39 |
40 | KeyboardReport report = new KeyboardReport();
41 |
42 | report.keyDown(KeyboardKey.H);
43 | vmulti.updateKeyboard(report);
44 | report.keyUp(KeyboardKey.H);
45 | report.keyDown(KeyboardKey.E);
46 | vmulti.updateKeyboard(report);
47 | report.keyUp(KeyboardKey.E);
48 | report.keyDown(KeyboardKey.L);
49 | vmulti.updateKeyboard(report);
50 | report.keyUp(KeyboardKey.L);
51 | vmulti.updateKeyboard(report);
52 | report.keyDown(KeyboardKey.L);
53 | vmulti.updateKeyboard(report);
54 | report.keyUp(KeyboardKey.L);
55 | report.keyDown(KeyboardKey.O);
56 | vmulti.updateKeyboard(report);
57 | report.keyUp(KeyboardKey.O);
58 | report.keyDown(KeyboardModifier.LShift);
59 | report.keyDown(KeyboardKey.Number1);
60 | vmulti.updateKeyboard(report);
61 | report.keyUp(KeyboardModifier.LShift);
62 | report.keyUp(KeyboardKey.Number1);
63 | vmulti.updateKeyboard(report);
64 |
65 | System.Threading.Thread.Sleep(4000);
66 | report.keyDown(KeyboardModifier.LWin);
67 | report.keyDown(KeyboardKey.D);
68 | vmulti.updateKeyboard(report);
69 | report.keyUp(KeyboardModifier.LWin);
70 | report.keyUp(KeyboardKey.D);
71 | vmulti.updateKeyboard(report);
72 | }
73 |
74 | private void joystickTest(VMulti vmulti)
75 | {
76 | double i = 0;
77 | bool running = true;
78 | while (running)
79 | {
80 | JoystickButtonState joyButtonState = new JoystickButtonState();
81 | joyButtonState.A = false;
82 | joyButtonState.X = false;
83 | joyButtonState.Left = false;
84 |
85 | double x = Math.Sin(i);
86 | double y = Math.Cos(i);
87 |
88 | Console.WriteLine("x: " + x + " y: " + y);
89 |
90 | JoystickReport joystickReport = new JoystickReport(joyButtonState, x, y);
91 |
92 | Console.WriteLine("Update Joystick: " + vmulti.updateJoystick(joystickReport));
93 |
94 | i += 0.1;
95 |
96 | System.Threading.Thread.Sleep(100);
97 | }
98 | }
99 |
100 | private void multitouchTest(VMulti vmulti)
101 | {
102 | double x = 500;
103 | double y = 500;
104 |
105 | while (true)
106 | {
107 | List touches = new List();
108 | bool spacePressed = Convert.ToBoolean(GetKeyState(0x20) & 0x8000);
109 | MultitouchPointerInfo pointer = new MultitouchPointerInfo();
110 |
111 | bool rightPressed = Convert.ToBoolean(GetKeyState(0x27) & 0x8000);
112 | if (rightPressed)
113 | x += 10;
114 | bool downPressed = Convert.ToBoolean(GetKeyState(0x28) & 0x8000);
115 | if (downPressed)
116 | y += 10;
117 | bool leftPressed = Convert.ToBoolean(GetKeyState(0x25) & 0x8000);
118 | if (leftPressed)
119 | x -= 10;
120 | bool upPressed = Convert.ToBoolean(GetKeyState(0x26) & 0x8000);
121 | if (upPressed)
122 | y -= 10;
123 |
124 |
125 | if (spacePressed)
126 | {
127 | Console.WriteLine("pressed");
128 | pointer.Down = true;
129 | }
130 | else
131 | {
132 | pointer.Down = false;
133 | }
134 |
135 | Point mousePos = Control.MousePosition;
136 | Console.WriteLine(mousePos);
137 | pointer.X = x / Screen.PrimaryScreen.Bounds.Width;
138 | pointer.Y = y / Screen.PrimaryScreen.Bounds.Height;
139 |
140 | Console.WriteLine("X: " + pointer.X);
141 | Console.WriteLine("Y: " + pointer.Y);
142 |
143 | touches.Add(pointer);
144 |
145 | MultitouchReport report = new MultitouchReport(touches);
146 |
147 | if (!vmulti.updateMultitouch(report))
148 | {
149 | Console.WriteLine("fail");
150 | }
151 |
152 | System.Threading.Thread.Sleep(10);
153 | }
154 | }
155 |
156 |
157 |
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/VMultiDll/vmulticommon.h:
--------------------------------------------------------------------------------
1 | #if !defined(_VMULTI_COMMON_H_)
2 | #define _VMULTI_COMMON_H_
3 |
4 | #include "minwindef.h"
5 |
6 | //
7 | //These are the device attributes returned by vmulti in response
8 | // to IOCTL_HID_GET_DEVICE_ATTRIBUTES.
9 | //
10 |
11 | #define VMULTI_PID1 0xBA1C
12 | #define VMULTI_VID1 0x001F
13 |
14 | #define VMULTI_PID2 0xBA2C
15 | #define VMULTI_VID2 0x002F
16 |
17 | #define VMULTI_PID3 0xBA3C
18 | #define VMULTI_VID3 0x003F
19 |
20 | #define VMULTI_PID4 0xBA4C
21 | #define VMULTI_VID4 0x004F
22 |
23 | #define VMULTI_PID5 0xBA5C
24 | #define VMULTI_VID5 0x005F
25 |
26 | #define VMULTI_VERSION 0x0001
27 |
28 | //
29 | // These are the report ids
30 | //
31 |
32 | #define REPORTID_MTOUCH 0x01
33 | #define REPORTID_FEATURE 0x02
34 | #define REPORTID_MOUSE 0x03
35 | #define REPORTID_RELATIVE_MOUSE 0x04
36 | #define REPORTID_DIGI 0x05
37 | #define REPORTID_JOYSTICK 0x06
38 | #define REPORTID_KEYBOARD 0x07
39 | #define REPORTID_MESSAGE 0x10
40 | #define REPORTID_CONTROL 0x40
41 |
42 | //
43 | // Control defined report size
44 | //
45 |
46 | #define CONTROL_REPORT_SIZE 0x41
47 |
48 | //
49 | // Report header
50 | //
51 |
52 | #pragma pack(1)
53 | typedef struct _VMULTI_CONTROL_REPORT_HEADER
54 | {
55 |
56 | BYTE ReportID;
57 |
58 | BYTE ReportLength;
59 |
60 | } VMultiControlReportHeader;
61 | #pragma pack()
62 |
63 | //
64 | // Keyboard specific report infomation
65 | //
66 |
67 | #define KBD_LCONTROL_BIT 1
68 | #define KBD_LSHIFT_BIT 2
69 | #define KBD_LALT_BIT 4
70 | #define KBD_LGUI_BIT 8
71 | #define KBD_RCONTROL_BIT 16
72 | #define KBD_RSHIFT_BIT 32
73 | #define KBD_RALT_BIT 64
74 | #define KBD_RGUI_BIT 128
75 |
76 | #define KBD_KEY_CODES 6
77 |
78 | #pragma pack(1)
79 | typedef struct _VMULTI_KEYBOARD_REPORT
80 | {
81 | BYTE ReportID;
82 | // Left Control, Left Shift, Left Alt, Left GUI
83 | // Right Control, Right Shift, Right Alt, Right GUI
84 | BYTE ShiftKeyFlags;
85 | BYTE Reserved;
86 | // See http://www.usb.org/developers/devclass_docs/Hut1_11.pdf
87 | // for a list of key codes
88 | BYTE KeyCodes[KBD_KEY_CODES];
89 |
90 | } VMultiKeyboardReport;
91 |
92 | typedef struct _VMULTI_KEYBOARD_OUTPUT_REPORT
93 | {
94 | // Num Lock, Caps Lock, Scroll Lock, Compose, Kana
95 | BYTE LedFlags;
96 | } VMultiKeyboardOutputReport;
97 | #pragma pack()
98 |
99 | //
100 | // Joystick specific report infomation
101 | //
102 | #pragma pack(1)
103 | typedef struct _VMULTI_JOYSTICK_REPORT
104 | {
105 | BYTE ReportID;
106 | BYTE Throttle;
107 | BYTE XValue;
108 | BYTE YValue;
109 | BYTE ZValue;
110 | BYTE Hat;
111 | BYTE RZValue;
112 | USHORT Buttons;
113 | } VMultiJoystickReport;
114 | #pragma pack()
115 |
116 | //
117 | // Digitizer specific report infomation
118 | //
119 |
120 | #define DIGI_TIPSWITCH_BIT 1
121 | #define DIGI_IN_RANGE_BIT 2
122 |
123 | #define DIGI_MIN_COORDINATE 0x0000
124 | #define DIGI_MAX_COORDINATE 0x7FFF
125 |
126 | #pragma pack(1)
127 | typedef struct _VMULTI_DIGI_REPORT
128 | {
129 | BYTE ReportID;
130 | BYTE Status;
131 | USHORT XValue;
132 | USHORT YValue;
133 | } VMultiDigiReport;
134 | #pragma pack()
135 |
136 | //
137 | // Mouse specific report information
138 | //
139 |
140 | #define MOUSE_BUTTON_1 0x01
141 | #define MOUSE_BUTTON_2 0x02
142 | #define MOUSE_BUTTON_3 0x04
143 |
144 | #define MOUSE_MIN_COORDINATE 0x0000
145 | #define MOUSE_MAX_COORDINATE 0x7FFF
146 |
147 | #define MIN_WHEEL_POS -127
148 | #define MAX_WHEEL_POS 127
149 |
150 | #pragma pack(1)
151 | typedef struct _VMULTI_MOUSE_REPORT
152 | {
153 | BYTE ReportID;
154 | BYTE Button;
155 | USHORT XValue;
156 | USHORT YValue;
157 | BYTE WheelPosition;
158 | } VMultiMouseReport;
159 | #pragma pack()
160 |
161 | //
162 | // Relative mouse specific report information
163 | //
164 |
165 | #define RELATIVE_MOUSE_MIN_COORDINATE -127
166 | #define RELATIVE_MOUSE_MAX_COORDINATE 127
167 |
168 | #pragma pack(1)
169 | typedef struct _VMULTI_RELATIVE_MOUSE_REPORT
170 | {
171 | BYTE ReportID;
172 | BYTE Button;
173 | BYTE XValue;
174 | BYTE YValue;
175 | BYTE WheelPosition;
176 | } VMultiRelativeMouseReport;
177 | #pragma pack()
178 |
179 | //
180 | // Multitouch specific report information
181 | //
182 |
183 | #define MULTI_TIPSWITCH_BIT 1
184 | #define MULTI_IN_RANGE_BIT 2
185 | #define MULTI_CONFIDENCE_BIT 4
186 |
187 | #define MULTI_MIN_COORDINATE 0x0000
188 | #define MULTI_MAX_COORDINATE 0x7FFF
189 |
190 | #define MULTI_MAX_COUNT 20
191 |
192 | #pragma pack(1)
193 | typedef struct
194 | {
195 | BYTE Status;
196 | BYTE ContactID;
197 | USHORT XValue;
198 | USHORT YValue;
199 | USHORT Width;
200 | USHORT Height;
201 | }
202 | TOUCH, *PTOUCH;
203 |
204 | typedef struct _VMULTI_MULTITOUCH_REPORT
205 | {
206 | BYTE ReportID;
207 | TOUCH Touch[2];
208 | BYTE ActualCount;
209 | } VMultiMultiTouchReport;
210 | #pragma pack()
211 |
212 | //
213 | // Feature report infomation
214 | //
215 |
216 | #define DEVICE_MODE_MOUSE 0x00
217 | #define DEVICE_MODE_SINGLE_INPUT 0x01
218 | #define DEVICE_MODE_MULTI_INPUT 0x02
219 |
220 | #pragma pack(1)
221 | typedef struct _VMULTI_FEATURE_REPORT
222 | {
223 | BYTE ReportID;
224 | BYTE DeviceMode;
225 | BYTE DeviceIdentifier;
226 | } VMultiFeatureReport;
227 |
228 | typedef struct _VMULTI_MAXCOUNT_REPORT
229 | {
230 | BYTE ReportID;
231 | BYTE MaximumCount;
232 | } VMultiMaxCountReport;
233 | #pragma pack()
234 |
235 | //
236 | // Message specific report information
237 | //
238 |
239 | #define MESSAGE_SIZE 0x20
240 |
241 | #pragma pack(1)
242 | typedef struct _VMULTI_MESSAGE_REPORT
243 | {
244 | BYTE ReportID;
245 | char Message[MESSAGE_SIZE];
246 | } VMultiMessageReport;
247 | #pragma pack()
248 |
249 | #endif
250 |
--------------------------------------------------------------------------------
/VMultiDll/hidport.h:
--------------------------------------------------------------------------------
1 | /*++
2 |
3 | Copyright (c) 1996 Microsoft Corporation
4 |
5 | Module Name:
6 |
7 | hidmini.h
8 |
9 | Abstract
10 |
11 | Definitions that are common to all HID minidrivers.
12 |
13 | Authors:
14 |
15 | Forrest Foltz
16 | Ervin Peretz
17 |
18 | Environment:
19 |
20 | Kernel mode only
21 |
22 | Revision History:
23 |
24 |
25 | --*/
26 |
27 | #ifndef __HIDPORT_H__
28 | #define __HIDPORT_H__
29 |
30 | #include
31 | #include
32 |
33 | //
34 | // HID_MINIDRIVER_REGISTRATION is a packet of information describing the
35 | // HID minidriver to the class driver. It must be filled in by the minidriver
36 | // and passed to the class driver via HidRegisterMinidriver() from the
37 | // minidriver's DriverEntry() routine.
38 | //
39 |
40 | typedef struct _HID_MINIDRIVER_REGISTRATION {
41 |
42 | //
43 | // Revision must be set to HID_REVISION by the minidriver
44 | //
45 |
46 | ULONG Revision;
47 |
48 | //
49 | // DriverObject is a pointer to the minidriver's DriverObject that it
50 | // received as a DriverEntry() parameter.
51 | //
52 |
53 | PDRIVER_OBJECT DriverObject;
54 |
55 | //
56 | // RegistryPath is a pointer to the minidriver's RegistryPath that it
57 | // received as a DriverEntry() parameter.
58 | //
59 |
60 | PUNICODE_STRING RegistryPath;
61 |
62 | //
63 | // DeviceExtensionSize is the size of the minidriver's per-device
64 | // extension.
65 | //
66 |
67 | ULONG DeviceExtensionSize;
68 |
69 | //
70 | // Either all or none of the devices driven by a given minidriver are polled.
71 | //
72 | BOOLEAN DevicesArePolled;
73 | UCHAR Reserved[3];
74 |
75 | } HID_MINIDRIVER_REGISTRATION, *PHID_MINIDRIVER_REGISTRATION;
76 |
77 | //
78 | // HID_DEVICE_EXTENSION is the public part of the device extension of a HID
79 | // functional device object.
80 | //
81 |
82 | typedef struct _HID_DEVICE_EXTENSION {
83 |
84 | //
85 | // PhysicalDeviceObject... normally IRPs are not passed to this.
86 | //
87 |
88 | PDEVICE_OBJECT PhysicalDeviceObject;
89 |
90 | //
91 | // NextDeviceObject... IRPs are sent here by the minidriver. Note that
92 | // NextDeviceObject and PhysicalDeviceObject are the same unless someone
93 | // has inserted a 'filter' device object, in which case they are not the
94 | // same. Sending IRPs to NextDeviceObject will hit the filter device
95 | // objects on the way down.
96 | //
97 |
98 | PDEVICE_OBJECT NextDeviceObject;
99 |
100 | //
101 | // MiniDeviceExtension is the per-device extension area for use by
102 | // the minidriver. It's size is determined by the DeviceExtensionSize
103 | // parameter passed in to HidAddDevice().
104 | //
105 | // So, given a Functional Device Object, a mininidriver finds this
106 | // structure by:
107 | //
108 | // HidDeviceExtension = (PHID_DEVICE_EXTENSION)(Fdo->DeviceExtension);
109 | //
110 | // And of course it's per-device extension is found by:
111 | //
112 | // MiniDeviceExtension = HidDeviceExtension->MiniDeviceExtension;
113 | //
114 |
115 | PVOID MiniDeviceExtension;
116 |
117 | } HID_DEVICE_EXTENSION, *PHID_DEVICE_EXTENSION;
118 |
119 | typedef struct _HID_DEVICE_ATTRIBUTES {
120 |
121 | ULONG Size;
122 | //
123 | // sizeof (struct _HID_DEVICE_ATTRIBUTES)
124 | //
125 |
126 | //
127 | // Vendor ids of this hid device
128 | //
129 | USHORT VendorID;
130 | USHORT ProductID;
131 | USHORT VersionNumber;
132 | USHORT Reserved[11];
133 |
134 | } HID_DEVICE_ATTRIBUTES, * PHID_DEVICE_ATTRIBUTES;
135 |
136 |
137 | #include
138 | typedef struct _HID_DESCRIPTOR
139 | {
140 | UCHAR bLength;
141 | UCHAR bDescriptorType;
142 | USHORT bcdHID;
143 | UCHAR bCountry;
144 | UCHAR bNumDescriptors;
145 |
146 | /*
147 | * This is an array of one OR MORE descriptors.
148 | */
149 | struct _HID_DESCRIPTOR_DESC_LIST {
150 | UCHAR bReportType;
151 | USHORT wReportLength;
152 | } DescriptorList [1];
153 |
154 | } HID_DESCRIPTOR, * PHID_DESCRIPTOR;
155 | #include
156 |
157 |
158 | typedef
159 | VOID
160 | (*HID_SEND_IDLE_CALLBACK)(
161 | PVOID Context
162 | );
163 |
164 | typedef struct _HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO {
165 | HID_SEND_IDLE_CALLBACK IdleCallback;
166 | PVOID IdleContext;
167 | } HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO, *PHID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO;
168 |
169 | //
170 | // Function prototypes for the HID services exported by the hid class driver
171 | // follow.
172 | //
173 |
174 | NTSTATUS
175 | HidRegisterMinidriver(
176 | __in PHID_MINIDRIVER_REGISTRATION MinidriverRegistration
177 | );
178 |
179 | //
180 | // Internal IOCTLs for the class/mini driver interface.
181 | //
182 |
183 | #define IOCTL_HID_GET_DEVICE_DESCRIPTOR HID_CTL_CODE(0)
184 | #define IOCTL_HID_GET_REPORT_DESCRIPTOR HID_CTL_CODE(1)
185 | #define IOCTL_HID_READ_REPORT HID_CTL_CODE(2)
186 | #define IOCTL_HID_WRITE_REPORT HID_CTL_CODE(3)
187 | #define IOCTL_HID_GET_STRING HID_CTL_CODE(4)
188 | #define IOCTL_HID_ACTIVATE_DEVICE HID_CTL_CODE(7)
189 | #define IOCTL_HID_DEACTIVATE_DEVICE HID_CTL_CODE(8)
190 | #define IOCTL_HID_GET_DEVICE_ATTRIBUTES HID_CTL_CODE(9)
191 | #define IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST HID_CTL_CODE(10)
192 |
193 | /*
194 | * Codes for HID-specific descriptor types, from HID USB spec.
195 | */
196 | #define HID_HID_DESCRIPTOR_TYPE 0x21
197 | #define HID_REPORT_DESCRIPTOR_TYPE 0x22
198 | #define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 // for body part associations
199 |
200 |
201 |
202 | /*
203 | * These are string IDs for use with IOCTL_HID_GET_STRING
204 | * They match the string field offsets in Chapter 9 of the USB Spec.
205 | */
206 | #define HID_STRING_ID_IMANUFACTURER 14
207 | #define HID_STRING_ID_IPRODUCT 15
208 | #define HID_STRING_ID_ISERIALNUMBER 16
209 |
210 |
211 |
212 | #endif // __HIDPORT_H__
213 |
214 |
215 |
--------------------------------------------------------------------------------
/VMultiDll.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VMultiDll", "VMultiDll\VMultiDll.vcxproj", "{3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMultiDllWrapper", "VMultiDllWrapper\VMultiDllWrapper.csproj", "{22020466-69C1-488D-B0EB-93DB380F2871}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMultiTest", "VMultiTest\VMultiTest.csproj", "{2C96C636-972D-4251-A350-52FB606AF440}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Debug|Mixed Platforms = Debug|Mixed Platforms
16 | Debug|Win32 = Debug|Win32
17 | Debug|x64 = Debug|x64
18 | Debug|x86 = Debug|x86
19 | Release|Any CPU = Release|Any CPU
20 | Release|Mixed Platforms = Release|Mixed Platforms
21 | Release|Win32 = Release|Win32
22 | Release|x64 = Release|x64
23 | Release|x86 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|Any CPU.ActiveCfg = Debug|Win32
27 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
28 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|Mixed Platforms.Build.0 = Debug|Win32
29 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32
30 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|Win32.ActiveCfg = Debug|Win32
31 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|Win32.Build.0 = Debug|Win32
32 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|Win32.Deploy.0 = Debug|Win32
33 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|x64.ActiveCfg = Debug|x64
34 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|x64.Build.0 = Debug|x64
35 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|x64.Deploy.0 = Debug|x64
36 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|x86.ActiveCfg = Debug|Win32
37 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|x86.Build.0 = Debug|Win32
38 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Debug|x86.Deploy.0 = Debug|Win32
39 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|Any CPU.ActiveCfg = Release|Win32
40 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|Mixed Platforms.ActiveCfg = Release|Win32
41 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|Mixed Platforms.Build.0 = Release|Win32
42 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|Mixed Platforms.Deploy.0 = Release|Win32
43 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|Win32.ActiveCfg = Release|Win32
44 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|Win32.Build.0 = Release|Win32
45 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|Win32.Deploy.0 = Release|Win32
46 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|x64.ActiveCfg = Release|x64
47 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|x64.Build.0 = Release|x64
48 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|x64.Deploy.0 = Release|x64
49 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|x86.ActiveCfg = Release|Win32
50 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|x86.Build.0 = Release|Win32
51 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}.Release|x86.Deploy.0 = Release|Win32
52 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
53 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|Any CPU.Build.0 = Debug|Any CPU
54 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
55 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
56 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|Win32.ActiveCfg = Debug|x86
57 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|x64.ActiveCfg = Debug|x64
58 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|x64.Build.0 = Debug|x64
59 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|x86.ActiveCfg = Debug|x86
60 | {22020466-69C1-488D-B0EB-93DB380F2871}.Debug|x86.Build.0 = Debug|x86
61 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|Any CPU.ActiveCfg = Release|Any CPU
62 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|Any CPU.Build.0 = Release|Any CPU
63 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|Mixed Platforms.ActiveCfg = Release|x86
64 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|Mixed Platforms.Build.0 = Release|x86
65 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|Win32.ActiveCfg = Release|x86
66 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|x64.ActiveCfg = Release|x64
67 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|x64.Build.0 = Release|x64
68 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|x86.ActiveCfg = Release|x86
69 | {22020466-69C1-488D-B0EB-93DB380F2871}.Release|x86.Build.0 = Release|x86
70 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
71 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|Any CPU.Build.0 = Debug|Any CPU
72 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
73 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
74 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|Win32.ActiveCfg = Debug|x86
75 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|x64.ActiveCfg = Debug|x64
76 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|x64.Build.0 = Debug|x64
77 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|x86.ActiveCfg = Debug|x86
78 | {2C96C636-972D-4251-A350-52FB606AF440}.Debug|x86.Build.0 = Debug|x86
79 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|Any CPU.ActiveCfg = Release|Any CPU
80 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|Any CPU.Build.0 = Release|Any CPU
81 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|Mixed Platforms.ActiveCfg = Release|x86
82 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|Mixed Platforms.Build.0 = Release|x86
83 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|Win32.ActiveCfg = Release|x86
84 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|x64.ActiveCfg = Release|x64
85 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|x64.Build.0 = Release|x64
86 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|x86.ActiveCfg = Release|x86
87 | {2C96C636-972D-4251-A350-52FB606AF440}.Release|x86.Build.0 = Release|x86
88 | EndGlobalSection
89 | GlobalSection(SolutionProperties) = preSolution
90 | HideSolutionNode = FALSE
91 | EndGlobalSection
92 | EndGlobal
93 |
--------------------------------------------------------------------------------
/VMultiDllWrapper/VMulti.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace VMultiDllWrapper
6 | {
7 | public class VMulti
8 | {
9 |
10 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
11 | public static extern void MyHelloWorld();
12 |
13 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
14 | public static extern int MySum(int a, int b);
15 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
16 | public static extern IntPtr vmulti_alloc();
17 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
18 | public static extern void vmulti_free(IntPtr vmulti);
19 |
20 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
21 | public static extern bool vmulti_connect(IntPtr vmulti, int i);
22 |
23 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
24 | public static extern void vmulti_disconnect(IntPtr vmulti);
25 |
26 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
27 | public static extern bool vmulti_update_joystick(IntPtr vmulti, ushort buttons, byte hat, byte x, byte y, byte z, byte rz, byte throttle);
28 |
29 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
30 | public static extern bool vmulti_update_multitouch(IntPtr vmulti, MultitouchPointerInfoRaw[] pTouch, byte actualCount, byte request_type, byte report_control_id);
31 |
32 | [DllImport("VMultiDll.dll", CallingConvention = CallingConvention.Cdecl)]
33 | public static extern bool vmulti_update_keyboard(IntPtr vmulti, byte shiftKeyFlags, byte[] keyCodes);
34 |
35 | [DllImport("Kernel32.dll", SetLastError = true)]
36 | private static extern int GetProcAddress(int handle, string funcName);
37 | [DllImport("Kernel32.dll", SetLastError = true, CharSet =CharSet.Unicode)]
38 | private static extern int LoadLibrary(string dllPath);
39 | [DllImport("Kernel32.dll", SetLastError = true)]
40 | private static extern int FreeLibrary(int handle);
41 |
42 |
43 | /*
44 | public delegate void HelloWorld();
45 | private HelloWorld Pro_HelloWorld { get; set; }
46 |
47 | public delegate IntPtr vmulti_alloc();
48 | private vmulti_alloc Pro_vmulti_alloc { get; set; }
49 | public delegate void vmulti_free(IntPtr vmulti);
50 | private vmulti_free Pro_vmulti_free { get; set; }
51 | public delegate bool vmulti_connect(IntPtr vmulti, int i);
52 | private vmulti_connect Pro_vmulti_connect { get; set; }
53 | public delegate void vmulti_disconnect(IntPtr vmulti);
54 | private vmulti_disconnect Pro_vmulti_disconnect { get; set; }
55 | public delegate bool vmulti_update_joystick(IntPtr vmulti, ushort buttons, byte hat, byte x, byte y, byte z, byte rz, byte throttle);
56 | private vmulti_update_joystick Pro_vmulti_update_joystick { get; set; }
57 | public delegate bool vmulti_update_multitouch(IntPtr vmulti, MultitouchPointerInfoRaw[] pTouch, byte actualCount, byte request_type, byte report_control_id);
58 | private vmulti_update_multitouch Pro_vmulti_update_multitouch { get; set; }
59 | public delegate bool vmulti_update_keyboard(IntPtr vmulti, byte shiftKeyFlags, byte[] keyCodes);
60 | private vmulti_update_keyboard Pro_vmulti_update_keyboard { get; set; }
61 | */
62 | private IntPtr vmulti;
63 | private bool connected;
64 | private int nDllHandle = 0;
65 |
66 | /*
67 | private static Delegate GetAddress(int dllMoule,string functionName, Type t)
68 | {
69 | int Addr = GetProcAddress(dllMoule, functionName);
70 | if (Addr == 0)
71 | return null;
72 | else
73 | return Marshal.GetDelegateForFunctionPointer(new IntPtr(Addr), t);
74 | }
75 | private void MyFreeLibrary()
76 | {
77 | if (this.nDllHandle >= 32)
78 | FreeLibrary(this.nDllHandle);
79 | }
80 | private bool MyLoadLibaray(string dllPath)
81 | {
82 | this.nDllHandle = LoadLibrary(dllPath);
83 | if(this.nDllHandle >= 32)
84 | {
85 | this.Pro_HelloWorld = (HelloWorld)GetAddress(nDllHandle, "HelloWorld", typeof(HelloWorld));
86 | this.Pro_vmulti_alloc = (vmulti_alloc)GetAddress(nDllHandle, "vmulti_alloc", typeof(vmulti_alloc));
87 | this.Pro_vmulti_free = (vmulti_free)GetAddress(nDllHandle, "vmulti_free", typeof(vmulti_free));
88 | this.Pro_vmulti_connect = (vmulti_connect)GetAddress(nDllHandle, "vmulti_connect", typeof(vmulti_connect));
89 | this.Pro_vmulti_disconnect = (vmulti_disconnect)GetAddress(nDllHandle, "vmulti_disconnect", typeof(vmulti_disconnect));
90 | this.Pro_vmulti_update_joystick = (vmulti_update_joystick)GetAddress(nDllHandle, "vmulti_update_joystick", typeof(vmulti_update_joystick));
91 | this.Pro_vmulti_update_multitouch = (vmulti_update_multitouch)GetAddress(nDllHandle, "vmulti_update_multitouch", typeof(vmulti_update_multitouch));
92 | this.Pro_vmulti_update_keyboard = (vmulti_update_keyboard)GetAddress(nDllHandle, "vmulti_update_keyboard", typeof(vmulti_update_keyboard));
93 | return true;
94 | }
95 | else
96 | {
97 | string strError = Marshal.GetLastWin32Error().ToString();
98 | throw new Exception("LoadLibrary failed, error code = " + strError);
99 | }
100 | }
101 | */
102 |
103 | public VMulti(string dllPath)
104 | {
105 | /*
106 | int a = 1; int b = 2;
107 | int c = MySum(a, b);
108 | */
109 | MyHelloWorld();
110 | //MyLoadLibaray(dllPath);
111 | vmulti = vmulti_alloc();
112 | }
113 |
114 | ~VMulti()
115 | {
116 | //MyFreeLibrary();
117 | }
118 |
119 | public virtual bool isConnected()
120 | {
121 | return this.connected;
122 | }
123 |
124 | public virtual bool connect()
125 | {
126 | return this.connected = vmulti_connect(vmulti, 1);
127 | }
128 |
129 | public virtual void disconnect()
130 | {
131 | if (connected)
132 | {
133 | vmulti_disconnect(vmulti);
134 | }
135 | }
136 |
137 | public virtual bool updateJoystick(JoystickReport report)
138 | {
139 | if (connected)
140 | {
141 | return vmulti_update_joystick(vmulti, report.getButtonsRaw(),
142 | report.getPOVRaw(), report.getJoystickXRaw(), report.getJoystickYRaw(), 0, 128, 0);
143 | }
144 | else
145 | {
146 | return false;
147 | }
148 | }
149 |
150 | public virtual bool updateMultitouch(MultitouchReport report)
151 | {
152 | if (connected)
153 | {
154 | MultitouchPointerInfoRaw[] touches = report.getTouchesRaw();
155 | return vmulti_update_multitouch(vmulti, touches,
156 | report.getTouchesCountRaw(), report.getRequestType(), report.getReportControlId());
157 | }
158 | else
159 | {
160 | return false;
161 | }
162 | }
163 |
164 | public virtual bool updateKeyboard(KeyboardReport report)
165 | {
166 | if (connected)
167 | {
168 | return vmulti_update_keyboard(vmulti,
169 | report.getRawShiftKeyFlags(), report.getRawKeyCodes());
170 | }
171 | else
172 | {
173 | return false;
174 | }
175 | }
176 |
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/VMultiDll/VMultiDll.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {3C94F8A0-8F51-47B6-91E5-FBB0BD3E5C44}
23 | Win32Proj
24 | VMultiDll
25 | 8.1
26 |
27 |
28 |
29 | DynamicLibrary
30 | true
31 | v140
32 | Unicode
33 |
34 |
35 | DynamicLibrary
36 | true
37 | v140
38 | Unicode
39 |
40 |
41 | DynamicLibrary
42 | false
43 | v140
44 | true
45 | Unicode
46 |
47 |
48 | DynamicLibrary
49 | false
50 | v140
51 | true
52 | Unicode
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | true
72 |
73 |
74 | true
75 | $(SolutionDir)$(Configuration)\
76 | $(Configuration)\
77 |
78 |
79 | true
80 | $(SolutionDir)\$(Configuration)\
81 | $(Configuration)\
82 |
83 |
84 | false
85 | $(SolutionDir)\$(Configuration)\
86 | $(Configuration)\
87 |
88 |
89 |
90 |
91 |
92 | Level3
93 | Disabled
94 | WIN32;_DEBUG;_WINDOWS;_USRDLL;VMULTIDLL_EXPORTS;%(PreprocessorDefinitions)
95 | MultiThreadedDebug
96 |
97 |
98 | Windows
99 | true
100 | %(AdditionalDependencies)
101 |
102 |
103 |
104 |
105 |
106 |
107 | Level3
108 | Disabled
109 | WIN32;_DEBUG;_WINDOWS;_USRDLL;VMULTIDLL_EXPORTS;%(PreprocessorDefinitions)
110 | MultiThreadedDebug
111 |
112 |
113 | Windows
114 | true
115 |
116 |
117 |
118 |
119 | Level3
120 |
121 |
122 | MaxSpeed
123 | true
124 | true
125 | WIN32;NDEBUG;_WINDOWS;_USRDLL;VMULTIDLL_EXPORTS;%(PreprocessorDefinitions)
126 | MultiThreaded
127 |
128 |
129 | Windows
130 | true
131 | true
132 | true
133 | setupapi.lib;hid.lib;%(AdditionalDependencies)
134 |
135 |
136 |
137 |
138 | Level3
139 | NotUsing
140 | MaxSpeed
141 | true
142 | true
143 | WIN32;NDEBUG;_WINDOWS;_USRDLL;VMULTIDLL_EXPORTS;%(PreprocessorDefinitions)
144 |
145 |
146 | Windows
147 | true
148 | true
149 | true
150 | setupapi.lib;hid.lib;%(AdditionalDependencies)
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/VMultiDll/client.c:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "vmulticlient.h"
9 |
10 | #if __GNUC__
11 | #define __in
12 | #define __in_ecount(x)
13 | typedef void* PVOID;
14 | typedef PVOID HDEVINFO;
15 | WINHIDSDI BOOL WINAPI HidD_SetOutputReport(HANDLE, PVOID, ULONG);
16 | #endif
17 |
18 | typedef struct _vmulti_client_t
19 | {
20 | HANDLE hControl;
21 | HANDLE hMessage;
22 | BYTE controlReport[CONTROL_REPORT_SIZE];
23 | } vmulti_client_t;
24 | int id;
25 | int vmul_vid=0x0000;
26 | int vmul_pid=0x0000;
27 |
28 | //
29 | // Function prototypes
30 | //
31 |
32 | HANDLE
33 | SearchMatchingHwID (
34 | USAGE myUsagePage,
35 | USAGE myUsage
36 | );
37 |
38 | HANDLE
39 | OpenDeviceInterface (
40 | HDEVINFO HardwareDeviceInfo,
41 | PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
42 | USAGE myUsagePage,
43 | USAGE myUsage
44 | );
45 |
46 | BOOLEAN
47 | CheckIfOurDevice(
48 | HANDLE file,
49 | USAGE myUsagePage,
50 | USAGE myUsage
51 | );
52 |
53 | BOOL
54 | HidOutput(
55 | BOOL useSetOutputReport,
56 | HANDLE file,
57 | PCHAR buffer,
58 | ULONG bufferSize
59 | );
60 |
61 | //
62 | // Copied this structure from hidport.h
63 | //
64 |
65 | typedef struct _HID_DEVICE_ATTRIBUTES {
66 |
67 | ULONG Size;
68 | //
69 | // sizeof (struct _HID_DEVICE_ATTRIBUTES)
70 | //
71 | //
72 | // Vendor ids of this hid device
73 | //
74 | USHORT VendorID;
75 | USHORT ProductID;
76 | USHORT VersionNumber;
77 | USHORT Reserved[11];
78 |
79 | } HID_DEVICE_ATTRIBUTES, * PHID_DEVICE_ATTRIBUTES;
80 |
81 | //
82 | // Implementation
83 | //
84 |
85 | pvmulti_client vmulti_alloc(void)
86 | {
87 | return (pvmulti_client)malloc(sizeof(vmulti_client_t));
88 | }
89 |
90 | void vmulti_free(pvmulti_client vmulti)
91 | {
92 | free(vmulti);
93 | }
94 |
95 | BOOL vmulti_connect(pvmulti_client vmulti,int i)
96 | {
97 | //
98 | // Find the HID devices
99 | //
100 | id=i;
101 | vmulti->hControl = SearchMatchingHwID(0xff00, 0x0001);
102 | if (vmulti->hControl == INVALID_HANDLE_VALUE || vmulti->hControl == NULL)
103 | return FALSE;
104 | vmulti->hMessage = SearchMatchingHwID(0xff00, 0x0002);
105 | if (vmulti->hMessage == INVALID_HANDLE_VALUE || vmulti->hMessage == NULL)
106 | {
107 | vmulti_disconnect(vmulti);
108 | return FALSE;
109 | }
110 |
111 | //
112 | // Set the buffer count to 10 on the message HID
113 | //
114 |
115 | if (!HidD_SetNumInputBuffers(vmulti->hMessage, 10))
116 | {
117 | printf("failed HidD_SetNumInputBuffers %d\n", GetLastError());
118 | vmulti_disconnect(vmulti);
119 | return FALSE;
120 | }
121 |
122 | return TRUE;
123 | }
124 |
125 | void vmulti_disconnect(pvmulti_client vmulti)
126 | {
127 | if (vmulti->hControl != NULL)
128 | CloseHandle(vmulti->hControl);
129 | if (vmulti->hMessage != NULL)
130 | CloseHandle(vmulti->hMessage);
131 | vmulti->hControl = NULL;
132 | vmulti->hMessage = NULL;
133 | }
134 |
135 | BOOL vmulti_update_mouse(pvmulti_client vmulti, BYTE button, USHORT x, USHORT y, BYTE wheelPosition)
136 | {
137 | VMultiControlReportHeader* pReport = NULL;
138 | VMultiMouseReport* pMouseReport = NULL;
139 |
140 | if (CONTROL_REPORT_SIZE <= sizeof(VMultiControlReportHeader) + sizeof(VMultiMouseReport))
141 | {
142 | return FALSE;
143 | }
144 |
145 | //
146 | // Set the report header
147 | //
148 |
149 | pReport = (VMultiControlReportHeader*)vmulti->controlReport;
150 | pReport->ReportID = REPORTID_CONTROL;
151 | pReport->ReportLength = sizeof(VMultiMouseReport);
152 |
153 | //
154 | // Set the input report
155 | //
156 |
157 | pMouseReport = (VMultiMouseReport*)(vmulti->controlReport + sizeof(VMultiControlReportHeader));
158 | pMouseReport->ReportID = REPORTID_MOUSE;
159 | pMouseReport->Button = button;
160 | pMouseReport->XValue = x;
161 | pMouseReport->YValue = y;
162 | pMouseReport->WheelPosition = wheelPosition;
163 |
164 | // Send the report
165 | return HidOutput(FALSE, vmulti->hControl, (PCHAR)vmulti->controlReport, CONTROL_REPORT_SIZE);
166 | }
167 |
168 | BOOL vmulti_update_relative_mouse(pvmulti_client vmulti, BYTE button,
169 | BYTE x, BYTE y, BYTE wheelPosition)
170 | {
171 | VMultiControlReportHeader* pReport = NULL;
172 | VMultiRelativeMouseReport* pMouseReport = NULL;
173 |
174 | if (CONTROL_REPORT_SIZE <= sizeof(VMultiControlReportHeader) + sizeof(VMultiRelativeMouseReport))
175 | {
176 | return FALSE;
177 | }
178 |
179 | //
180 | // Set the report header
181 | //
182 |
183 | pReport = (VMultiControlReportHeader*)vmulti->controlReport;
184 | pReport->ReportID = REPORTID_CONTROL;
185 | pReport->ReportLength = sizeof(VMultiRelativeMouseReport);
186 |
187 | //
188 | // Set the input report
189 | //
190 |
191 | pMouseReport = (VMultiRelativeMouseReport*)(vmulti->controlReport + sizeof(VMultiControlReportHeader));
192 | pMouseReport->ReportID = REPORTID_RELATIVE_MOUSE;
193 | pMouseReport->Button = button;
194 | pMouseReport->XValue = x;
195 | pMouseReport->YValue = y;
196 | pMouseReport->WheelPosition = wheelPosition;
197 |
198 | // Send the report
199 | return HidOutput(FALSE, vmulti->hControl, (PCHAR)vmulti->controlReport, CONTROL_REPORT_SIZE);
200 | }
201 |
202 | BOOL vmulti_update_digi(pvmulti_client vmulti, BYTE status, USHORT x, USHORT y)
203 | {
204 | VMultiControlReportHeader* pReport = NULL;
205 | VMultiDigiReport* pDigiReport = NULL;
206 |
207 | if (CONTROL_REPORT_SIZE <= sizeof(VMultiControlReportHeader) + sizeof(VMultiDigiReport))
208 | {
209 | return FALSE;
210 | }
211 |
212 | //
213 | // Set the report header
214 | //
215 |
216 | pReport = (VMultiControlReportHeader*)vmulti->controlReport;
217 | pReport->ReportID = REPORTID_CONTROL;
218 | pReport->ReportLength = sizeof(VMultiDigiReport);
219 |
220 | //
221 | // Set the input report
222 | //
223 |
224 | pDigiReport = (VMultiDigiReport*)(vmulti->controlReport + sizeof(VMultiControlReportHeader));
225 | pDigiReport->ReportID = REPORTID_DIGI;
226 | pDigiReport->Status = status;
227 | pDigiReport->XValue = x;
228 | pDigiReport->YValue = y;
229 |
230 | // Send the report
231 | return HidOutput(FALSE, vmulti->hControl, (PCHAR)vmulti->controlReport, CONTROL_REPORT_SIZE);
232 | }
233 |
234 | BOOL vmulti_update_multitouch(pvmulti_client vmulti, PTOUCH pTouch, BYTE actualCount,BYTE request_type,BYTE report_control_id)
235 | {
236 | VMultiControlReportHeader* pReport = NULL;
237 | VMultiMultiTouchReport* pMultiReport = NULL;
238 | int numberOfTouchesSent = 0;
239 |
240 | if (CONTROL_REPORT_SIZE <= sizeof(VMultiControlReportHeader) + sizeof(VMultiMultiTouchReport))
241 | return FALSE;
242 |
243 | //
244 | // Set the report header
245 | //
246 |
247 | pReport = (VMultiControlReportHeader*)vmulti->controlReport;
248 | pReport->ReportID = report_control_id;
249 | pReport->ReportLength = sizeof(VMultiMultiTouchReport);
250 |
251 | while (numberOfTouchesSent < actualCount)
252 | {
253 |
254 | //
255 | // Set the input report
256 | //
257 |
258 | pMultiReport = (VMultiMultiTouchReport*)(vmulti->controlReport + sizeof(VMultiControlReportHeader));
259 | pMultiReport->ReportID = request_type;
260 | memcpy(pMultiReport->Touch, pTouch + numberOfTouchesSent, sizeof(TOUCH));
261 | if (numberOfTouchesSent <= actualCount - 2)
262 | memcpy(pMultiReport->Touch + 1, pTouch + numberOfTouchesSent + 1, sizeof(TOUCH));
263 | else
264 | memset(pMultiReport->Touch + 1, 0, sizeof(TOUCH));
265 | if (numberOfTouchesSent == 0)
266 | pMultiReport->ActualCount = actualCount;
267 | else
268 | pMultiReport->ActualCount = 0;
269 |
270 | // Send the report
271 | if (!HidOutput(TRUE, vmulti->hControl, (PCHAR)vmulti->controlReport, CONTROL_REPORT_SIZE))
272 | return FALSE;
273 |
274 | numberOfTouchesSent += 2;
275 | }
276 |
277 | return TRUE;
278 | }
279 |
280 | BOOL vmulti_update_joystick(pvmulti_client vmulti, USHORT buttons, BYTE hat, BYTE x, BYTE y, BYTE z, BYTE rz, BYTE throttle)
281 | {
282 | VMultiControlReportHeader* pReport = NULL;
283 | VMultiJoystickReport* pJoystickReport = NULL;
284 |
285 | if (CONTROL_REPORT_SIZE <= sizeof(VMultiControlReportHeader) + sizeof(VMultiJoystickReport))
286 | {
287 | return FALSE;
288 | }
289 |
290 | //
291 | // Set the report header
292 | //
293 |
294 | pReport = (VMultiControlReportHeader*)vmulti->controlReport;
295 | pReport->ReportID = REPORTID_CONTROL;
296 | pReport->ReportLength = sizeof(VMultiJoystickReport);
297 |
298 | //
299 | // Set the input report
300 | //
301 |
302 | pJoystickReport = (VMultiJoystickReport*)(vmulti->controlReport + sizeof(VMultiControlReportHeader));
303 | pJoystickReport->ReportID = REPORTID_JOYSTICK;
304 | pJoystickReport->Buttons = buttons;
305 | pJoystickReport->Hat = hat;
306 | pJoystickReport->XValue = x;
307 | pJoystickReport->YValue = y;
308 | pJoystickReport->ZValue = z;
309 | pJoystickReport->RZValue = rz;
310 | pJoystickReport->Throttle = throttle;
311 |
312 | // Send the report
313 | return HidOutput(FALSE, vmulti->hControl, (PCHAR)vmulti->controlReport, CONTROL_REPORT_SIZE);
314 | }
315 |
316 | BOOL vmulti_update_keyboard(pvmulti_client vmulti, BYTE shiftKeyFlags, BYTE keyCodes[KBD_KEY_CODES])
317 | {
318 | VMultiControlReportHeader* pReport = NULL;
319 | VMultiKeyboardReport* pKeyboardReport = NULL;
320 |
321 | if (CONTROL_REPORT_SIZE <= sizeof(VMultiControlReportHeader) + sizeof(VMultiKeyboardReport))
322 | {
323 | return FALSE;
324 | }
325 |
326 | //
327 | // Set the report header
328 | //
329 |
330 | pReport = (VMultiControlReportHeader*)vmulti->controlReport;
331 | pReport->ReportID = REPORTID_CONTROL;
332 | pReport->ReportLength = sizeof(VMultiKeyboardReport);
333 |
334 | //
335 | // Set the input report
336 | //
337 |
338 | pKeyboardReport = (VMultiKeyboardReport*)(vmulti->controlReport + sizeof(VMultiControlReportHeader));
339 | pKeyboardReport->ReportID = REPORTID_KEYBOARD;
340 | pKeyboardReport->ShiftKeyFlags = shiftKeyFlags;
341 | memcpy(pKeyboardReport->KeyCodes, keyCodes, KBD_KEY_CODES);
342 |
343 | // Send the report
344 | return HidOutput(FALSE, vmulti->hControl, (PCHAR)vmulti->controlReport, CONTROL_REPORT_SIZE);
345 | }
346 |
347 | BOOL vmulti_write_message(pvmulti_client vmulti, VMultiMessageReport* pReport)
348 | {
349 | VMultiControlReportHeader* pReportHeader;
350 | ULONG bytesWritten;
351 |
352 | //
353 | // Set the report header
354 | //
355 |
356 | pReportHeader = (VMultiControlReportHeader*)vmulti->controlReport;
357 | pReportHeader->ReportID = REPORTID_CONTROL;
358 | pReportHeader->ReportLength = sizeof(VMultiMessageReport);
359 |
360 | //
361 | // Set the body
362 | //
363 |
364 | pReport->ReportID = REPORTID_MESSAGE;
365 | memcpy(vmulti->controlReport + sizeof(VMultiControlReportHeader), pReport, sizeof(VMultiMessageReport));
366 |
367 | //
368 | // Write the report
369 | //
370 |
371 | if (!WriteFile(vmulti->hControl, vmulti->controlReport, CONTROL_REPORT_SIZE, &bytesWritten, NULL))
372 | {
373 | printf("failed WriteFile %d\n", GetLastError());
374 | return FALSE;
375 | }
376 |
377 | return TRUE;
378 | }
379 |
380 | BOOL vmulti_read_message(pvmulti_client vmulti, VMultiMessageReport* pReport)
381 | {
382 | ULONG bytesRead;
383 |
384 | //
385 | // Read the report
386 | //
387 |
388 | if (!ReadFile(vmulti->hMessage, pReport, sizeof(VMultiMessageReport), &bytesRead, NULL))
389 | {
390 | printf("failed ReadFile %d\n", GetLastError());
391 | return FALSE;
392 | }
393 |
394 | return TRUE;
395 | }
396 |
397 | HANDLE
398 | SearchMatchingHwID (
399 | USAGE myUsagePage,
400 | USAGE myUsage
401 | )
402 | {
403 | HDEVINFO hardwareDeviceInfo;
404 | SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
405 | SP_DEVINFO_DATA devInfoData;
406 | GUID hidguid;
407 | int i;
408 |
409 | HidD_GetHidGuid(&hidguid);
410 |
411 | hardwareDeviceInfo =
412 | SetupDiGetClassDevs ((LPGUID)&hidguid,
413 | NULL,
414 | NULL, // Define no
415 | (DIGCF_PRESENT |
416 | DIGCF_INTERFACEDEVICE));
417 |
418 | if (INVALID_HANDLE_VALUE == hardwareDeviceInfo)
419 | {
420 | printf("SetupDiGetClassDevs failed: %x\n", GetLastError());
421 | return INVALID_HANDLE_VALUE;
422 | }
423 |
424 | deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
425 |
426 | devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
427 |
428 | //
429 | // Enumerate devices of this interface class
430 | //
431 |
432 | printf("\n....looking for our HID device (with UP=0x%x "
433 | "and Usage=0x%x)\n", myUsagePage, myUsage);
434 |
435 | for (i = 0; SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
436 | 0, // No care about specific PDOs
437 | (LPGUID)&hidguid,
438 | i, //
439 | &deviceInterfaceData);
440 | i++)
441 | {
442 |
443 | //
444 | // Open the device interface and Check if it is our device
445 | // by matching the Usage page and Usage from Hid_Caps.
446 | // If this is our device then send the hid request.
447 | //
448 |
449 | HANDLE file = OpenDeviceInterface(hardwareDeviceInfo, &deviceInterfaceData, myUsagePage, myUsage);
450 |
451 | if (file != INVALID_HANDLE_VALUE)
452 | {
453 | SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
454 | return file;
455 | }
456 |
457 | //
458 | //device was not found so loop around.
459 | //
460 |
461 | }
462 |
463 | printf("Failure: Could not find our HID device \n");
464 |
465 | SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
466 |
467 | return INVALID_HANDLE_VALUE;
468 | }
469 |
470 | HANDLE
471 | OpenDeviceInterface (
472 | HDEVINFO hardwareDeviceInfo,
473 | PSP_DEVICE_INTERFACE_DATA deviceInterfaceData,
474 | USAGE myUsagePage,
475 | USAGE myUsage
476 | )
477 | {
478 | PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
479 |
480 | DWORD predictedLength = 0;
481 | DWORD requiredLength = 0;
482 | HANDLE file = INVALID_HANDLE_VALUE;
483 |
484 | SetupDiGetDeviceInterfaceDetail(
485 | hardwareDeviceInfo,
486 | deviceInterfaceData,
487 | NULL, // probing so no output buffer yet
488 | 0, // probing so output buffer length of zero
489 | &requiredLength,
490 | NULL
491 | ); // not interested in the specific dev-node
492 |
493 | predictedLength = requiredLength;
494 |
495 | deviceInterfaceDetailData =
496 | (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc (predictedLength);
497 |
498 | if (!deviceInterfaceDetailData)
499 | {
500 | printf("Error: OpenDeviceInterface: malloc failed\n");
501 | goto cleanup;
502 | }
503 |
504 | deviceInterfaceDetailData->cbSize =
505 | sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
506 |
507 | if (!SetupDiGetDeviceInterfaceDetail(
508 | hardwareDeviceInfo,
509 | deviceInterfaceData,
510 | deviceInterfaceDetailData,
511 | predictedLength,
512 | &requiredLength,
513 | NULL))
514 | {
515 | printf("Error: SetupDiGetInterfaceDeviceDetail failed\n");
516 | free (deviceInterfaceDetailData);
517 | goto cleanup;
518 | }
519 |
520 | //wchar_t wstFilePath[512];
521 | //memset(wstFilePath, 0, 512);
522 | //wsprintf(wstFilePath, L"%s%s", L"D:\\", deviceInterfaceDetailData->DevicePath);
523 | file = CreateFile (deviceInterfaceDetailData->DevicePath,
524 | GENERIC_READ | GENERIC_WRITE,
525 | FILE_SHARE_READ | FILE_SHARE_READ,
526 | NULL, // no SECURITY_ATTRIBUTES structure
527 | OPEN_EXISTING, // No special create flags
528 | 0, // No special attributes
529 | NULL); // No template file
530 |
531 | if (INVALID_HANDLE_VALUE == file) {
532 | printf("Error: CreateFile failed: %d\n", GetLastError());
533 | goto cleanup;
534 | }
535 |
536 | if (CheckIfOurDevice(file, myUsagePage, myUsage)){
537 | goto cleanup;
538 | }
539 |
540 | CloseHandle(file);
541 |
542 | file = INVALID_HANDLE_VALUE;
543 |
544 | cleanup:
545 |
546 | free (deviceInterfaceDetailData);
547 |
548 | return file;
549 |
550 | }
551 |
552 |
553 | BOOLEAN
554 | CheckIfOurDevice(
555 | HANDLE file,
556 | USAGE myUsagePage,
557 | USAGE myUsage)
558 | {
559 | PHIDP_PREPARSED_DATA Ppd = NULL; // The opaque parser info describing this device
560 | HIDD_ATTRIBUTES Attributes; // The Attributes of this hid device.
561 | HIDP_CAPS Caps; // The Capabilities of this hid device.
562 | BOOLEAN result = FALSE;
563 |
564 | if (!HidD_GetPreparsedData (file, &Ppd))
565 | {
566 | printf("Error: HidD_GetPreparsedData failed \n");
567 | goto cleanup;
568 | }
569 |
570 | if (!HidD_GetAttributes(file, &Attributes))
571 | {
572 | printf("Error: HidD_GetAttributes failed \n");
573 | goto cleanup;
574 | }
575 | if(id==1)
576 | {
577 | vmul_vid=VMULTI_VID1;
578 | vmul_pid=VMULTI_PID1;
579 | }
580 | else if(id==2)
581 | {
582 | vmul_vid=VMULTI_VID2;
583 | vmul_pid=VMULTI_PID2;
584 | }
585 | else if(id==3)
586 | {
587 | vmul_vid=VMULTI_VID3;
588 | vmul_pid=VMULTI_PID3;
589 | }
590 | else if(id==4)
591 | {
592 | vmul_vid=VMULTI_VID4;
593 | vmul_pid=VMULTI_PID4;
594 | }
595 | else if(id==5)
596 | {
597 | vmul_vid=VMULTI_VID5;
598 | vmul_pid=VMULTI_PID5;
599 | }
600 |
601 | if (Attributes.VendorID == vmul_vid && Attributes.ProductID == vmul_pid)
602 | {
603 | if (!HidP_GetCaps (Ppd, &Caps))
604 | {
605 | printf("Error: HidP_GetCaps failed \n");
606 | goto cleanup;
607 | }
608 |
609 | if ((Caps.UsagePage == myUsagePage) && (Caps.Usage == myUsage))
610 | {
611 | printf("Success: Found my device.. \n");
612 | result = TRUE;
613 | }
614 | }
615 |
616 | cleanup:
617 |
618 | if (Ppd != NULL)
619 | {
620 | HidD_FreePreparsedData (Ppd);
621 | }
622 |
623 | return result;
624 | }
625 |
626 | BOOL
627 | HidOutput(
628 | BOOL useSetOutputReport,
629 | HANDLE file,
630 | PCHAR buffer,
631 | ULONG bufferSize
632 | )
633 | {
634 | ULONG bytesWritten;
635 | if (useSetOutputReport)
636 | {
637 | //
638 | // Send Hid report thru HidD_SetOutputReport API
639 | //
640 |
641 | if (!HidD_SetOutputReport(file, buffer, bufferSize))
642 | {
643 | printf("failed HidD_SetOutputReport %d\n", GetLastError());
644 | return FALSE;
645 | }
646 | }
647 | else
648 | {
649 | if (!WriteFile(file, buffer, bufferSize, &bytesWritten, NULL))
650 | {
651 | printf("failed WriteFile %d\n", GetLastError());
652 | return FALSE;
653 | }
654 | }
655 |
656 | return TRUE;
657 | }
--------------------------------------------------------------------------------