├── crostouchpad
├── stdint.h
├── spb.h
├── trace.h
├── hidcommon.h
├── crostouchpad.vcxproj.user
├── crostouchpad.vcxproj.filters
├── crostouchpad.inf
├── cyapa.h
├── spb.c
├── driver.h
├── crostouchpad.vcxproj
└── cyapa.c
├── crostouchpad Package
├── crostouchpad Package.vcxproj.user
├── crostouchpad Package.vcxproj.filters
└── crostouchpad Package.vcxproj
├── LICENSE.txt
├── .gitignore
└── crostouchpad4.sln
/crostouchpad/stdint.h:
--------------------------------------------------------------------------------
1 | typedef signed char int8_t;
2 | typedef signed short int16_t;
3 | typedef signed int int32_t;
4 | typedef unsigned char uint8_t;
5 | typedef unsigned short uint16_t;
6 | typedef unsigned int uint32_t;
--------------------------------------------------------------------------------
/crostouchpad Package/crostouchpad Package.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | DbgengRemoteDebugger
5 |
6 |
--------------------------------------------------------------------------------
/crostouchpad Package/crostouchpad Package.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {8E41214B-6785-4CFE-B992-037D68949A14}
6 | inf;inv;inx;mof;mc;
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2016 CoolStar
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/crostouchpad/spb.h:
--------------------------------------------------------------------------------
1 | /*++
2 | Copyright (c) Microsoft Corporation. All Rights Reserved.
3 | Sample code. Dealpoint ID #843729.
4 |
5 | Module Name:
6 |
7 | spb.h
8 |
9 | Abstract:
10 |
11 | This module contains the touch driver I2C helper definitions.
12 |
13 | Environment:
14 |
15 | Kernel Mode
16 |
17 | Revision History:
18 |
19 | --*/
20 |
21 | #pragma once
22 |
23 | #include
24 | #include
25 |
26 | #define DEFAULT_SPB_BUFFER_SIZE 64
27 | #define RESHUB_USE_HELPER_ROUTINES
28 |
29 | //
30 | // SPB (I2C) context
31 | //
32 |
33 | typedef struct _SPB_CONTEXT
34 | {
35 | WDFIOTARGET SpbIoTarget;
36 | LARGE_INTEGER I2cResHubId;
37 | WDFMEMORY WriteMemory;
38 | WDFMEMORY ReadMemory;
39 | WDFWAITLOCK SpbLock;
40 | } SPB_CONTEXT;
41 |
42 | NTSTATUS
43 | SpbReadDataSynchronously(
44 | _In_ SPB_CONTEXT *SpbContext,
45 | _In_ UCHAR Address,
46 | _In_reads_bytes_(Length) PVOID Data,
47 | _In_ ULONG Length
48 | );
49 |
50 | VOID
51 | SpbTargetDeinitialize(
52 | IN WDFDEVICE FxDevice,
53 | IN SPB_CONTEXT *SpbContext
54 | );
55 |
56 | NTSTATUS
57 | SpbTargetInitialize(
58 | IN WDFDEVICE FxDevice,
59 | IN SPB_CONTEXT *SpbContext
60 | );
61 |
62 | NTSTATUS
63 | SpbWriteDataSynchronously(
64 | IN SPB_CONTEXT *SpbContext,
65 | IN UCHAR Address,
66 | IN PVOID Data,
67 | IN ULONG Length
68 | );
--------------------------------------------------------------------------------
/crostouchpad/trace.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #ifndef _TRACE_H_
4 | #define _TRACE_H_
5 |
6 | extern "C"
7 | {
8 | //
9 | // Tracing Definitions:
10 | //
11 | // Control GUID:
12 | // {73e3b785-f5fb-423e-94a9-56627fea9053}
13 | //
14 |
15 | #define WPP_CONTROL_GUIDS \
16 | WPP_DEFINE_CONTROL_GUID( \
17 | SpbTestToolTraceGuid, \
18 | (73e3b785,f5fb,423e,94a9,56627fea9053), \
19 | WPP_DEFINE_BIT(TRACE_FLAG_WDFLOADING) \
20 | WPP_DEFINE_BIT(TRACE_FLAG_SPBAPI) \
21 | WPP_DEFINE_BIT(TRACE_FLAG_OTHER) \
22 | )
23 | }
24 |
25 | #define WPP_LEVEL_FLAGS_LOGGER(level,flags) WPP_LEVEL_LOGGER(flags)
26 | #define WPP_LEVEL_FLAGS_ENABLED(level, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= level)
27 |
28 | #define Trace CyapaPrint
29 | #define FuncEntry
30 | #define FuncExit
31 | #define WPP_INIT_TRACING
32 | #define WPP_CLEANUP
33 | #define TRACE_FLAG_SPBAPI 0
34 | #define TRACE_FLAG_WDFLOADING 0
35 |
36 | // begin_wpp config
37 | // FUNC FuncEntry{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS);
38 | // FUNC FuncExit{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS);
39 | // USEPREFIX(FuncEntry, "%!STDPREFIX! [%!FUNC!] --> entry");
40 | // USEPREFIX(FuncExit, "%!STDPREFIX! [%!FUNC!] <--");
41 | // end_wpp
42 |
43 | #endif _TRACE_H_
44 |
--------------------------------------------------------------------------------
/crostouchpad/hidcommon.h:
--------------------------------------------------------------------------------
1 | #if !defined(_CYAPA_COMMON_H_)
2 | #define _CYAPA_COMMON_H_
3 |
4 | //
5 | //These are the device attributes returned by vmulti in response
6 | // to IOCTL_HID_GET_DEVICE_ATTRIBUTES.
7 | //
8 |
9 | #define CYAPA_PID 0xBACC
10 | #define CYAPA_VID 0x00FF
11 | #define CYAPA_VERSION 0x0001
12 |
13 | //
14 | // These are the report ids
15 | //
16 |
17 | #define REPORTID_MTOUCH 0x01
18 | #define REPORTID_FEATURE 0x02
19 | #define REPORTID_MOUSE 0x03
20 | #define REPORTID_PTPHQA 0x04
21 |
22 | //
23 | // Multitouch specific report information
24 | //
25 |
26 | #define MULTI_CONFIDENCE_BIT 1
27 | #define MULTI_TIPSWITCH_BIT 2
28 |
29 | #define MULTI_MIN_COORDINATE 0x0000
30 | #define MULTI_MAX_COORDINATE 0x7FFF
31 |
32 | #define MULTI_MAX_COUNT 5
33 |
34 | #pragma pack(1)
35 | typedef struct
36 | {
37 |
38 | BYTE Status;
39 |
40 | BYTE ContactID;
41 |
42 | USHORT XValue;
43 |
44 | USHORT YValue;
45 |
46 | USHORT Pressure;
47 | }
48 | TOUCH, *PTOUCH;
49 |
50 | typedef struct _CYAPA_MULTITOUCH_REPORT
51 | {
52 |
53 | BYTE ReportID;
54 |
55 | TOUCH Touch[5];
56 |
57 | USHORT ScanTime;
58 |
59 | BYTE ContactCount;
60 |
61 | BYTE IsDepressed;
62 | } CyapaMultiTouchReport;
63 | #pragma pack()
64 |
65 | //
66 | // Feature report infomation
67 | //
68 |
69 | #define DEVICE_MODE_MOUSE 0x00
70 | #define DEVICE_MODE_SINGLE_INPUT 0x01
71 | #define DEVICE_MODE_MULTI_INPUT 0x02
72 |
73 | #pragma pack(1)
74 | typedef struct _CYAPA_FEATURE_REPORT
75 | {
76 |
77 | BYTE ReportID;
78 |
79 | BYTE DeviceMode;
80 |
81 | BYTE DeviceIdentifier;
82 |
83 | } CyapaFeatureReport;
84 |
85 | typedef struct _CYAPA_MAXCOUNT_REPORT
86 | {
87 |
88 | BYTE ReportID;
89 |
90 | BYTE MaximumCount;
91 |
92 | BYTE PadType;
93 |
94 | } CyapaMaxCountReport;
95 | #pragma pack()
96 |
97 | #endif
98 |
--------------------------------------------------------------------------------
/crostouchpad/crostouchpad.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Off
5 |
6 |
7 |
8 |
9 |
10 |
11 | Off
12 |
13 |
14 | Off
15 |
16 |
17 | Off
18 |
19 |
20 | Off
21 |
22 |
23 | Off
24 |
25 |
26 | Off
27 |
28 |
29 | Off
30 |
31 |
32 | Off
33 |
34 |
35 | Off
36 |
37 |
38 | Off
39 |
40 |
41 | Off
42 |
43 |
--------------------------------------------------------------------------------
/crostouchpad/crostouchpad.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 | {8E41214B-6785-4CFE-B992-037D68949A14}
18 | inf;inv;inx;mof;mc;
19 |
20 |
21 |
22 |
23 | Header Files
24 |
25 |
26 | Header Files
27 |
28 |
29 | Header Files
30 |
31 |
32 | Header Files
33 |
34 |
35 | Header Files
36 |
37 |
38 | Header Files
39 |
40 |
41 |
42 |
43 | Source Files
44 |
45 |
46 | Source Files
47 |
48 |
49 |
50 |
51 | Driver Files
52 |
53 |
54 |
--------------------------------------------------------------------------------
/crostouchpad/crostouchpad.inf:
--------------------------------------------------------------------------------
1 | ;/*++
2 | ;
3 | ;Copyright (c) CoolStar. All rights reserved.
4 | ;
5 | ;Module Name:
6 | ; coolstar.inf
7 | ;
8 | ;Abstract:
9 | ; INF file for installing the Cypress v3 Touchpad Driver
10 | ;
11 | ;
12 | ;--*/
13 |
14 | [Version]
15 | Signature = "$WINDOWS NT$"
16 | Class = HIDClass
17 | ClassGuid = {745a17a0-74d3-11d0-b6fe-00a0c90f57da}
18 | Provider = CoolStar
19 | DriverVer = 2/15/2022,4.1.2
20 | CatalogFile = crostouchpad.cat
21 | PnpLockdown = 1
22 |
23 | [DestinationDirs]
24 | DefaultDestDir = 12
25 |
26 | ; ================= Class section =====================
27 |
28 | [SourceDisksNames]
29 | 1 = %DiskId1%,,,""
30 |
31 | [SourceDisksFiles]
32 | crostouchpad.sys = 1,,
33 |
34 | ;*****************************************
35 | ; CrosTouchpad Install Section
36 | ;*****************************************
37 |
38 | [Manufacturer]
39 | %StdMfg%=Standard,NT$ARCH$
40 |
41 | ; Decorated model section take precedence over undecorated
42 | ; ones on XP and later.
43 | [Standard.NT$ARCH$]
44 | %CrosTouchpad.DeviceDesc%=CrosTouchpad_Device, ACPI\CYAP0000
45 |
46 | [CrosTouchpad_Device.NT]
47 | CopyFiles=Drivers_Dir
48 |
49 | [CrosTouchpad_Device.NT.HW]
50 | AddReg=CrosTouchpad_AddReg
51 |
52 | [Drivers_Dir]
53 | crostouchpad.sys
54 |
55 | [CrosTouchpad_AddReg]
56 | ; Set to 1 to connect the first interrupt resource found, 0 to leave disconnected
57 | HKR,Settings,"ConnectInterrupt",0x00010001,0
58 | HKR,,"UpperFilters",0x00010000,"mshidkmdf"
59 |
60 | ;-------------- Service installation
61 | [CrosTouchpad_Device.NT.Services]
62 | AddService = CrosTouchpad,%SPSVCINST_ASSOCSERVICE%, CrosTouchpad_Service_Inst
63 |
64 | ; -------------- CrosTouchpad driver install sections
65 | [CrosTouchpad_Service_Inst]
66 | DisplayName = %CrosTouchpad.SVCDESC%
67 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER
68 | StartType = 3 ; SERVICE_DEMAND_START
69 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL
70 | ServiceBinary = %12%\crostouchpad.sys
71 | LoadOrderGroup = Base
72 |
73 | [Strings]
74 | SPSVCINST_ASSOCSERVICE= 0x00000002
75 | StdMfg = "CoolStar"
76 | DiskId1 = "CrosTouchpad Installation Disk #1"
77 | CrosTouchpad.DeviceDesc = "Chromebook Cypress v3 Touchpad"
78 | CrosTouchpad.SVCDESC = "CrosTouchpad Service"
79 |
--------------------------------------------------------------------------------
/crostouchpad/cyapa.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 The DragonFly Project. All rights reserved.
3 | *
4 | * This code is derived from software contributed to The DragonFly Project
5 | * by Matthew Dillon
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions
9 | * are met:
10 | *
11 | * 1. Redistributions of source code must retain the above copyright
12 | * notice, this list of conditions and the following disclaimer.
13 | * 2. Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in
15 | * the documentation and/or other materials provided with the
16 | * distribution.
17 | * 3. Neither the name of The DragonFly Project nor the names of its
18 | * contributors may be used to endorse or promote products derived
19 | * from this software without specific, prior written permission.
20 | *
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 | * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 | * SUCH DAMAGE.
33 | */
34 |
35 | #include "stdint.h"
36 |
37 | #ifndef __packed
38 | #define __packed( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
39 | #endif
40 |
41 | #ifndef _SYS_DEV_SMBUS_CYAPA_CYAPA_H_
42 | #define _SYS_DEV_SMBUS_CYAPA_CYAPA_H_
43 |
44 | #define CYAPA_MAX_MT 5
45 |
46 | /*
47 | * Boot-time registers. This is the device map
48 | * if (stat & CYAPA_STAT_RUNNING) is 0.
49 | */
50 | __packed(struct cyapa_boot_regs{
51 | uint8_t stat; /* CYAPA_STAT_xxx */
52 | uint8_t boot; /* CYAPA_BOOT_xxx */
53 | uint8_t error;
54 | });
55 |
56 | #define CYAPA_BOOT_BUSY 0x80
57 | #define CYAPA_BOOT_RUNNING 0x10
58 | #define CYAPA_BOOT_DATA_VALID 0x08
59 | #define CYAPA_BOOT_CSUM_VALID 0x01
60 |
61 | #define CYAPA_ERROR_INVALID 0x80
62 | #define CYAPA_ERROR_INVALID_KEY 0x40
63 | #define CYAPA_ERROR_BOOTLOADER 0x20
64 | #define CYAPA_ERROR_CMD_CSUM 0x10
65 | #define CYAPA_ERROR_FLASH_PROT 0x08
66 | #define CYAPA_ERROR_FLASH_CSUM 0x04
67 |
68 | /*
69 | * Gen3 Operational Device Status Register
70 | *
71 | * bit 7: Valid interrupt source
72 | * bit 6 - 4: Reserved
73 | * bit 3 - 2: Power status
74 | * bit 1 - 0: Device status
75 | */
76 | #define REG_OP_STATUS 0x00
77 | #define OP_STATUS_SRC 0x80
78 | #define OP_STATUS_POWER 0x0c
79 | #define OP_STATUS_DEV 0x03
80 | #define OP_STATUS_MASK (OP_STATUS_SRC | OP_STATUS_POWER | OP_STATUS_DEV)
81 |
82 | /*
83 | * Operational Finger Count/Button Flags Register
84 | *
85 | * bit 7 - 4: Number of touched finger
86 | * bit 3: Valid data
87 | * bit 2: Middle Physical Button
88 | * bit 1: Right Physical Button
89 | * bit 0: Left physical Button
90 | */
91 | #define REG_OP_DATA1 0x01
92 | #define OP_DATA_VALID 0x08
93 | #define OP_DATA_MIDDLE_BTN 0x04
94 | #define OP_DATA_RIGHT_BTN 0x02
95 | #define OP_DATA_LEFT_BTN 0x01
96 | #define OP_DATA_BTN_MASK (OP_DATA_MIDDLE_BTN | OP_DATA_RIGHT_BTN | \
97 | OP_DATA_LEFT_BTN)
98 |
99 | __packed(struct cyapa_regs{
100 | uint8_t stat;
101 | uint8_t fngr;
102 |
103 | struct {
104 | uint8_t xy_high; /* 7:4 high 4 bits of x */
105 | uint8_t x_low; /* 3:0 high 4 bits of y */
106 | uint8_t y_low;
107 | uint8_t pressure;
108 | uint8_t id; /* 1-15 incremented each touch */
109 | } touch[CYAPA_MAX_MT];
110 | });
111 |
112 | __packed(struct cyapa_cap{
113 | uint8_t prod_ida[5]; /* 0x00 - 0x04 */
114 | uint8_t prod_idb[6]; /* 0x05 - 0x0A */
115 | uint8_t prod_idc[2]; /* 0x0B - 0x0C */
116 | uint8_t reserved[6]; /* 0x0D - 0x12 */
117 | uint8_t buttons; /* 0x13 */
118 | uint8_t gen; /* 0x14, low 4 bits */
119 | uint8_t max_abs_xy_high;/* 0x15 7:4 high x bits, 3:0 high y bits */
120 | uint8_t max_abs_x_low; /* 0x16 */
121 | uint8_t max_abs_y_low; /* 0x17 */
122 | uint8_t phy_siz_xy_high;/* 0x18 7:4 high x bits, 3:0 high y bits */
123 | uint8_t phy_siz_x_low; /* 0x19 */
124 | uint8_t phy_siz_y_low; /* 0x1A */
125 | });
126 |
127 | #define CYAPA_STAT_RUNNING 0x80
128 | #define CYAPA_STAT_PWR_MASK 0x0C
129 | #define CYAPA_PWR_OFF 0x00
130 | #define CYAPA_PWR_IDLE 0x08
131 | #define CYAPA_PWR_ACTIVE 0x0C
132 |
133 | #define CYAPA_STAT_DEV_MASK 0x03
134 | #define CYAPA_DEV_NORMAL 0x03
135 | #define CYAPA_DEV_BUSY 0x01
136 |
137 | #define CYAPA_FNGR_DATA_VALID 0x08
138 | #define CYAPA_FNGR_MIDDLE 0x04
139 | #define CYAPA_FNGR_RIGHT 0x02
140 | #define CYAPA_FNGR_LEFT 0x01
141 | #define CYAPA_FNGR_NUMFINGERS(c) (((c) >> 4) & 0x0F)
142 |
143 | #define CYAPA_TOUCH_X(regs, i) ((((regs)->touch[i].xy_high << 4) & 0x0F00) | \
144 | (regs)->touch[i].x_low)
145 | #define CYAPA_TOUCH_Y(regs, i) ((((regs)->touch[i].xy_high << 8) & 0x0F00) | \
146 | (regs)->touch[i].y_low)
147 | #define CYAPA_TOUCH_P(regs, i) ((regs)->touch[i].pressure)
148 |
149 | #define CMD_BOOT_STATUS 0x00 /* only if in boot state */
150 | #define CMD_DEV_STATUS 0x00 /* only if in operational state */
151 | #define CMD_SOFT_RESET 0x28
152 | #define CMD_POWER_MODE 0x29
153 | #define CMD_POWER_MODE_OFF (0x00 << 2)
154 | #define CMD_POWER_MODE_IDLE (0x03 << 2)
155 | #define CMD_POWER_MODE_FULL (0x3f << 2)
156 | #define CMD_QUERY_CAPABILITIES 0x2A
157 |
158 |
159 | /*struct cyapa_softc {
160 | uint32_t x;
161 | uint32_t y;
162 | bool mousedown;
163 | int mousebutton;
164 | int lastnfingers;
165 | int lastid = -1;
166 | bool mousedownfromtap;
167 | int tick = 0;
168 | int tickssincelastclick = 0;
169 |
170 | int multitaskinggesturetick = 0;
171 | int multitaskingx;
172 | int multitaskingy;
173 | bool multitaskingdone;
174 | bool hasmoved;
175 |
176 | int scrollratelimit = 0;
177 | };*/
178 |
179 | static int cyapa_minpressure = 16;
180 | static int cyapa_norm_freq = 100;
181 |
182 | #define ZSCALE 10
183 | #define SIMULATE_BUT4 0x0100
184 | #define SIMULATE_BUT5 0x0200
185 | #define SIMULATE_LOCK 0x8000
186 |
187 | #define MXT_T9_RELEASE (1 << 5)
188 | #define MXT_T9_PRESS (1 << 6)
189 | #define MXT_T9_DETECT (1 << 7)
190 |
191 | #endif
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | bld/
24 | [Bb]in/
25 | [Oo]bj/
26 | [Ll]og/
27 |
28 | # Visual Studio 2015/2017 cache/options directory
29 | .vs/
30 | # Uncomment if you have tasks that create the project's static files in wwwroot
31 | #wwwroot/
32 |
33 | # Visual Studio 2017 auto generated files
34 | Generated\ Files/
35 |
36 | # MSTest test Results
37 | [Tt]est[Rr]esult*/
38 | [Bb]uild[Ll]og.*
39 |
40 | # NUNIT
41 | *.VisualState.xml
42 | TestResult.xml
43 |
44 | # Build Results of an ATL Project
45 | [Dd]ebugPS/
46 | [Rr]eleasePS/
47 | dlldata.c
48 |
49 | # Benchmark Results
50 | BenchmarkDotNet.Artifacts/
51 |
52 | # .NET Core
53 | project.lock.json
54 | project.fragment.lock.json
55 | artifacts/
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_h.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *_wpftmp.csproj
81 | *.log
82 | *.vspscc
83 | *.vssscc
84 | .builds
85 | *.pidb
86 | *.svclog
87 | *.scc
88 |
89 | # Chutzpah Test files
90 | _Chutzpah*
91 |
92 | # Visual C++ cache files
93 | ipch/
94 | *.aps
95 | *.ncb
96 | *.opendb
97 | *.opensdf
98 | *.sdf
99 | *.cachefile
100 | *.VC.db
101 | *.VC.VC.opendb
102 |
103 | # Visual Studio profiler
104 | *.psess
105 | *.vsp
106 | *.vspx
107 | *.sap
108 |
109 | # Visual Studio Trace Files
110 | *.e2e
111 |
112 | # TFS 2012 Local Workspace
113 | $tf/
114 |
115 | # Guidance Automation Toolkit
116 | *.gpState
117 |
118 | # ReSharper is a .NET coding add-in
119 | _ReSharper*/
120 | *.[Rr]e[Ss]harper
121 | *.DotSettings.user
122 |
123 | # JustCode is a .NET coding add-in
124 | .JustCode
125 |
126 | # TeamCity is a build add-in
127 | _TeamCity*
128 |
129 | # DotCover is a Code Coverage Tool
130 | *.dotCover
131 |
132 | # AxoCover is a Code Coverage Tool
133 | .axoCover/*
134 | !.axoCover/settings.json
135 |
136 | # Visual Studio code coverage results
137 | *.coverage
138 | *.coveragexml
139 |
140 | # NCrunch
141 | _NCrunch_*
142 | .*crunch*.local.xml
143 | nCrunchTemp_*
144 |
145 | # MightyMoose
146 | *.mm.*
147 | AutoTest.Net/
148 |
149 | # Web workbench (sass)
150 | .sass-cache/
151 |
152 | # Installshield output folder
153 | [Ee]xpress/
154 |
155 | # DocProject is a documentation generator add-in
156 | DocProject/buildhelp/
157 | DocProject/Help/*.HxT
158 | DocProject/Help/*.HxC
159 | DocProject/Help/*.hhc
160 | DocProject/Help/*.hhk
161 | DocProject/Help/*.hhp
162 | DocProject/Help/Html2
163 | DocProject/Help/html
164 |
165 | # Click-Once directory
166 | publish/
167 |
168 | # Publish Web Output
169 | *.[Pp]ublish.xml
170 | *.azurePubxml
171 | # Note: Comment the next line if you want to checkin your web deploy settings,
172 | # but database connection strings (with potential passwords) will be unencrypted
173 | *.pubxml
174 | *.publishproj
175 |
176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
177 | # checkin your Azure Web App publish settings, but sensitive information contained
178 | # in these scripts will be unencrypted
179 | PublishScripts/
180 |
181 | # NuGet Packages
182 | *.nupkg
183 | # The packages folder can be ignored because of Package Restore
184 | **/[Pp]ackages/*
185 | # except build/, which is used as an MSBuild target.
186 | !**/[Pp]ackages/build/
187 | # Uncomment if necessary however generally it will be regenerated when needed
188 | #!**/[Pp]ackages/repositories.config
189 | # NuGet v3's project.json files produces more ignorable files
190 | *.nuget.props
191 | *.nuget.targets
192 |
193 | # Microsoft Azure Build Output
194 | csx/
195 | *.build.csdef
196 |
197 | # Microsoft Azure Emulator
198 | ecf/
199 | rcf/
200 |
201 | # Windows Store app package directories and files
202 | AppPackages/
203 | BundleArtifacts/
204 | Package.StoreAssociation.xml
205 | _pkginfo.txt
206 | *.appx
207 |
208 | # Visual Studio cache files
209 | # files ending in .cache can be ignored
210 | *.[Cc]ache
211 | # but keep track of directories ending in .cache
212 | !*.[Cc]ache/
213 |
214 | # Others
215 | ClientBin/
216 | ~$*
217 | *~
218 | *.dbmdl
219 | *.dbproj.schemaview
220 | *.jfm
221 | *.pfx
222 | *.publishsettings
223 | orleans.codegen.cs
224 |
225 | # Including strong name files can present a security risk
226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
227 | #*.snk
228 |
229 | # Since there are multiple workflows, uncomment next line to ignore bower_components
230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
231 | #bower_components/
232 |
233 | # RIA/Silverlight projects
234 | Generated_Code/
235 |
236 | # Backup & report files from converting an old project file
237 | # to a newer Visual Studio version. Backup files are not needed,
238 | # because we have git ;-)
239 | _UpgradeReport_Files/
240 | Backup*/
241 | UpgradeLog*.XML
242 | UpgradeLog*.htm
243 | ServiceFabricBackup/
244 | *.rptproj.bak
245 |
246 | # SQL Server files
247 | *.mdf
248 | *.ldf
249 | *.ndf
250 |
251 | # Business Intelligence projects
252 | *.rdl.data
253 | *.bim.layout
254 | *.bim_*.settings
255 | *.rptproj.rsuser
256 |
257 | # Microsoft Fakes
258 | FakesAssemblies/
259 |
260 | # GhostDoc plugin setting file
261 | *.GhostDoc.xml
262 |
263 | # Node.js Tools for Visual Studio
264 | .ntvs_analysis.dat
265 | node_modules/
266 |
267 | # Visual Studio 6 build log
268 | *.plg
269 |
270 | # Visual Studio 6 workspace options file
271 | *.opt
272 |
273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
274 | *.vbw
275 |
276 | # Visual Studio LightSwitch build output
277 | **/*.HTMLClient/GeneratedArtifacts
278 | **/*.DesktopClient/GeneratedArtifacts
279 | **/*.DesktopClient/ModelManifest.xml
280 | **/*.Server/GeneratedArtifacts
281 | **/*.Server/ModelManifest.xml
282 | _Pvt_Extensions
283 |
284 | # Paket dependency manager
285 | .paket/paket.exe
286 | paket-files/
287 |
288 | # FAKE - F# Make
289 | .fake/
290 |
291 | # JetBrains Rider
292 | .idea/
293 | *.sln.iml
294 |
295 | # CodeRush personal settings
296 | .cr/personal
297 |
298 | # Python Tools for Visual Studio (PTVS)
299 | __pycache__/
300 | *.pyc
301 |
302 | # Cake - Uncomment if you are using it
303 | # tools/**
304 | # !tools/packages.config
305 |
306 | # Tabs Studio
307 | *.tss
308 |
309 | # Telerik's JustMock configuration file
310 | *.jmconfig
311 |
312 | # BizTalk build output
313 | *.btp.cs
314 | *.btm.cs
315 | *.odx.cs
316 | *.xsd.cs
317 |
318 | # OpenCover UI analysis results
319 | OpenCover/
320 |
321 | # Azure Stream Analytics local run output
322 | ASALocalRun/
323 |
324 | # MSBuild Binary and Structured Log
325 | *.binlog
326 |
327 | # NVidia Nsight GPU debugger configuration file
328 | *.nvuser
329 |
330 | # MFractors (Xamarin productivity tool) working folder
331 | .mfractor/
332 |
333 | # Local History for Visual Studio
334 | .localhistory/
335 |
--------------------------------------------------------------------------------
/crostouchpad4.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.40629.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crostouchpad", "crostouchpad\crostouchpad.vcxproj", "{B3E71397-9BE4-492B-AAED-4D056E59CB1F}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crostouchpad Package", "crostouchpad Package\crostouchpad Package.vcxproj", "{EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}"
9 | ProjectSection(ProjectDependencies) = postProject
10 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F} = {B3E71397-9BE4-492B-AAED-4D056E59CB1F}
11 | EndProjectSection
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Win7 Debug|Win32 = Win7 Debug|Win32
16 | Win7 Debug|x64 = Win7 Debug|x64
17 | Win7 Release|Win32 = Win7 Release|Win32
18 | Win7 Release|x64 = Win7 Release|x64
19 | Win8 Debug|Win32 = Win8 Debug|Win32
20 | Win8 Debug|x64 = Win8 Debug|x64
21 | Win8 Release|Win32 = Win8 Release|Win32
22 | Win8 Release|x64 = Win8 Release|x64
23 | Win8.1 Debug|Win32 = Win8.1 Debug|Win32
24 | Win8.1 Debug|x64 = Win8.1 Debug|x64
25 | Win8.1 Release|Win32 = Win8.1 Release|Win32
26 | Win8.1 Release|x64 = Win8.1 Release|x64
27 | EndGlobalSection
28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
29 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32
30 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32
31 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32
32 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64
33 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Debug|x64.Build.0 = Win7 Debug|x64
34 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64
35 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32
36 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Release|Win32.Build.0 = Win7 Release|Win32
37 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32
38 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Release|x64.ActiveCfg = Win7 Release|x64
39 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Release|x64.Build.0 = Win7 Release|x64
40 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win7 Release|x64.Deploy.0 = Win7 Release|x64
41 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32
42 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32
43 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32
44 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64
45 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|x64.Build.0 = Win8 Debug|x64
46 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64
47 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32
48 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|Win32.Build.0 = Win8 Release|Win32
49 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32
50 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|x64.ActiveCfg = Win8 Release|x64
51 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|x64.Build.0 = Win8 Release|x64
52 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|x64.Deploy.0 = Win8 Release|x64
53 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32
54 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32
55 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32
56 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64
57 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64
58 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64
59 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32
60 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32
61 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32
62 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64
63 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64
64 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64
65 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32
66 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32
67 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32
68 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64
69 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Debug|x64.Build.0 = Win7 Debug|x64
70 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64
71 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32
72 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Release|Win32.Build.0 = Win7 Release|Win32
73 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32
74 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Release|x64.ActiveCfg = Win7 Release|x64
75 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Release|x64.Build.0 = Win7 Release|x64
76 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win7 Release|x64.Deploy.0 = Win7 Release|x64
77 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32
78 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32
79 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32
80 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64
81 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|x64.Build.0 = Win8 Debug|x64
82 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64
83 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32
84 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|Win32.Build.0 = Win8 Release|Win32
85 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32
86 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|x64.ActiveCfg = Win8 Release|x64
87 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|x64.Build.0 = Win8 Release|x64
88 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|x64.Deploy.0 = Win8 Release|x64
89 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32
90 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32
91 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32
92 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64
93 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64
94 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64
95 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32
96 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32
97 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32
98 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64
99 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64
100 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64
101 | EndGlobalSection
102 | GlobalSection(SolutionProperties) = preSolution
103 | HideSolutionNode = FALSE
104 | EndGlobalSection
105 | EndGlobal
106 |
--------------------------------------------------------------------------------
/crostouchpad/spb.c:
--------------------------------------------------------------------------------
1 | /*++
2 | Copyright (c) Microsoft Corporation. All Rights Reserved.
3 | Sample code. Dealpoint ID #843729.
4 |
5 | Module Name:
6 |
7 | spb.c
8 |
9 | Abstract:
10 |
11 | Contains all I2C-specific functionality
12 |
13 | Environment:
14 |
15 | Kernel mode
16 |
17 | Revision History:
18 |
19 | --*/
20 |
21 | #include "driver.h"
22 | #include "spb.h"
23 | #include
24 |
25 | static ULONG CyapaDebugLevel = 100;
26 | static ULONG CyapaDebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL;
27 |
28 | NTSTATUS
29 | SpbDoWriteDataSynchronously(
30 | IN SPB_CONTEXT *SpbContext,
31 | IN UCHAR Address,
32 | IN PVOID Data,
33 | IN ULONG Length
34 | )
35 | /*++
36 |
37 | Routine Description:
38 |
39 | This helper routine abstracts creating and sending an I/O
40 | request (I2C Write) to the Spb I/O target.
41 |
42 | Arguments:
43 |
44 | SpbContext - Pointer to the current device context
45 | Address - The I2C register address to write to
46 | Data - A buffer to receive the data at at the above address
47 | Length - The amount of data to be read from the above address
48 |
49 | Return Value:
50 |
51 | NTSTATUS Status indicating success or failure
52 |
53 | --*/
54 | {
55 | PUCHAR buffer;
56 | ULONG length;
57 | WDFMEMORY memory;
58 | WDF_MEMORY_DESCRIPTOR memoryDescriptor;
59 | NTSTATUS status;
60 |
61 | //
62 | // The address pointer and data buffer must be combined
63 | // into one contiguous buffer representing the write transaction.
64 | //
65 | length = Length + 1;
66 | memory = NULL;
67 |
68 | if (length > DEFAULT_SPB_BUFFER_SIZE)
69 | {
70 | status = WdfMemoryCreate(
71 | WDF_NO_OBJECT_ATTRIBUTES,
72 | NonPagedPool,
73 | CYAPA_POOL_TAG,
74 | length,
75 | &memory,
76 | (PVOID *)&buffer);
77 |
78 | if (!NT_SUCCESS(status))
79 | {
80 | CyapaPrint(
81 | DEBUG_LEVEL_ERROR,
82 | DBG_IOCTL,
83 | "Error allocating memory for Spb write - %!STATUS!",
84 | status);
85 | goto exit;
86 | }
87 |
88 | WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(
89 | &memoryDescriptor,
90 | memory,
91 | NULL);
92 | }
93 | else
94 | {
95 | buffer = (PUCHAR)WdfMemoryGetBuffer(SpbContext->WriteMemory, NULL);
96 |
97 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
98 | &memoryDescriptor,
99 | (PVOID)buffer,
100 | length);
101 | }
102 |
103 | //
104 | // Transaction starts by specifying the address bytes
105 | //
106 | RtlCopyMemory(buffer, &Address, sizeof(Address));
107 |
108 | //
109 | // Address is followed by the data payload
110 | //
111 | RtlCopyMemory((buffer + sizeof(Address)), Data, length - sizeof(Address));
112 |
113 | status = WdfIoTargetSendWriteSynchronously(
114 | SpbContext->SpbIoTarget,
115 | NULL,
116 | &memoryDescriptor,
117 | NULL,
118 | NULL,
119 | NULL);
120 |
121 | if (!NT_SUCCESS(status))
122 | {
123 | CyapaPrint(
124 | DEBUG_LEVEL_ERROR,
125 | DBG_IOCTL,
126 | "Error writing to Spb - %!STATUS!",
127 | status);
128 | goto exit;
129 | }
130 |
131 | exit:
132 |
133 | if (NULL != memory)
134 | {
135 | WdfObjectDelete(memory);
136 | }
137 |
138 | return status;
139 | }
140 |
141 | NTSTATUS
142 | SpbWriteDataSynchronously(
143 | IN SPB_CONTEXT *SpbContext,
144 | IN UCHAR Address,
145 | IN PVOID Data,
146 | IN ULONG Length
147 | )
148 | /*++
149 |
150 | Routine Description:
151 |
152 | This routine abstracts creating and sending an I/O
153 | request (I2C Write) to the Spb I/O target and utilizes
154 | a helper routine to do work inside of locked code.
155 |
156 | Arguments:
157 |
158 | SpbContext - Pointer to the current device context
159 | Address - The I2C register address to write to
160 | Data - A buffer to receive the data at at the above address
161 | Length - The amount of data to be read from the above address
162 |
163 | Return Value:
164 |
165 | NTSTATUS Status indicating success or failure
166 |
167 | --*/
168 | {
169 | NTSTATUS status;
170 |
171 | WdfWaitLockAcquire(SpbContext->SpbLock, NULL);
172 |
173 | status = SpbDoWriteDataSynchronously(
174 | SpbContext,
175 | Address,
176 | Data,
177 | Length);
178 |
179 | WdfWaitLockRelease(SpbContext->SpbLock);
180 |
181 | return status;
182 | }
183 |
184 | NTSTATUS
185 | SpbReadDataSynchronously(
186 | _In_ SPB_CONTEXT *SpbContext,
187 | _In_ UCHAR Address,
188 | _In_reads_bytes_(Length) PVOID Data,
189 | _In_ ULONG Length
190 | )
191 | /*++
192 |
193 | Routine Description:
194 |
195 | This helper routine abstracts creating and sending an I/O
196 | request (I2C Read) to the Spb I/O target.
197 |
198 | Arguments:
199 |
200 | SpbContext - Pointer to the current device context
201 | Address - The I2C register address to read from
202 | Data - A buffer to receive the data at at the above address
203 | Length - The amount of data to be read from the above address
204 |
205 | Return Value:
206 |
207 | NTSTATUS Status indicating success or failure
208 |
209 | --*/
210 | {
211 | PUCHAR buffer;
212 | WDFMEMORY memory;
213 | WDF_MEMORY_DESCRIPTOR memoryDescriptor;
214 | NTSTATUS status;
215 | ULONG_PTR bytesRead;
216 |
217 | WdfWaitLockAcquire(SpbContext->SpbLock, NULL);
218 |
219 | memory = NULL;
220 | status = STATUS_INVALID_PARAMETER;
221 | bytesRead = 0;
222 |
223 | //
224 | // Read transactions start by writing an address pointer
225 | //
226 | status = SpbDoWriteDataSynchronously(
227 | SpbContext,
228 | Address,
229 | NULL,
230 | 0);
231 |
232 | if (!NT_SUCCESS(status))
233 | {
234 | CyapaPrint(
235 | DEBUG_LEVEL_ERROR,
236 | DBG_IOCTL,
237 | "Error setting address pointer for Spb read - %!STATUS!",
238 | status);
239 | goto exit;
240 | }
241 |
242 | if (Length > DEFAULT_SPB_BUFFER_SIZE)
243 | {
244 | status = WdfMemoryCreate(
245 | WDF_NO_OBJECT_ATTRIBUTES,
246 | NonPagedPool,
247 | CYAPA_POOL_TAG,
248 | Length,
249 | &memory,
250 | (PVOID *)&buffer);
251 |
252 | if (!NT_SUCCESS(status))
253 | {
254 | CyapaPrint(
255 | DEBUG_LEVEL_ERROR,
256 | DBG_IOCTL,
257 | "Error allocating memory for Spb read - %!STATUS!",
258 | status);
259 | goto exit;
260 | }
261 |
262 | WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(
263 | &memoryDescriptor,
264 | memory,
265 | NULL);
266 | }
267 | else
268 | {
269 | buffer = (PUCHAR)WdfMemoryGetBuffer(SpbContext->ReadMemory, NULL);
270 |
271 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
272 | &memoryDescriptor,
273 | (PVOID)buffer,
274 | Length);
275 | }
276 |
277 |
278 | status = WdfIoTargetSendReadSynchronously(
279 | SpbContext->SpbIoTarget,
280 | NULL,
281 | &memoryDescriptor,
282 | NULL,
283 | NULL,
284 | &bytesRead);
285 |
286 | if (!NT_SUCCESS(status) ||
287 | bytesRead != Length)
288 | {
289 | CyapaPrint(
290 | DEBUG_LEVEL_ERROR,
291 | DBG_IOCTL,
292 | "Error reading from Spb - %!STATUS!",
293 | status);
294 | goto exit;
295 | }
296 |
297 | //
298 | // Copy back to the caller's buffer
299 | //
300 | RtlCopyMemory(Data, buffer, Length);
301 |
302 | exit:
303 | if (NULL != memory)
304 | {
305 | WdfObjectDelete(memory);
306 | }
307 |
308 | WdfWaitLockRelease(SpbContext->SpbLock);
309 |
310 | return status;
311 | }
312 |
313 | VOID
314 | SpbTargetDeinitialize(
315 | IN WDFDEVICE FxDevice,
316 | IN SPB_CONTEXT *SpbContext
317 | )
318 | /*++
319 |
320 | Routine Description:
321 |
322 | This helper routine is used to free any members added to the SPB_CONTEXT,
323 | note the SPB I/O target is parented to the device and will be
324 | closed and free'd when the device is removed.
325 |
326 | Arguments:
327 |
328 | FxDevice - Handle to the framework device object
329 | SpbContext - Pointer to the current device context
330 |
331 | Return Value:
332 |
333 | NTSTATUS Status indicating success or failure
334 |
335 | --*/
336 | {
337 | UNREFERENCED_PARAMETER(FxDevice);
338 | UNREFERENCED_PARAMETER(SpbContext);
339 |
340 | //
341 | // Free any SPB_CONTEXT allocations here
342 | //
343 | if (SpbContext->SpbLock != NULL)
344 | {
345 | WdfObjectDelete(SpbContext->SpbLock);
346 | }
347 |
348 | if (SpbContext->ReadMemory != NULL)
349 | {
350 | WdfObjectDelete(SpbContext->ReadMemory);
351 | }
352 |
353 | if (SpbContext->WriteMemory != NULL)
354 | {
355 | WdfObjectDelete(SpbContext->WriteMemory);
356 | }
357 | }
358 |
359 | NTSTATUS
360 | SpbTargetInitialize(
361 | IN WDFDEVICE FxDevice,
362 | IN SPB_CONTEXT *SpbContext
363 | )
364 | /*++
365 |
366 | Routine Description:
367 |
368 | This helper routine opens the Spb I/O target and
369 | initializes a request object used for the lifetime
370 | of communication between this driver and Spb.
371 |
372 | Arguments:
373 |
374 | FxDevice - Handle to the framework device object
375 | SpbContext - Pointer to the current device context
376 |
377 | Return Value:
378 |
379 | NTSTATUS Status indicating success or failure
380 |
381 | --*/
382 | {
383 | WDF_OBJECT_ATTRIBUTES objectAttributes;
384 | WDF_IO_TARGET_OPEN_PARAMS openParams;
385 | UNICODE_STRING spbDeviceName;
386 | WCHAR spbDeviceNameBuffer[RESOURCE_HUB_PATH_SIZE];
387 | NTSTATUS status;
388 |
389 | WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes);
390 | objectAttributes.ParentObject = FxDevice;
391 |
392 | status = WdfIoTargetCreate(
393 | FxDevice,
394 | &objectAttributes,
395 | &SpbContext->SpbIoTarget);
396 |
397 | if (!NT_SUCCESS(status))
398 | {
399 | CyapaPrint(
400 | DEBUG_LEVEL_ERROR,
401 | DBG_IOCTL,
402 | "Error creating IoTarget object - %!STATUS!",
403 | status);
404 |
405 | WdfObjectDelete(SpbContext->SpbIoTarget);
406 | goto exit;
407 | }
408 |
409 | RtlInitEmptyUnicodeString(
410 | &spbDeviceName,
411 | spbDeviceNameBuffer,
412 | sizeof(spbDeviceNameBuffer));
413 |
414 | status = RESOURCE_HUB_CREATE_PATH_FROM_ID(
415 | &spbDeviceName,
416 | SpbContext->I2cResHubId.LowPart,
417 | SpbContext->I2cResHubId.HighPart);
418 |
419 | if (!NT_SUCCESS(status))
420 | {
421 | CyapaPrint(
422 | DEBUG_LEVEL_ERROR,
423 | DBG_IOCTL,
424 | "Error creating Spb resource hub path string - %!STATUS!",
425 | status);
426 | goto exit;
427 | }
428 |
429 | WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
430 | &openParams,
431 | &spbDeviceName,
432 | (GENERIC_READ | GENERIC_WRITE));
433 |
434 | openParams.ShareAccess = 0;
435 | openParams.CreateDisposition = FILE_OPEN;
436 | openParams.FileAttributes = FILE_ATTRIBUTE_NORMAL;
437 |
438 | status = WdfIoTargetOpen(SpbContext->SpbIoTarget, &openParams);
439 |
440 | if (!NT_SUCCESS(status))
441 | {
442 | CyapaPrint(
443 | DEBUG_LEVEL_ERROR,
444 | DBG_IOCTL,
445 | "Error opening Spb target for communication - %!STATUS!",
446 | status);
447 | goto exit;
448 | }
449 |
450 | //
451 | // Allocate some fixed-size buffers from NonPagedPool for typical
452 | // Spb transaction sizes to avoid pool fragmentation in most cases
453 | //
454 | status = WdfMemoryCreate(
455 | WDF_NO_OBJECT_ATTRIBUTES,
456 | NonPagedPool,
457 | CYAPA_POOL_TAG,
458 | DEFAULT_SPB_BUFFER_SIZE,
459 | &SpbContext->WriteMemory,
460 | NULL);
461 |
462 | if (!NT_SUCCESS(status))
463 | {
464 | CyapaPrint(
465 | DEBUG_LEVEL_ERROR,
466 | DBG_IOCTL,
467 | "Error allocating default memory for Spb write - %!STATUS!",
468 | status);
469 | goto exit;
470 | }
471 |
472 | status = WdfMemoryCreate(
473 | WDF_NO_OBJECT_ATTRIBUTES,
474 | NonPagedPool,
475 | CYAPA_POOL_TAG,
476 | DEFAULT_SPB_BUFFER_SIZE,
477 | &SpbContext->ReadMemory,
478 | NULL);
479 |
480 | if (!NT_SUCCESS(status))
481 | {
482 | CyapaPrint(
483 | DEBUG_LEVEL_ERROR,
484 | DBG_IOCTL,
485 | "Error allocating default memory for Spb read - %!STATUS!",
486 | status);
487 | goto exit;
488 | }
489 |
490 | //
491 | // Allocate a waitlock to guard access to the default buffers
492 | //
493 | status = WdfWaitLockCreate(
494 | WDF_NO_OBJECT_ATTRIBUTES,
495 | &SpbContext->SpbLock);
496 |
497 | if (!NT_SUCCESS(status))
498 | {
499 | CyapaPrint(
500 | DEBUG_LEVEL_ERROR,
501 | DBG_IOCTL,
502 | "Error creating Spb Waitlock - %!STATUS!",
503 | status);
504 | goto exit;
505 | }
506 |
507 | exit:
508 |
509 | if (!NT_SUCCESS(status))
510 | {
511 | SpbTargetDeinitialize(FxDevice, SpbContext);
512 | }
513 |
514 | return status;
515 | }
--------------------------------------------------------------------------------
/crostouchpad/driver.h:
--------------------------------------------------------------------------------
1 | #if !defined(_CYAPA_H_)
2 | #define _CYAPA_H_
3 |
4 | #pragma warning(disable:4200) // suppress nameless struct/union warning
5 | #pragma warning(disable:4201) // suppress nameless struct/union warning
6 | #pragma warning(disable:4214) // suppress bit field types other than int warning
7 | #include
8 | #include
9 |
10 | #pragma warning(default:4200)
11 | #pragma warning(default:4201)
12 | #pragma warning(default:4214)
13 | #include
14 |
15 | #pragma warning(disable:4201) // suppress nameless struct/union warning
16 | #pragma warning(disable:4214) // suppress bit field types other than int warning
17 | #include
18 |
19 | #include "hidcommon.h"
20 | #include "spb.h"
21 | #include "cyapa.h"
22 |
23 | //
24 | // String definitions
25 | //
26 |
27 | #define DRIVERNAME "crostouchpad4.sys: "
28 |
29 | #define CYAPA_POOL_TAG (ULONG) 'payC'
30 |
31 | #define NTDEVICE_NAME_STRING L"\\Device\\CYAP0000"
32 | #define SYMBOLIC_NAME_STRING L"\\DosDevices\\CYAP0000"
33 |
34 | #define MT_TOUCH_COLLECTION0 \
35 | 0xa1, 0x02, /* COLLECTION (Logical) */ \
36 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \
37 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \
38 | 0x09, 0x47, /* USAGE (Confidence) */ \
39 | 0x09, 0x42, /* USAGE (Tip switch) */ \
40 | 0x95, 0x02, /* REPORT_COUNT (2) */ \
41 | 0x75, 0x01, /* REPORT_SIZE (1) */ \
42 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
43 | 0x95, 0x06, /* REPORT_COUNT (6) */ \
44 | 0x81, 0x03, /* INPUT (Cnst,Ary,Abs) */ \
45 | 0x95, 0x01, /* REPORT_COUNT (1) */ \
46 | 0x75, 0x04, /* REPORT_SIZE (4) */ \
47 | 0x25, 0x10, /* LOGICAL_MAXIMUM (16) */ \
48 | 0x09, 0x51, /* USAGE (Contact Identifier)*/ \
49 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
50 | 0x75, 0x01, /* REPORT_SIZE (1) */ \
51 | 0x95, 0x04, /* REPORT_COUNT (4) */ \
52 | 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \
53 | 0x05, 0x01, /* USAGE_PAGE (Generic Desk..*/ \
54 | 0x75, 0x10, /* REPORT_SIZE (16) */ \
55 | 0x55, 0x0e, /* UNIT_EXPONENT (-2) */ \
56 | /*0x65, 0x13, /* UNIT(Inch,EngLinear) */ \
57 | 0x65, 0x11, /* UNIT(Cm,SiLinear) */ \
58 | 0x09, 0x30, /* USAGE (X) */ \
59 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \
60 | 0x35, 0x00, /* PHYSICAL_MINIMUM (0) */ \
61 |
62 | #define MT_TOUCH_COLLECTION1 \
63 | 0x95, 0x01, /* REPORT_COUNT (1) */ \
64 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
65 |
66 | #define MT_TOUCH_COLLECTION2 \
67 | 0x09, 0x31, /* USAGE (Y) */ \
68 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
69 | 0x05, 0x0d, /* USAGE PAGE (Digitizers) */ \
70 | 0x25, 0x28, /* LOGICAL_MAXIMUM (40) */ \
71 | 0x09, 0x30, /* USAGE (Tip Pressure) */ \
72 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
73 | 0xc0, /* END_COLLECTION */
74 |
75 | #define MT_REF_TOUCH_COLLECTION \
76 | MT_TOUCH_COLLECTION0 \
77 | 0x26, 0x66, 0x03, /* LOGICAL_MAXIMUM (870) */ \
78 | 0x46, 0x8E, 0x03, /* PHYSICAL_MAXIMUM (910) */ \
79 | MT_TOUCH_COLLECTION1 \
80 | 0x26, 0xE0, 0x01, /* LOGICAL_MAXIMUM (480) */ \
81 | 0x46, 0xFE, 0x01, /* PHYSICAL_MAXIMUM (550) */ \
82 | MT_TOUCH_COLLECTION2
83 |
84 | #define USAGE_PAGES \
85 | 0x55, 0x0C, /* UNIT_EXPONENT (-4) */ \
86 | 0x66, 0x01, 0x10, /* UNIT (Seconds) */ \
87 | 0x47, 0xff, 0xff, 0x00, 0x00, /* PHYSICAL_MAXIMUM (65535) */ \
88 | 0x27, 0xff, 0xff, 0x00, 0x00, /* LOGICAL_MAXIMUM (65535) */ \
89 | 0x75, 0x10, /* REPORT_SIZE (16) */ \
90 | 0x95, 0x01, /* REPORT_COUNT (1) */ \
91 | 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */ \
92 | 0x09, 0x56, /* USAGE (Scan Time) */ \
93 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
94 | 0x09, 0x54, /* USAGE (Contact count) */ \
95 | 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ \
96 | 0x95, 0x01, /* REPORT_COUNT (1) */ \
97 | 0x75, 0x08, /* REPORT_SIZE (8) */ \
98 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
99 | 0x05, 0x09, /* USAGE_PAGE (Button) */ \
100 | 0x09, 0x01, /* USAGE_(Button 1) */ \
101 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \
102 | 0x75, 0x01, /* REPORT_SIZE (1) */ \
103 | 0x95, 0x01, /* REPORT_COUNT (1) */ \
104 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
105 | 0x95, 0x07, /* REPORT_COUNT (7) */ \
106 | 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \
107 | 0x05, 0x0d, /* USAGE_PAGE (Digitizer) */ \
108 | 0x85, REPORTID_MTOUCH, /* REPORT_ID (Feature) */ \
109 | 0x09, 0x55, /* USAGE (Contact Count Maximum) */ \
110 | 0x09, 0x59, /* USAGE (Pad TYpe) */ \
111 | 0x75, 0x08, /* REPORT_SIZE (8) */ \
112 | 0x95, 0x02, /* REPORT_COUNT (2) */ \
113 | 0x25, 0x0f, /* LOGICAL_MAXIMUM (15) */ \
114 | 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */ \
115 | 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */ \
116 | 0x85, REPORTID_PTPHQA, /* Report ID (Certification) */ \
117 | 0x09, 0xC5, /* Usage (0xC5) */ \
118 | 0x15, 0x00, /* Logical Minimum (0) */ \
119 | 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ \
120 | 0x75, 0x08, /* Report Size (8) */ \
121 | 0x96, 0x00, 0x01, /* Report Count (256) */ \
122 | 0xB1, 0x02, /* Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */ \
123 | 0xc0, /* END_COLLECTION */ \
124 | \
125 | /*MOUSE TLC */ \
126 | 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \
127 | 0x09, 0x02, /* USAGE (Mouse) */ \
128 | 0xa1, 0x01, /* COLLECTION (Application) */ \
129 | 0x85, REPORTID_MOUSE, /* REPORT_ID (Mouse) */ \
130 | 0x09, 0x01, /* USAGE (Pointer) */ \
131 | 0xa1, 0x00, /* COLLECTION (Physical) */ \
132 | 0x05, 0x09, /* USAGE_PAGE (Button) */ \
133 | 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ \
134 | 0x29, 0x02, /* USAGE_MAXIMUM (Button 2) */ \
135 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \
136 | 0x75, 0x01, /* REPORT_SIZE (1) */ \
137 | 0x95, 0x02, /* REPORT_COUNT (2) */ \
138 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
139 | 0x95, 0x06, /* REPORT_COUNT (6) */ \
140 | 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \
141 | 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \
142 | 0x09, 0x30, /* USAGE (X) */ \
143 | 0x09, 0x31, /* USAGE (Y) */ \
144 | 0x75, 0x10, /* REPORT_SIZE (16) */ \
145 | 0x95, 0x02, /* REPORT_COUNT (2) */ \
146 | 0x25, 0x0a, /* LOGICAL_MAXIMUM (10) */ \
147 | 0x81, 0x06, /* INPUT (Data,Var,Rel) */ \
148 | 0xc0, /* END_COLLECTION */ \
149 | 0xc0, /*END_COLLECTION */
150 | //
151 | // This is the default report descriptor for the Hid device provided
152 | // by the mini driver in response to IOCTL_HID_GET_REPORT_DESCRIPTOR.
153 | //
154 |
155 | typedef UCHAR HID_REPORT_DESCRIPTOR, *PHID_REPORT_DESCRIPTOR;
156 |
157 | #ifdef DESCRIPTOR_DEF
158 | HID_REPORT_DESCRIPTOR DefaultReportDescriptor[] = {
159 | //
160 | // Multitouch report starts here
161 | //
162 | //TOUCH PAD input TLC
163 | 0x05, 0x0d, // USAGE_PAGE (Digitizers)
164 | 0x09, 0x05, // USAGE (Touch Pad)
165 | 0xa1, 0x01, // COLLECTION (Application)
166 | 0x85, REPORTID_MTOUCH, // REPORT_ID (Touch pad)
167 | 0x09, 0x22, // USAGE (Finger)
168 | MT_REF_TOUCH_COLLECTION
169 | MT_REF_TOUCH_COLLECTION
170 | MT_REF_TOUCH_COLLECTION
171 | MT_REF_TOUCH_COLLECTION
172 | MT_REF_TOUCH_COLLECTION
173 | USAGE_PAGES
174 | };
175 |
176 |
177 | //
178 | // This is the default HID descriptor returned by the mini driver
179 | // in response to IOCTL_HID_GET_DEVICE_DESCRIPTOR. The size
180 | // of report descriptor is currently the size of DefaultReportDescriptor.
181 | //
182 |
183 | CONST HID_DESCRIPTOR DefaultHidDescriptor = {
184 | 0x09, // length of HID descriptor
185 | 0x21, // descriptor type == HID 0x21
186 | 0x0100, // hid spec release
187 | 0x00, // country code == Not Specified
188 | 0x01, // number of HID class descriptors
189 | { 0x22, // descriptor type
190 | sizeof(DefaultReportDescriptor) } // total length of report descriptor
191 | };
192 | #endif
193 |
194 | #define true 1
195 | #define false 0
196 |
197 | typedef struct _CYAPA_CONTEXT
198 | {
199 |
200 | //
201 | // Handle back to the WDFDEVICE
202 | //
203 |
204 | WDFDEVICE FxDevice;
205 |
206 | WDFQUEUE ReportQueue;
207 |
208 | BYTE DeviceMode;
209 |
210 | SPB_CONTEXT I2CContext;
211 |
212 | WDFINTERRUPT Interrupt;
213 |
214 | BOOLEAN ConnectInterrupt;
215 |
216 | BOOLEAN RegsSet;
217 |
218 | uint8_t Flags[15];
219 |
220 | USHORT XValue[15];
221 |
222 | USHORT YValue[15];
223 |
224 | USHORT PValue[15];
225 |
226 | BOOLEAN BUTTONPRESSED;
227 |
228 | USHORT TIMEINT;
229 |
230 | LARGE_INTEGER LastTime;
231 |
232 | uint16_t max_x;
233 | uint16_t max_y;
234 |
235 | uint8_t max_x_hid[2];
236 | uint8_t max_y_hid[2];
237 |
238 | uint16_t phy_x;
239 | uint16_t phy_y;
240 |
241 | uint8_t phy_x_hid[2];
242 | uint8_t phy_y_hid[2];
243 |
244 | WDFREQUEST lastRequest;
245 |
246 | } CYAPA_CONTEXT, *PCYAPA_CONTEXT;
247 |
248 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CYAPA_CONTEXT, GetDeviceContext)
249 |
250 | //
251 | // Function definitions
252 | //
253 |
254 | DRIVER_INITIALIZE DriverEntry;
255 |
256 | EVT_WDF_DRIVER_UNLOAD CyapaDriverUnload;
257 |
258 | EVT_WDF_DRIVER_DEVICE_ADD CyapaEvtDeviceAdd;
259 |
260 | EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL CyapaEvtInternalDeviceControl;
261 |
262 | NTSTATUS
263 | CyapaGetHidDescriptor(
264 | IN WDFDEVICE Device,
265 | IN WDFREQUEST Request
266 | );
267 |
268 | NTSTATUS
269 | CyapaGetReportDescriptor(
270 | IN WDFDEVICE Device,
271 | IN WDFREQUEST Request,
272 | IN BOOLEAN Retried,
273 | OUT BOOLEAN* CompleteRequest
274 | );
275 |
276 | NTSTATUS
277 | CyapaGetDeviceAttributes(
278 | IN WDFREQUEST Request
279 | );
280 |
281 | NTSTATUS
282 | CyapaGetString(
283 | IN WDFREQUEST Request
284 | );
285 |
286 | NTSTATUS
287 | CyapaWriteReport(
288 | IN PCYAPA_CONTEXT DevContext,
289 | IN WDFREQUEST Request
290 | );
291 |
292 | NTSTATUS
293 | CyapaProcessVendorReport(
294 | IN PCYAPA_CONTEXT DevContext,
295 | IN PVOID ReportBuffer,
296 | IN ULONG ReportBufferLen,
297 | OUT size_t* BytesWritten
298 | );
299 |
300 | NTSTATUS
301 | CyapaReadReport(
302 | IN PCYAPA_CONTEXT DevContext,
303 | IN WDFREQUEST Request,
304 | OUT BOOLEAN* CompleteRequest
305 | );
306 |
307 | NTSTATUS
308 | CyapaSetFeature(
309 | IN PCYAPA_CONTEXT DevContext,
310 | IN WDFREQUEST Request,
311 | OUT BOOLEAN* CompleteRequest
312 | );
313 |
314 | NTSTATUS
315 | CyapaGetFeature(
316 | IN PCYAPA_CONTEXT DevContext,
317 | IN WDFREQUEST Request,
318 | OUT BOOLEAN* CompleteRequest
319 | );
320 |
321 | PCHAR
322 | DbgHidInternalIoctlString(
323 | IN ULONG IoControlCode
324 | );
325 |
326 | //
327 | // Helper macros
328 | //
329 |
330 | #define DEBUG_LEVEL_ERROR 1
331 | #define DEBUG_LEVEL_INFO 2
332 | #define DEBUG_LEVEL_VERBOSE 3
333 |
334 | #define DBG_INIT 1
335 | #define DBG_PNP 2
336 | #define DBG_IOCTL 4
337 |
338 | #if 0
339 | #define CyapaPrint(dbglevel, dbgcatagory, fmt, ...) { \
340 | if (CyapaDebugLevel >= dbglevel && \
341 | (CyapaDebugCatagories && dbgcatagory)) \
342 | { \
343 | DbgPrint(DRIVERNAME); \
344 | DbgPrint(fmt, __VA_ARGS__); \
345 | } \
346 | }
347 | #else
348 | #define CyapaPrint(dbglevel, fmt, ...) { \
349 | }
350 | #endif
351 |
352 | #endif
353 |
--------------------------------------------------------------------------------
/crostouchpad/crostouchpad.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Win8.1 Debug
6 | Win32
7 |
8 |
9 | Win8.1 Release
10 | Win32
11 |
12 |
13 | Win8 Debug
14 | Win32
15 |
16 |
17 | Win8 Release
18 | Win32
19 |
20 |
21 | Win7 Debug
22 | Win32
23 |
24 |
25 | Win7 Release
26 | Win32
27 |
28 |
29 | Win8.1 Debug
30 | x64
31 |
32 |
33 | Win8.1 Release
34 | x64
35 |
36 |
37 | Win8 Debug
38 | x64
39 |
40 |
41 | Win8 Release
42 | x64
43 |
44 |
45 | Win7 Debug
46 | x64
47 |
48 |
49 | Win7 Release
50 | x64
51 |
52 |
53 |
54 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}
55 | {1bc93793-694f-48fe-9372-81e2b05556fd}
56 | v4.5
57 | 11.0
58 | Win8.1 Debug
59 | Win32
60 | crostouchpad
61 | 10.0.22000.0
62 | crostouchpad
63 |
64 |
65 |
66 | WindowsV6.3
67 | true
68 | WindowsKernelModeDriver10.0
69 | Driver
70 | KMDF
71 |
72 |
73 | WindowsV6.3
74 | false
75 | WindowsKernelModeDriver10.0
76 | Driver
77 | KMDF
78 |
79 |
80 | Windows8
81 | true
82 | WindowsKernelModeDriver10.0
83 | Driver
84 | KMDF
85 |
86 |
87 | Windows8
88 | false
89 | WindowsKernelModeDriver10.0
90 | Driver
91 | KMDF
92 |
93 |
94 | Windows7
95 | true
96 | WindowsKernelModeDriver10.0
97 | Driver
98 | KMDF
99 |
100 |
101 | Windows7
102 | false
103 | WindowsKernelModeDriver10.0
104 | Driver
105 | KMDF
106 |
107 |
108 | WindowsV6.3
109 | true
110 | WindowsKernelModeDriver10.0
111 | Driver
112 | KMDF
113 |
114 |
115 | WindowsV6.3
116 | false
117 | WindowsKernelModeDriver10.0
118 | Driver
119 | KMDF
120 |
121 |
122 | Windows8
123 | true
124 | WindowsKernelModeDriver10.0
125 | Driver
126 | KMDF
127 |
128 |
129 | Windows8
130 | false
131 | WindowsKernelModeDriver10.0
132 | Driver
133 | KMDF
134 |
135 |
136 | Windows7
137 | true
138 | WindowsKernelModeDriver10.0
139 | Driver
140 | KMDF
141 |
142 |
143 | Windows7
144 | false
145 | WindowsKernelModeDriver10.0
146 | Driver
147 | KMDF
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 | DbgengKernelDebugger
159 |
160 |
161 | DbgengKernelDebugger
162 |
163 |
164 | DbgengKernelDebugger
165 |
166 |
167 | DbgengKernelDebugger
168 |
169 |
170 | DbgengKernelDebugger
171 |
172 |
173 | DbgengKernelDebugger
174 |
175 |
176 | DbgengKernelDebugger
177 |
178 |
179 | DbgengKernelDebugger
180 |
181 |
182 | DbgengKernelDebugger
183 |
184 |
185 | DbgengKernelDebugger
186 |
187 |
188 | DbgengKernelDebugger
189 |
190 |
191 | DbgengKernelDebugger
192 |
193 |
194 |
195 | true
196 | trace.h
197 | true
198 | false
199 |
200 |
201 | 4.1.3
202 |
203 |
204 |
205 |
206 | true
207 | trace.h
208 | true
209 | false
210 |
211 |
212 | 4.1.3
213 |
214 |
215 |
216 |
217 | true
218 | trace.h
219 | true
220 | false
221 |
222 |
223 | 4.1.3
224 |
225 |
226 |
227 |
228 | true
229 | trace.h
230 | true
231 | false
232 |
233 |
234 | 4.1.3
235 |
236 |
237 |
238 |
239 | true
240 | trace.h
241 | true
242 | false
243 |
244 |
245 | 4.1.3
246 |
247 |
248 |
249 |
250 | true
251 | trace.h
252 | true
253 | false
254 |
255 |
256 | 4.1.3
257 |
258 |
259 |
260 |
261 | true
262 | trace.h
263 | true
264 | false
265 |
266 |
267 | 4.1.3
268 |
269 |
270 |
271 |
272 | true
273 | trace.h
274 | true
275 | false
276 |
277 |
278 | 4.1.3
279 |
280 |
281 |
282 |
283 | true
284 | trace.h
285 | true
286 | false
287 |
288 |
289 | 4.1.3
290 |
291 |
292 |
293 |
294 | true
295 | trace.h
296 | true
297 | false
298 |
299 |
300 | 4.1.3
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 | true
310 | trace.h
311 | true
312 | false
313 |
314 |
315 | 4.1.3
316 |
317 |
318 |
319 |
320 | true
321 | trace.h
322 | true
323 | false
324 |
325 |
326 | 4.1.3
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
--------------------------------------------------------------------------------
/crostouchpad Package/crostouchpad Package.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Win8.1 Debug
6 | Win32
7 |
8 |
9 | Win8.1 Release
10 | Win32
11 |
12 |
13 | Win8 Debug
14 | Win32
15 |
16 |
17 | Win8 Release
18 | Win32
19 |
20 |
21 | Win7 Debug
22 | Win32
23 |
24 |
25 | Win7 Release
26 | Win32
27 |
28 |
29 | Win8.1 Debug
30 | x64
31 |
32 |
33 | Win8.1 Release
34 | x64
35 |
36 |
37 | Win8 Debug
38 | x64
39 |
40 |
41 | Win8 Release
42 | x64
43 |
44 |
45 | Win7 Debug
46 | x64
47 |
48 |
49 | Win7 Release
50 | x64
51 |
52 |
53 |
54 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}
55 | {4605da2c-74a5-4865-98e1-152ef136825f}
56 | v4.5
57 | 11.0
58 | Win8.1 Debug
59 | Win32
60 | crostouchpad_Package
61 | 10.0.22000.0
62 | crostouchpad Package
63 |
64 |
65 |
66 | WindowsV6.3
67 | true
68 | WindowsKernelModeDriver10.0
69 | Utility
70 | Package
71 | true
72 |
73 |
74 | WindowsV6.3
75 | false
76 | WindowsKernelModeDriver10.0
77 | Utility
78 | Package
79 | true
80 |
81 |
82 | Windows8
83 | true
84 | WindowsKernelModeDriver10.0
85 | Utility
86 | Package
87 | true
88 |
89 |
90 | Windows8
91 | false
92 | WindowsKernelModeDriver10.0
93 | Utility
94 | Package
95 | true
96 |
97 |
98 | Windows7
99 | true
100 | WindowsKernelModeDriver10.0
101 | Utility
102 | Package
103 | true
104 |
105 |
106 | Windows7
107 | false
108 | WindowsKernelModeDriver10.0
109 | Utility
110 | Package
111 | true
112 |
113 |
114 | WindowsV6.3
115 | true
116 | WindowsKernelModeDriver10.0
117 | Utility
118 | Package
119 | true
120 |
121 |
122 | WindowsV6.3
123 | false
124 | WindowsKernelModeDriver10.0
125 | Utility
126 | Package
127 | true
128 |
129 |
130 | Windows8
131 | true
132 | WindowsKernelModeDriver10.0
133 | Utility
134 | Package
135 | true
136 |
137 |
138 | Windows8
139 | false
140 | WindowsKernelModeDriver10.0
141 | Utility
142 | Package
143 | true
144 |
145 |
146 | Windows7
147 | true
148 | WindowsKernelModeDriver10.0
149 | Utility
150 | Package
151 | true
152 |
153 |
154 | Windows7
155 | false
156 | WindowsKernelModeDriver10.0
157 | Utility
158 | Package
159 | true
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | DbgengKernelDebugger
171 | False
172 | True
173 |
174 |
175 |
176 | False
177 | False
178 | True
179 |
180 | 133563
181 |
182 |
183 | DbgengKernelDebugger
184 | False
185 | True
186 |
187 |
188 |
189 | False
190 | False
191 | True
192 |
193 | 133563
194 |
195 |
196 | DbgengKernelDebugger
197 | False
198 | True
199 |
200 |
201 |
202 | False
203 | False
204 | True
205 |
206 | 133563
207 |
208 |
209 | DbgengKernelDebugger
210 | False
211 | True
212 |
213 |
214 |
215 | False
216 | False
217 | True
218 |
219 | 133563
220 |
221 |
222 | DbgengKernelDebugger
223 | False
224 | True
225 |
226 |
227 |
228 | False
229 | False
230 | True
231 |
232 | 133563
233 |
234 |
235 | DbgengKernelDebugger
236 | False
237 | True
238 |
239 |
240 |
241 | False
242 | False
243 | True
244 |
245 | 133563
246 |
247 |
248 | DbgengKernelDebugger
249 | False
250 | True
251 |
252 |
253 |
254 | False
255 | False
256 | True
257 |
258 | 133563
259 |
260 |
261 | DbgengKernelDebugger
262 | False
263 | True
264 |
265 |
266 |
267 | False
268 | False
269 | True
270 |
271 | 133563
272 |
273 |
274 | DbgengKernelDebugger
275 | False
276 | True
277 |
278 |
279 |
280 | False
281 | False
282 | True
283 |
284 | 133563
285 |
286 |
287 | DbgengKernelDebugger
288 | False
289 | True
290 |
291 |
292 |
293 | False
294 | False
295 | True
296 |
297 | 133563
298 |
299 |
300 | DbgengKernelDebugger
301 | False
302 | True
303 |
304 |
305 |
306 | False
307 | False
308 | True
309 |
310 | 133563
311 |
312 |
313 | DbgengKernelDebugger
314 | False
315 | True
316 |
317 |
318 |
319 | False
320 | False
321 | True
322 |
323 | 133563
324 |
325 |
326 |
327 | SHA256
328 |
329 |
330 |
331 |
332 | SHA256
333 |
334 |
335 |
336 |
337 | SHA256
338 |
339 |
340 |
341 |
342 | SHA256
343 |
344 |
345 |
346 |
347 | SHA256
348 |
349 |
350 |
351 |
352 | SHA256
353 |
354 |
355 |
356 |
357 | SHA256
358 |
359 |
360 |
361 |
362 | SHA256
363 |
364 |
365 |
366 |
367 | SHA256
368 |
369 |
370 |
371 |
372 | SHA256
373 |
374 |
375 |
376 |
377 | SHA256
378 |
379 |
380 |
381 |
382 | SHA256
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 | {b3e71397-9be4-492b-aaed-4d056e59cb1f}
391 |
392 |
393 |
394 |
395 |
396 |
--------------------------------------------------------------------------------
/crostouchpad/cyapa.c:
--------------------------------------------------------------------------------
1 | #define DESCRIPTOR_DEF
2 | #include "driver.h"
3 |
4 | #define bool int
5 |
6 | static ULONG CyapaDebugLevel = 100;
7 | static ULONG CyapaDebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL;
8 |
9 | static bool deviceLoaded = false;
10 |
11 | static int sqr(int num) {
12 | return num * num;
13 | }
14 |
15 | static int diffsig(int x, int y, int lastx, int lasty) {
16 | uint32_t distsq = sqr(x - lastx) + sqr(y - lasty);
17 | if (distsq < 4)
18 | return 0;
19 | return 1;
20 | }
21 |
22 | NTSTATUS
23 | DriverEntry(
24 | __in PDRIVER_OBJECT DriverObject,
25 | __in PUNICODE_STRING RegistryPath
26 | )
27 | {
28 | NTSTATUS status = STATUS_SUCCESS;
29 | WDF_DRIVER_CONFIG config;
30 | WDF_OBJECT_ATTRIBUTES attributes;
31 |
32 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_INIT,
33 | "Driver Entry\n");
34 |
35 | WDF_DRIVER_CONFIG_INIT(&config, CyapaEvtDeviceAdd);
36 |
37 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
38 |
39 | //
40 | // Create a framework driver object to represent our driver.
41 | //
42 |
43 | status = WdfDriverCreate(DriverObject,
44 | RegistryPath,
45 | &attributes,
46 | &config,
47 | WDF_NO_HANDLE
48 | );
49 |
50 | if (!NT_SUCCESS(status))
51 | {
52 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_INIT,
53 | "WdfDriverCreate failed with status 0x%x\n", status);
54 | }
55 |
56 | return status;
57 | }
58 |
59 | NTSTATUS cyapa_set_power_mode(_In_ PCYAPA_CONTEXT pDevice, _In_ uint8_t power_mode)
60 | {
61 | NTSTATUS status;
62 | uint8_t ret = 0;
63 | uint8_t power;
64 |
65 | status = SpbReadDataSynchronously(&pDevice->I2CContext, CMD_POWER_MODE, &ret, 1);
66 | if (!NT_SUCCESS(status)) {
67 | return status;
68 | }
69 | if (ret < 0)
70 | return STATUS_INVALID_DEVICE_STATE;
71 |
72 | power = (ret & ~0xFC);
73 | power |= power_mode & 0xFc;
74 |
75 | status = SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_POWER_MODE, &power, 1);
76 | return status;
77 | }
78 |
79 | VOID
80 | CyapaBootWorkItem(
81 | IN WDFWORKITEM WorkItem
82 | )
83 | {
84 | NTSTATUS status;
85 | WDFDEVICE Device = (WDFDEVICE)WdfWorkItemGetParentObject(WorkItem);
86 | PCYAPA_CONTEXT pDevice = GetDeviceContext(Device);
87 |
88 | struct cyapa_cap cap = { 0 };
89 | status = SpbReadDataSynchronously(&pDevice->I2CContext, CMD_QUERY_CAPABILITIES, &cap, sizeof(cap));
90 | if (!NT_SUCCESS(status)) {
91 | WdfObjectDelete(WorkItem);
92 | return;
93 | }
94 | if (strncmp((const char *)cap.prod_ida, "CYTRA", 5) != 0) {
95 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "[cyapainit] Product ID \"%5.5s\" mismatch\n",
96 | cap.prod_ida);
97 | status = SpbReadDataSynchronously(&pDevice->I2CContext, CMD_QUERY_CAPABILITIES, &cap, sizeof(cap));
98 | if (!NT_SUCCESS(status)) {
99 | WdfObjectDelete(WorkItem);
100 | return;
101 | }
102 | }
103 |
104 | pDevice->max_x = ((cap.max_abs_xy_high << 4) & 0x0F00) |
105 | cap.max_abs_x_low;
106 | pDevice->max_y = ((cap.max_abs_xy_high << 8) & 0x0F00) |
107 | cap.max_abs_y_low;
108 |
109 | pDevice->phy_x = ((cap.phy_siz_xy_high << 4) & 0x0F00) |
110 | cap.phy_siz_x_low;
111 | pDevice->phy_y = ((cap.phy_siz_xy_high << 8) & 0x0F00) |
112 | cap.phy_siz_y_low;
113 |
114 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_PNP, "[cyapainit] %5.5s-%6.6s-%2.2s buttons=%c%c%c res=%dx%d\n",
115 | cap.prod_ida, cap.prod_idb, cap.prod_idc,
116 | ((cap.buttons & CYAPA_FNGR_LEFT) ? 'L' : '-'),
117 | ((cap.buttons & CYAPA_FNGR_MIDDLE) ? 'M' : '-'),
118 | ((cap.buttons & CYAPA_FNGR_RIGHT) ? 'R' : '-'),
119 | pDevice->max_x,
120 | pDevice->max_y);
121 |
122 | uint16_t max_x[] = { pDevice->max_x };
123 | uint16_t max_y[] = { pDevice->max_y };
124 |
125 | uint8_t *max_x8bit = (uint8_t *)max_x;
126 | uint8_t *max_y8bit = (uint8_t *)max_y;
127 |
128 | pDevice->max_x_hid[0] = max_x8bit[0];
129 | pDevice->max_x_hid[1] = max_x8bit[1];
130 |
131 | pDevice->max_y_hid[0] = max_y8bit[0];
132 | pDevice->max_y_hid[1] = max_y8bit[1];
133 |
134 |
135 | uint16_t phy_x[] = { pDevice->phy_x * 10 };
136 | uint16_t phy_y[] = { pDevice->phy_y * 10 };
137 |
138 | uint8_t *phy_x8bit = (uint8_t *)phy_x;
139 | uint8_t *phy_y8bit = (uint8_t *)phy_y;
140 |
141 | pDevice->phy_x_hid[0] = phy_x8bit[0];
142 | pDevice->phy_x_hid[1] = phy_x8bit[1];
143 |
144 | pDevice->phy_y_hid[0] = phy_y8bit[0];
145 | pDevice->phy_y_hid[1] = phy_y8bit[1];
146 |
147 | cyapa_set_power_mode(pDevice, CMD_POWER_MODE_FULL);
148 |
149 | pDevice->ConnectInterrupt = true;
150 | WdfObjectDelete(WorkItem);
151 | }
152 |
153 | void CyapaBootTimer(_In_ WDFTIMER hTimer) {
154 | WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer);
155 |
156 | WDF_OBJECT_ATTRIBUTES attributes;
157 | WDF_WORKITEM_CONFIG workitemConfig;
158 | WDFWORKITEM hWorkItem;
159 |
160 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
161 | WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, CYAPA_CONTEXT);
162 | attributes.ParentObject = Device;
163 | WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CyapaBootWorkItem);
164 |
165 | WdfWorkItemCreate(&workitemConfig,
166 | &attributes,
167 | &hWorkItem);
168 |
169 | WdfWorkItemEnqueue(hWorkItem);
170 | WdfTimerStop(hTimer, FALSE);
171 | }
172 |
173 | NTSTATUS BOOTTRACKPAD(
174 | _In_ PCYAPA_CONTEXT pDevice
175 | )
176 | {
177 | NTSTATUS status;
178 |
179 | static char bl_exit[] = {
180 | 0x00, 0xff, 0xa5, 0x00, 0x01,
181 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
182 |
183 | static char bl_deactivate[] = {
184 | 0x00, 0xff, 0x3b, 0x00, 0x01,
185 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
186 |
187 | struct cyapa_boot_regs boot = { 0 };
188 |
189 | status = SpbReadDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, &boot, sizeof(boot));
190 | if (!NT_SUCCESS(status)) {
191 | return status;
192 | }
193 |
194 | if ((boot.stat & CYAPA_STAT_RUNNING) == 0) {
195 | if (boot.error & CYAPA_ERROR_BOOTLOADER)
196 | status = SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, bl_deactivate, sizeof(bl_deactivate));
197 | else
198 | status = SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, bl_exit, sizeof(bl_exit));
199 |
200 | if (!NT_SUCCESS(status)) {
201 | return status;
202 | }
203 | }
204 |
205 | WDF_TIMER_CONFIG timerConfig;
206 | WDFTIMER hTimer;
207 | WDF_OBJECT_ATTRIBUTES attributes;
208 |
209 | WDF_TIMER_CONFIG_INIT(&timerConfig, CyapaBootTimer);
210 |
211 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
212 | attributes.ParentObject = pDevice->FxDevice;
213 | status = WdfTimerCreate(&timerConfig, &attributes, &hTimer);
214 |
215 | WdfTimerStart(hTimer, WDF_REL_TIMEOUT_IN_MS(75));
216 |
217 | return status;
218 | }
219 |
220 | NTSTATUS
221 | OnPrepareHardware(
222 | _In_ WDFDEVICE FxDevice,
223 | _In_ WDFCMRESLIST FxResourcesRaw,
224 | _In_ WDFCMRESLIST FxResourcesTranslated
225 | )
226 | /*++
227 |
228 | Routine Description:
229 |
230 | This routine caches the SPB resource connection ID.
231 |
232 | Arguments:
233 |
234 | FxDevice - a handle to the framework device object
235 | FxResourcesRaw - list of translated hardware resources that
236 | the PnP manager has assigned to the device
237 | FxResourcesTranslated - list of raw hardware resources that
238 | the PnP manager has assigned to the device
239 |
240 | Return Value:
241 |
242 | Status
243 |
244 | --*/
245 | {
246 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice);
247 | BOOLEAN fSpbResourceFound = FALSE;
248 | NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
249 |
250 | UNREFERENCED_PARAMETER(FxResourcesRaw);
251 |
252 | //
253 | // Parse the peripheral's resources.
254 | //
255 |
256 | ULONG resourceCount = WdfCmResourceListGetCount(FxResourcesTranslated);
257 |
258 | for (ULONG i = 0; i < resourceCount; i++)
259 | {
260 | PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
261 | UCHAR Class;
262 | UCHAR Type;
263 |
264 | pDescriptor = WdfCmResourceListGetDescriptor(
265 | FxResourcesTranslated, i);
266 |
267 | switch (pDescriptor->Type)
268 | {
269 | case CmResourceTypeConnection:
270 | //
271 | // Look for I2C or SPI resource and save connection ID.
272 | //
273 | Class = pDescriptor->u.Connection.Class;
274 | Type = pDescriptor->u.Connection.Type;
275 | if (Class == CM_RESOURCE_CONNECTION_CLASS_SERIAL &&
276 | Type == CM_RESOURCE_CONNECTION_TYPE_SERIAL_I2C)
277 | {
278 | if (fSpbResourceFound == FALSE)
279 | {
280 | status = STATUS_SUCCESS;
281 | pDevice->I2CContext.I2cResHubId.LowPart = pDescriptor->u.Connection.IdLowPart;
282 | pDevice->I2CContext.I2cResHubId.HighPart = pDescriptor->u.Connection.IdHighPart;
283 | fSpbResourceFound = TRUE;
284 | }
285 | else
286 | {
287 | }
288 | }
289 | break;
290 | default:
291 | //
292 | // Ignoring all other resource types.
293 | //
294 | break;
295 | }
296 | }
297 |
298 | //
299 | // An SPB resource is required.
300 | //
301 |
302 | if (fSpbResourceFound == FALSE)
303 | {
304 | status = STATUS_NOT_FOUND;
305 | }
306 |
307 | status = SpbTargetInitialize(FxDevice, &pDevice->I2CContext);
308 | if (!NT_SUCCESS(status))
309 | {
310 | return status;
311 | }
312 |
313 | struct cyapa_boot_regs boot = { 0 };
314 |
315 | status = SpbReadDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, &boot, sizeof(boot));
316 | if (!NT_SUCCESS(status)) {
317 | return status;
318 | }
319 |
320 | return status;
321 | }
322 |
323 | NTSTATUS
324 | OnReleaseHardware(
325 | _In_ WDFDEVICE FxDevice,
326 | _In_ WDFCMRESLIST FxResourcesTranslated
327 | )
328 | /*++
329 |
330 | Routine Description:
331 |
332 | Arguments:
333 |
334 | FxDevice - a handle to the framework device object
335 | FxResourcesTranslated - list of raw hardware resources that
336 | the PnP manager has assigned to the device
337 |
338 | Return Value:
339 |
340 | Status
341 |
342 | --*/
343 | {
344 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice);
345 | NTSTATUS status = STATUS_SUCCESS;
346 |
347 | UNREFERENCED_PARAMETER(FxResourcesTranslated);
348 |
349 | SpbTargetDeinitialize(FxDevice, &pDevice->I2CContext);
350 |
351 | return status;
352 | }
353 |
354 | NTSTATUS
355 | OnD0Entry(
356 | _In_ WDFDEVICE FxDevice,
357 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState
358 | )
359 | /*++
360 |
361 | Routine Description:
362 |
363 | This routine allocates objects needed by the driver.
364 |
365 | Arguments:
366 |
367 | FxDevice - a handle to the framework device object
368 | FxPreviousState - previous power state
369 |
370 | Return Value:
371 |
372 | Status
373 |
374 | --*/
375 | {
376 | UNREFERENCED_PARAMETER(FxPreviousState);
377 |
378 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice);
379 | NTSTATUS status = STATUS_SUCCESS;
380 |
381 | for (int i = 0; i < 15; i++){
382 | pDevice->Flags[i] = 0;
383 | }
384 |
385 | pDevice->RegsSet = false;
386 |
387 | BOOTTRACKPAD(pDevice);
388 |
389 | return status;
390 | }
391 |
392 | NTSTATUS
393 | OnD0Exit(
394 | _In_ WDFDEVICE FxDevice,
395 | _In_ WDF_POWER_DEVICE_STATE FxTargetState
396 | )
397 | /*++
398 |
399 | Routine Description:
400 |
401 | This routine destroys objects needed by the driver.
402 |
403 | Arguments:
404 |
405 | FxDevice - a handle to the framework device object
406 | FxTargetState - the target power state
407 |
408 | Return Value:
409 |
410 | Status
411 |
412 | --*/
413 | {
414 | UNREFERENCED_PARAMETER(FxTargetState);
415 |
416 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice);
417 |
418 | pDevice->ConnectInterrupt = false;
419 |
420 | return STATUS_SUCCESS;
421 | }
422 |
423 | BOOLEAN OnInterruptIsr(
424 | WDFINTERRUPT Interrupt,
425 | ULONG MessageID){
426 | UNREFERENCED_PARAMETER(MessageID);
427 |
428 | WDFDEVICE Device = WdfInterruptGetDevice(Interrupt);
429 | PCYAPA_CONTEXT pDevice = GetDeviceContext(Device);
430 |
431 | if (!pDevice->ConnectInterrupt)
432 | return false;
433 |
434 | LARGE_INTEGER CurrentTime;
435 |
436 | KeQuerySystemTime(&CurrentTime);
437 |
438 | LARGE_INTEGER DIFF;
439 |
440 | DIFF.QuadPart = 0;
441 |
442 | if (pDevice->LastTime.QuadPart != 0)
443 | DIFF.QuadPart = (CurrentTime.QuadPart - pDevice->LastTime.QuadPart) / 1000;
444 |
445 | struct cyapa_regs rawregs = { 0 };
446 | if (!NT_SUCCESS(SpbReadDataSynchronously(&pDevice->I2CContext, 0, &rawregs, sizeof(rawregs)))) {
447 | return false;
448 | }
449 | struct cyapa_regs *regs = &rawregs;
450 |
451 | struct _CYAPA_MULTITOUCH_REPORT report;
452 | report.ReportID = REPORTID_MTOUCH;
453 |
454 | int nfingers;
455 |
456 | nfingers = CYAPA_FNGR_NUMFINGERS(regs->fngr);
457 |
458 | int x[15];
459 | int y[15];
460 | int p[15];
461 | for (int i = 0; i < 15; i++) {
462 | x[i] = -1;
463 | y[i] = -1;
464 | p[i] = -1;
465 | }
466 | for (int i = 0; i < nfingers; i++) {
467 | int a = regs->touch[i].id;
468 | int rawx = CYAPA_TOUCH_X(regs, i);
469 | int rawy = CYAPA_TOUCH_Y(regs, i);
470 | int rawp = CYAPA_TOUCH_P(regs, i);
471 | x[a] = rawx;
472 | y[a] = rawy;
473 | p[a] = rawp;
474 | }
475 | for (int i = 0; i < 15; i++) {
476 | if (pDevice->Flags[i] == MXT_T9_DETECT && x[i] == -1) {
477 | pDevice->Flags[i] = MXT_T9_RELEASE;
478 | }
479 | if (x[i] != -1) {
480 | bool updateValues = false;
481 |
482 | if (pDevice->Flags[i] == 0 || pDevice->Flags[i] == MXT_T9_RELEASE)
483 | updateValues = true;
484 |
485 | pDevice->Flags[i] = MXT_T9_DETECT;
486 |
487 | if (diffsig(x[i], y[i], pDevice->XValue[i], pDevice->YValue[i]) == 1)
488 | updateValues = true;
489 |
490 | if (updateValues) {
491 | pDevice->XValue[i] = (USHORT)x[i];
492 | pDevice->YValue[i] = (USHORT)y[i];
493 | pDevice->PValue[i] = (USHORT)p[i];
494 | }
495 | }
496 | }
497 |
498 | pDevice->BUTTONPRESSED = ((regs->fngr & CYAPA_FNGR_LEFT) != 0);
499 |
500 | pDevice->TIMEINT += (USHORT)DIFF.QuadPart;
501 |
502 | pDevice->LastTime = CurrentTime;
503 |
504 | BYTE count = 0, i = 0;
505 | while (count < 5 && i < 15) {
506 | if (pDevice->Flags[i] != 0) {
507 | report.Touch[count].ContactID = i;
508 |
509 | report.Touch[count].XValue = pDevice->XValue[i];
510 | report.Touch[count].YValue = pDevice->YValue[i];
511 | report.Touch[count].Pressure = pDevice->PValue[i];
512 |
513 | uint8_t flags = pDevice->Flags[i];
514 | if (flags & MXT_T9_DETECT) {
515 | report.Touch[count].Status = MULTI_CONFIDENCE_BIT | MULTI_TIPSWITCH_BIT;
516 | }
517 | else if (flags & MXT_T9_PRESS) {
518 | report.Touch[count].Status = MULTI_CONFIDENCE_BIT | MULTI_TIPSWITCH_BIT;
519 | }
520 | else if (flags & MXT_T9_RELEASE) {
521 | report.Touch[count].Status = MULTI_CONFIDENCE_BIT;
522 | pDevice->Flags[i] = 0;
523 | }
524 | else
525 | report.Touch[count].Status = 0;
526 |
527 | count++;
528 | }
529 | i++;
530 | }
531 |
532 | report.ScanTime = pDevice->TIMEINT;
533 | report.IsDepressed = pDevice->BUTTONPRESSED;
534 |
535 | report.ContactCount = count;
536 |
537 | size_t bytesWritten;
538 | CyapaProcessVendorReport(pDevice, &report, sizeof(report), &bytesWritten);
539 |
540 | pDevice->RegsSet = true;
541 | return true;
542 | }
543 |
544 | NTSTATUS
545 | CyapaEvtDeviceAdd(
546 | IN WDFDRIVER Driver,
547 | IN PWDFDEVICE_INIT DeviceInit
548 | )
549 | {
550 | NTSTATUS status = STATUS_SUCCESS;
551 | WDF_IO_QUEUE_CONFIG queueConfig;
552 | WDF_OBJECT_ATTRIBUTES attributes;
553 | WDFDEVICE device;
554 | WDF_INTERRUPT_CONFIG interruptConfig;
555 | WDFQUEUE queue;
556 | PCYAPA_CONTEXT devContext;
557 |
558 | UNREFERENCED_PARAMETER(Driver);
559 |
560 | PAGED_CODE();
561 |
562 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_PNP,
563 | "CyapaEvtDeviceAdd called\n");
564 |
565 | //
566 | // Tell framework this is a filter driver. Filter drivers by default are
567 | // not power policy owners. This works well for this driver because
568 | // HIDclass driver is the power policy owner for HID minidrivers.
569 | //
570 |
571 | WdfFdoInitSetFilter(DeviceInit);
572 |
573 | {
574 | WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks;
575 | WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks);
576 |
577 | pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware;
578 | pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware;
579 | pnpCallbacks.EvtDeviceD0Entry = OnD0Entry;
580 | pnpCallbacks.EvtDeviceD0Exit = OnD0Exit;
581 |
582 | WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks);
583 | }
584 |
585 | //
586 | // Setup the device context
587 | //
588 |
589 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CYAPA_CONTEXT);
590 |
591 | //
592 | // Create a framework device object.This call will in turn create
593 | // a WDM device object, attach to the lower stack, and set the
594 | // appropriate flags and attributes.
595 | //
596 |
597 | status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
598 |
599 | if (!NT_SUCCESS(status))
600 | {
601 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP,
602 | "WdfDeviceCreate failed with status code 0x%x\n", status);
603 |
604 | return status;
605 | }
606 |
607 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel);
608 |
609 | queueConfig.EvtIoInternalDeviceControl = CyapaEvtInternalDeviceControl;
610 |
611 | status = WdfIoQueueCreate(device,
612 | &queueConfig,
613 | WDF_NO_OBJECT_ATTRIBUTES,
614 | &queue
615 | );
616 |
617 | if (!NT_SUCCESS(status))
618 | {
619 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP,
620 | "WdfIoQueueCreate failed 0x%x\n", status);
621 |
622 | return status;
623 | }
624 |
625 | //
626 | // Create manual I/O queue to take care of hid report read requests
627 | //
628 |
629 | devContext = GetDeviceContext(device);
630 |
631 | devContext->FxDevice = device;
632 | devContext->ConnectInterrupt = false;
633 |
634 | WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);
635 |
636 | queueConfig.PowerManaged = WdfFalse;
637 |
638 | status = WdfIoQueueCreate(device,
639 | &queueConfig,
640 | WDF_NO_OBJECT_ATTRIBUTES,
641 | &devContext->ReportQueue
642 | );
643 |
644 | if (!NT_SUCCESS(status))
645 | {
646 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP,
647 | "WdfIoQueueCreate failed 0x%x\n", status);
648 |
649 | return status;
650 | }
651 |
652 | //
653 | // Create an interrupt object for hardware notifications
654 | //
655 | WDF_INTERRUPT_CONFIG_INIT(
656 | &interruptConfig,
657 | OnInterruptIsr,
658 | NULL);
659 | interruptConfig.PassiveHandling = TRUE;
660 |
661 | status = WdfInterruptCreate(
662 | device,
663 | &interruptConfig,
664 | WDF_NO_OBJECT_ATTRIBUTES,
665 | &devContext->Interrupt);
666 |
667 | if (!NT_SUCCESS(status))
668 | {
669 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP,
670 | "Error creating WDF interrupt object - %!STATUS!",
671 | status);
672 |
673 | return status;
674 | }
675 |
676 | //
677 | // Initialize DeviceMode
678 | //
679 |
680 | devContext->DeviceMode = DEVICE_MODE_MOUSE;
681 |
682 | return status;
683 | }
684 |
685 | VOID
686 | CyapaEvtInternalDeviceControl(
687 | IN WDFQUEUE Queue,
688 | IN WDFREQUEST Request,
689 | IN size_t OutputBufferLength,
690 | IN size_t InputBufferLength,
691 | IN ULONG IoControlCode
692 | )
693 | {
694 | NTSTATUS status = STATUS_SUCCESS;
695 | WDFDEVICE device;
696 | PCYAPA_CONTEXT devContext;
697 | BOOLEAN completeRequest = TRUE;
698 |
699 | UNREFERENCED_PARAMETER(OutputBufferLength);
700 | UNREFERENCED_PARAMETER(InputBufferLength);
701 |
702 | device = WdfIoQueueGetDevice(Queue);
703 | devContext = GetDeviceContext(device);
704 |
705 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
706 | "%s, Queue:0x%p, Request:0x%p\n",
707 | DbgHidInternalIoctlString(IoControlCode),
708 | Queue,
709 | Request
710 | );
711 |
712 | //
713 | // Please note that HIDCLASS provides the buffer in the Irp->UserBuffer
714 | // field irrespective of the ioctl buffer type. However, framework is very
715 | // strict about type checking. You cannot get Irp->UserBuffer by using
716 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER
717 | // internal ioctl. So depending on the ioctl code, we will either
718 | // use retreive function or escape to WDM to get the UserBuffer.
719 | //
720 |
721 | switch (IoControlCode)
722 | {
723 |
724 | case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
725 | //
726 | // Retrieves the device's HID descriptor.
727 | //
728 | status = CyapaGetHidDescriptor(device, Request);
729 | break;
730 |
731 | case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
732 | //
733 | //Retrieves a device's attributes in a HID_DEVICE_ATTRIBUTES structure.
734 | //
735 | status = CyapaGetDeviceAttributes(Request);
736 | break;
737 |
738 | case IOCTL_HID_GET_REPORT_DESCRIPTOR:
739 | //
740 | //Obtains the report descriptor for the HID device.
741 | //
742 | status = CyapaGetReportDescriptor(device, Request, FALSE, &completeRequest);
743 | break;
744 |
745 | case IOCTL_HID_GET_STRING:
746 | //
747 | // Requests that the HID minidriver retrieve a human-readable string
748 | // for either the manufacturer ID, the product ID, or the serial number
749 | // from the string descriptor of the device. The minidriver must send
750 | // a Get String Descriptor request to the device, in order to retrieve
751 | // the string descriptor, then it must extract the string at the
752 | // appropriate index from the string descriptor and return it in the
753 | // output buffer indicated by the IRP. Before sending the Get String
754 | // Descriptor request, the minidriver must retrieve the appropriate
755 | // index for the manufacturer ID, the product ID or the serial number
756 | // from the device extension of a top level collection associated with
757 | // the device.
758 | //
759 | status = CyapaGetString(Request);
760 | break;
761 |
762 | case IOCTL_HID_WRITE_REPORT:
763 | case IOCTL_HID_SET_OUTPUT_REPORT:
764 | //
765 | //Transmits a class driver-supplied report to the device.
766 | //
767 | status = CyapaWriteReport(devContext, Request);
768 | break;
769 |
770 | case IOCTL_HID_READ_REPORT:
771 | case IOCTL_HID_GET_INPUT_REPORT:
772 | //
773 | // Returns a report from the device into a class driver-supplied buffer.
774 | //
775 | status = CyapaReadReport(devContext, Request, &completeRequest);
776 | break;
777 |
778 | case IOCTL_HID_SET_FEATURE:
779 | //
780 | // This sends a HID class feature report to a top-level collection of
781 | // a HID class device.
782 | //
783 | status = CyapaSetFeature(devContext, Request, &completeRequest);
784 | break;
785 |
786 | case IOCTL_HID_GET_FEATURE:
787 | //
788 | // returns a feature report associated with a top-level collection
789 | //
790 | status = CyapaGetFeature(devContext, Request, &completeRequest);
791 | break;
792 |
793 | case IOCTL_HID_ACTIVATE_DEVICE:
794 | //
795 | // Makes the device ready for I/O operations.
796 | //
797 | case IOCTL_HID_DEACTIVATE_DEVICE:
798 | //
799 | // Causes the device to cease operations and terminate all outstanding
800 | // I/O requests.
801 | //
802 | default:
803 | status = STATUS_NOT_SUPPORTED;
804 | break;
805 | }
806 |
807 | if (completeRequest)
808 | {
809 | WdfRequestComplete(Request, status);
810 |
811 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
812 | "%s completed, Queue:0x%p, Request:0x%p\n",
813 | DbgHidInternalIoctlString(IoControlCode),
814 | Queue,
815 | Request
816 | );
817 | }
818 | else
819 | {
820 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
821 | "%s deferred, Queue:0x%p, Request:0x%p\n",
822 | DbgHidInternalIoctlString(IoControlCode),
823 | Queue,
824 | Request
825 | );
826 | }
827 |
828 | return;
829 | }
830 |
831 | NTSTATUS
832 | CyapaGetHidDescriptor(
833 | IN WDFDEVICE Device,
834 | IN WDFREQUEST Request
835 | )
836 | {
837 | NTSTATUS status = STATUS_SUCCESS;
838 | size_t bytesToCopy = 0;
839 | WDFMEMORY memory;
840 |
841 | UNREFERENCED_PARAMETER(Device);
842 |
843 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
844 | "CyapaGetHidDescriptor Entry\n");
845 |
846 | //
847 | // This IOCTL is METHOD_NEITHER so WdfRequestRetrieveOutputMemory
848 | // will correctly retrieve buffer from Irp->UserBuffer.
849 | // Remember that HIDCLASS provides the buffer in the Irp->UserBuffer
850 | // field irrespective of the ioctl buffer type. However, framework is very
851 | // strict about type checking. You cannot get Irp->UserBuffer by using
852 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER
853 | // internal ioctl.
854 | //
855 | status = WdfRequestRetrieveOutputMemory(Request, &memory);
856 |
857 | if (!NT_SUCCESS(status))
858 | {
859 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
860 | "WdfRequestRetrieveOutputMemory failed 0x%x\n", status);
861 |
862 | return status;
863 | }
864 |
865 | //
866 | // Use hardcoded "HID Descriptor"
867 | //
868 | bytesToCopy = DefaultHidDescriptor.bLength;
869 |
870 | if (bytesToCopy == 0)
871 | {
872 | status = STATUS_INVALID_DEVICE_STATE;
873 |
874 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
875 | "DefaultHidDescriptor is zero, 0x%x\n", status);
876 |
877 | return status;
878 | }
879 |
880 | status = WdfMemoryCopyFromBuffer(memory,
881 | 0, // Offset
882 | (PVOID)&DefaultHidDescriptor,
883 | bytesToCopy);
884 |
885 | if (!NT_SUCCESS(status))
886 | {
887 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
888 | "WdfMemoryCopyFromBuffer failed 0x%x\n", status);
889 |
890 | return status;
891 | }
892 |
893 | //
894 | // Report how many bytes were copied
895 | //
896 | WdfRequestSetInformation(Request, bytesToCopy);
897 |
898 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
899 | "CyapaGetHidDescriptor Exit = 0x%x\n", status);
900 |
901 | return status;
902 | }
903 |
904 | void CyapaDescriptorTimer(_In_ WDFTIMER hTimer) {
905 | WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer);
906 | PCYAPA_CONTEXT pDevice = GetDeviceContext(Device);
907 |
908 | WdfRequestForwardToIoQueue(pDevice->lastRequest, pDevice->ReportQueue);
909 |
910 | pDevice->lastRequest = NULL;
911 |
912 | WdfTimerStop(hTimer, FALSE);
913 | }
914 |
915 | NTSTATUS
916 | CyapaGetReportDescriptor(
917 | IN WDFDEVICE Device,
918 | IN WDFREQUEST Request,
919 | IN BOOLEAN Retried,
920 | OUT BOOLEAN* CompleteRequest
921 | )
922 | {
923 | NTSTATUS status = STATUS_SUCCESS;
924 | ULONG_PTR bytesToCopy;
925 | WDFMEMORY memory;
926 |
927 | PCYAPA_CONTEXT devContext = GetDeviceContext(Device);
928 |
929 | if (devContext->max_x == 0) {
930 | devContext->lastRequest = Request;
931 | WDF_TIMER_CONFIG timerConfig;
932 | WDFTIMER hTimer;
933 | WDF_OBJECT_ATTRIBUTES attributes;
934 |
935 | WDF_TIMER_CONFIG_INIT(&timerConfig, CyapaDescriptorTimer);
936 |
937 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
938 | attributes.ParentObject = Device;
939 | status = WdfTimerCreate(&timerConfig, &attributes, &hTimer);
940 |
941 | WdfTimerStart(hTimer, WDF_REL_TIMEOUT_IN_MS(75));
942 | *CompleteRequest = FALSE;
943 | }
944 |
945 | UNREFERENCED_PARAMETER(Device);
946 |
947 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
948 | "CyapaGetReportDescriptor Entry\n");
949 |
950 | #define MT_TOUCH_COLLECTION \
951 | MT_TOUCH_COLLECTION0 \
952 | 0x26, devContext->max_x_hid[0], devContext->max_x_hid[1], /* LOGICAL_MAXIMUM (WIDTH) */ \
953 | 0x46, devContext->phy_x_hid[0], devContext->phy_x_hid[1], /* PHYSICAL_MAXIMUM (WIDTH) */ \
954 | MT_TOUCH_COLLECTION1 \
955 | 0x26, devContext->max_y_hid[0], devContext->max_y_hid[1], /* LOGICAL_MAXIMUM (HEIGHT) */ \
956 | 0x46, devContext->phy_y_hid[0], devContext->phy_y_hid[1], /* PHYSICAL_MAXIMUM (HEIGHT) */ \
957 | MT_TOUCH_COLLECTION2
958 |
959 | HID_REPORT_DESCRIPTOR ReportDescriptor[] = {
960 | //
961 | // Multitouch report starts here
962 | //
963 | //TOUCH PAD input TLC
964 | 0x05, 0x0d, // USAGE_PAGE (Digitizers)
965 | 0x09, 0x05, // USAGE (Touch Pad)
966 | 0xa1, 0x01, // COLLECTION (Application)
967 | 0x85, REPORTID_MTOUCH, // REPORT_ID (Touch pad)
968 | 0x09, 0x22, // USAGE (Finger)
969 | MT_TOUCH_COLLECTION
970 | MT_TOUCH_COLLECTION
971 | MT_TOUCH_COLLECTION
972 | MT_TOUCH_COLLECTION
973 | MT_TOUCH_COLLECTION
974 | USAGE_PAGES
975 | };
976 |
977 | //
978 | // This IOCTL is METHOD_NEITHER so WdfRequestRetrieveOutputMemory
979 | // will correctly retrieve buffer from Irp->UserBuffer.
980 | // Remember that HIDCLASS provides the buffer in the Irp->UserBuffer
981 | // field irrespective of the ioctl buffer type. However, framework is very
982 | // strict about type checking. You cannot get Irp->UserBuffer by using
983 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER
984 | // internal ioctl.
985 | //
986 | status = WdfRequestRetrieveOutputMemory(Request, &memory);
987 | if (!NT_SUCCESS(status))
988 | {
989 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
990 | "WdfRequestRetrieveOutputMemory failed 0x%x\n", status);
991 |
992 | return status;
993 | }
994 |
995 | //
996 | // Use hardcoded Report descriptor
997 | //
998 | bytesToCopy = DefaultHidDescriptor.DescriptorList[0].wReportLength;
999 |
1000 | if (bytesToCopy == 0)
1001 | {
1002 | status = STATUS_INVALID_DEVICE_STATE;
1003 |
1004 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1005 | "DefaultHidDescriptor's reportLength is zero, 0x%x\n", status);
1006 |
1007 | return status;
1008 | }
1009 |
1010 | status = WdfMemoryCopyFromBuffer(memory,
1011 | 0,
1012 | (PVOID)ReportDescriptor,
1013 | bytesToCopy);
1014 | if (!NT_SUCCESS(status))
1015 | {
1016 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1017 | "WdfMemoryCopyFromBuffer failed 0x%x\n", status);
1018 |
1019 | return status;
1020 | }
1021 |
1022 | //
1023 | // Report how many bytes were copied
1024 | //
1025 | WdfRequestSetInformation(Request, bytesToCopy);
1026 |
1027 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1028 | "CyapaGetReportDescriptor Exit = 0x%x\n", status);
1029 |
1030 | if (Retried) {
1031 | WdfRequestComplete(Request, status);
1032 | }
1033 |
1034 | return status;
1035 | }
1036 |
1037 |
1038 | NTSTATUS
1039 | CyapaGetDeviceAttributes(
1040 | IN WDFREQUEST Request
1041 | )
1042 | {
1043 | NTSTATUS status = STATUS_SUCCESS;
1044 | PHID_DEVICE_ATTRIBUTES deviceAttributes = NULL;
1045 |
1046 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1047 | "CyapaGetDeviceAttributes Entry\n");
1048 |
1049 | //
1050 | // This IOCTL is METHOD_NEITHER so WdfRequestRetrieveOutputMemory
1051 | // will correctly retrieve buffer from Irp->UserBuffer.
1052 | // Remember that HIDCLASS provides the buffer in the Irp->UserBuffer
1053 | // field irrespective of the ioctl buffer type. However, framework is very
1054 | // strict about type checking. You cannot get Irp->UserBuffer by using
1055 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER
1056 | // internal ioctl.
1057 | //
1058 | status = WdfRequestRetrieveOutputBuffer(Request,
1059 | sizeof(HID_DEVICE_ATTRIBUTES),
1060 | &deviceAttributes,
1061 | NULL);
1062 | if (!NT_SUCCESS(status))
1063 | {
1064 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1065 | "WdfRequestRetrieveOutputBuffer failed 0x%x\n", status);
1066 |
1067 | return status;
1068 | }
1069 |
1070 | //
1071 | // Set USB device descriptor
1072 | //
1073 |
1074 | deviceAttributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);
1075 | deviceAttributes->VendorID = CYAPA_VID;
1076 | deviceAttributes->ProductID = CYAPA_PID;
1077 | deviceAttributes->VersionNumber = CYAPA_VERSION;
1078 |
1079 | //
1080 | // Report how many bytes were copied
1081 | //
1082 | WdfRequestSetInformation(Request, sizeof(HID_DEVICE_ATTRIBUTES));
1083 |
1084 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1085 | "CyapaGetDeviceAttributes Exit = 0x%x\n", status);
1086 |
1087 | return status;
1088 | }
1089 |
1090 | NTSTATUS
1091 | CyapaGetString(
1092 | IN WDFREQUEST Request
1093 | )
1094 | {
1095 |
1096 | NTSTATUS status = STATUS_SUCCESS;
1097 | PWSTR pwstrID;
1098 | size_t lenID;
1099 | WDF_REQUEST_PARAMETERS params;
1100 | void *pStringBuffer = NULL;
1101 |
1102 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1103 | "CyapaGetString Entry\n");
1104 |
1105 | WDF_REQUEST_PARAMETERS_INIT(¶ms);
1106 | WdfRequestGetParameters(Request, ¶ms);
1107 |
1108 | switch ((ULONG_PTR)params.Parameters.DeviceIoControl.Type3InputBuffer & 0xFFFF)
1109 | {
1110 | case HID_STRING_ID_IMANUFACTURER:
1111 | pwstrID = L"Cyapa.\0";
1112 | break;
1113 |
1114 | case HID_STRING_ID_IPRODUCT:
1115 | pwstrID = L"MaxTouch Touch Screen\0";
1116 | break;
1117 |
1118 | case HID_STRING_ID_ISERIALNUMBER:
1119 | pwstrID = L"123123123\0";
1120 | break;
1121 |
1122 | default:
1123 | pwstrID = NULL;
1124 | break;
1125 | }
1126 |
1127 | lenID = pwstrID ? wcslen(pwstrID)*sizeof(WCHAR) + sizeof(UNICODE_NULL) : 0;
1128 |
1129 | if (pwstrID == NULL)
1130 | {
1131 |
1132 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1133 | "CyapaGetString Invalid request type\n");
1134 |
1135 | status = STATUS_INVALID_PARAMETER;
1136 |
1137 | return status;
1138 | }
1139 |
1140 | status = WdfRequestRetrieveOutputBuffer(Request,
1141 | lenID,
1142 | &pStringBuffer,
1143 | &lenID);
1144 |
1145 | if (!NT_SUCCESS(status))
1146 | {
1147 |
1148 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1149 | "CyapaGetString WdfRequestRetrieveOutputBuffer failed Status 0x%x\n", status);
1150 |
1151 | return status;
1152 | }
1153 |
1154 | RtlCopyMemory(pStringBuffer, pwstrID, lenID);
1155 |
1156 | WdfRequestSetInformation(Request, lenID);
1157 |
1158 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1159 | "CyapaGetString Exit = 0x%x\n", status);
1160 |
1161 | return status;
1162 | }
1163 |
1164 | NTSTATUS
1165 | CyapaWriteReport(
1166 | IN PCYAPA_CONTEXT DevContext,
1167 | IN WDFREQUEST Request
1168 | )
1169 | {
1170 | UNREFERENCED_PARAMETER(DevContext);
1171 |
1172 | NTSTATUS status = STATUS_SUCCESS;
1173 | WDF_REQUEST_PARAMETERS params;
1174 | PHID_XFER_PACKET transferPacket = NULL;
1175 |
1176 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1177 | "CyapaWriteReport Entry\n");
1178 |
1179 | WDF_REQUEST_PARAMETERS_INIT(¶ms);
1180 | WdfRequestGetParameters(Request, ¶ms);
1181 |
1182 | if (params.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET))
1183 | {
1184 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1185 | "CyapaWriteReport Xfer packet too small\n");
1186 |
1187 | status = STATUS_BUFFER_TOO_SMALL;
1188 | }
1189 | else
1190 | {
1191 |
1192 | transferPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer;
1193 |
1194 | if (transferPacket == NULL)
1195 | {
1196 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1197 | "CyapaWriteReport No xfer packet\n");
1198 |
1199 | status = STATUS_INVALID_DEVICE_REQUEST;
1200 | }
1201 | else
1202 | {
1203 | //
1204 | // switch on the report id
1205 | //
1206 |
1207 | switch (transferPacket->reportId)
1208 | {
1209 | default:
1210 |
1211 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1212 | "CyapaWriteReport Unhandled report type %d\n", transferPacket->reportId);
1213 |
1214 | status = STATUS_INVALID_PARAMETER;
1215 |
1216 | break;
1217 | }
1218 | }
1219 | }
1220 |
1221 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1222 | "CyapaWriteReport Exit = 0x%x\n", status);
1223 |
1224 | return status;
1225 |
1226 | }
1227 |
1228 | NTSTATUS
1229 | CyapaProcessVendorReport(
1230 | IN PCYAPA_CONTEXT DevContext,
1231 | IN PVOID ReportBuffer,
1232 | IN ULONG ReportBufferLen,
1233 | OUT size_t* BytesWritten
1234 | )
1235 | {
1236 | NTSTATUS status = STATUS_SUCCESS;
1237 | WDFREQUEST reqRead;
1238 | PVOID pReadReport = NULL;
1239 | size_t bytesReturned = 0;
1240 |
1241 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1242 | "CyapaProcessVendorReport Entry\n");
1243 |
1244 | status = WdfIoQueueRetrieveNextRequest(DevContext->ReportQueue,
1245 | &reqRead);
1246 |
1247 | if (NT_SUCCESS(status))
1248 | {
1249 | status = WdfRequestRetrieveOutputBuffer(reqRead,
1250 | ReportBufferLen,
1251 | &pReadReport,
1252 | &bytesReturned);
1253 |
1254 | if (NT_SUCCESS(status))
1255 | {
1256 | //
1257 | // Copy ReportBuffer into read request
1258 | //
1259 |
1260 | if (bytesReturned > ReportBufferLen)
1261 | {
1262 | bytesReturned = ReportBufferLen;
1263 | }
1264 |
1265 | RtlCopyMemory(pReadReport,
1266 | ReportBuffer,
1267 | bytesReturned);
1268 |
1269 | //
1270 | // Complete read with the number of bytes returned as info
1271 | //
1272 |
1273 | WdfRequestCompleteWithInformation(reqRead,
1274 | status,
1275 | bytesReturned);
1276 |
1277 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
1278 | "CyapaProcessVendorReport %d bytes returned\n", bytesReturned);
1279 |
1280 | //
1281 | // Return the number of bytes written for the write request completion
1282 | //
1283 |
1284 | *BytesWritten = bytesReturned;
1285 |
1286 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
1287 | "%s completed, Queue:0x%p, Request:0x%p\n",
1288 | DbgHidInternalIoctlString(IOCTL_HID_READ_REPORT),
1289 | DevContext->ReportQueue,
1290 | reqRead);
1291 | }
1292 | else
1293 | {
1294 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1295 | "WdfRequestRetrieveOutputBuffer failed Status 0x%x\n", status);
1296 | }
1297 | }
1298 | else
1299 | {
1300 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1301 | "WdfIoQueueRetrieveNextRequest failed Status 0x%x\n", status);
1302 | }
1303 |
1304 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1305 | "CyapaProcessVendorReport Exit = 0x%x\n", status);
1306 |
1307 | return status;
1308 | }
1309 |
1310 | NTSTATUS
1311 | CyapaReadReport(
1312 | IN PCYAPA_CONTEXT DevContext,
1313 | IN WDFREQUEST Request,
1314 | OUT BOOLEAN* CompleteRequest
1315 | )
1316 | {
1317 | NTSTATUS status = STATUS_SUCCESS;
1318 |
1319 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1320 | "CyapaReadReport Entry\n");
1321 |
1322 | //
1323 | // Forward this read request to our manual queue
1324 | // (in other words, we are going to defer this request
1325 | // until we have a corresponding write request to
1326 | // match it with)
1327 | //
1328 |
1329 | status = WdfRequestForwardToIoQueue(Request, DevContext->ReportQueue);
1330 |
1331 | if (!NT_SUCCESS(status))
1332 | {
1333 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1334 | "WdfRequestForwardToIoQueue failed Status 0x%x\n", status);
1335 | }
1336 | else
1337 | {
1338 | *CompleteRequest = FALSE;
1339 | }
1340 |
1341 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1342 | "CyapaReadReport Exit = 0x%x\n", status);
1343 |
1344 | return status;
1345 | }
1346 |
1347 | NTSTATUS
1348 | CyapaSetFeature(
1349 | IN PCYAPA_CONTEXT DevContext,
1350 | IN WDFREQUEST Request,
1351 | OUT BOOLEAN* CompleteRequest
1352 | )
1353 | {
1354 | UNREFERENCED_PARAMETER(CompleteRequest);
1355 |
1356 | NTSTATUS status = STATUS_SUCCESS;
1357 | WDF_REQUEST_PARAMETERS params;
1358 | PHID_XFER_PACKET transferPacket = NULL;
1359 | CyapaFeatureReport* pReport = NULL;
1360 |
1361 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1362 | "CyapaSetFeature Entry\n");
1363 |
1364 | WDF_REQUEST_PARAMETERS_INIT(¶ms);
1365 | WdfRequestGetParameters(Request, ¶ms);
1366 |
1367 | if (params.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET))
1368 | {
1369 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1370 | "CyapaSetFeature Xfer packet too small\n");
1371 |
1372 | status = STATUS_BUFFER_TOO_SMALL;
1373 | }
1374 | else
1375 | {
1376 |
1377 | transferPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer;
1378 |
1379 | if (transferPacket == NULL)
1380 | {
1381 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1382 | "CyapaWriteReport No xfer packet\n");
1383 |
1384 | status = STATUS_INVALID_DEVICE_REQUEST;
1385 | }
1386 | else
1387 | {
1388 | //
1389 | // switch on the report id
1390 | //
1391 |
1392 | switch (transferPacket->reportId)
1393 | {
1394 | case REPORTID_FEATURE:
1395 |
1396 | if (transferPacket->reportBufferLen == sizeof(CyapaFeatureReport))
1397 | {
1398 | pReport = (CyapaFeatureReport*)transferPacket->reportBuffer;
1399 |
1400 | DevContext->DeviceMode = pReport->DeviceMode;
1401 |
1402 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
1403 | "CyapaSetFeature DeviceMode = 0x%x\n", DevContext->DeviceMode);
1404 | }
1405 | else
1406 | {
1407 | status = STATUS_INVALID_PARAMETER;
1408 |
1409 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1410 | "CyapaSetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(CyapaFeatureReport) (%d)\n",
1411 | transferPacket->reportBufferLen,
1412 | sizeof(CyapaFeatureReport));
1413 | }
1414 |
1415 | break;
1416 |
1417 | default:
1418 |
1419 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1420 | "CyapaSetFeature Unhandled report type %d\n", transferPacket->reportId);
1421 |
1422 | status = STATUS_INVALID_PARAMETER;
1423 |
1424 | break;
1425 | }
1426 | }
1427 | }
1428 |
1429 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1430 | "CyapaSetFeature Exit = 0x%x\n", status);
1431 |
1432 | return status;
1433 | }
1434 |
1435 | NTSTATUS
1436 | CyapaGetFeature(
1437 | IN PCYAPA_CONTEXT DevContext,
1438 | IN WDFREQUEST Request,
1439 | OUT BOOLEAN* CompleteRequest
1440 | )
1441 | {
1442 | UNREFERENCED_PARAMETER(CompleteRequest);
1443 |
1444 | NTSTATUS status = STATUS_SUCCESS;
1445 | WDF_REQUEST_PARAMETERS params;
1446 | PHID_XFER_PACKET transferPacket = NULL;
1447 |
1448 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1449 | "CyapaGetFeature Entry\n");
1450 |
1451 | WDF_REQUEST_PARAMETERS_INIT(¶ms);
1452 | WdfRequestGetParameters(Request, ¶ms);
1453 |
1454 | if (params.Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_XFER_PACKET))
1455 | {
1456 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1457 | "CyapaGetFeature Xfer packet too small\n");
1458 |
1459 | status = STATUS_BUFFER_TOO_SMALL;
1460 | }
1461 | else
1462 | {
1463 |
1464 | transferPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer;
1465 |
1466 | if (transferPacket == NULL)
1467 | {
1468 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1469 | "CyapaGetFeature No xfer packet\n");
1470 |
1471 | status = STATUS_INVALID_DEVICE_REQUEST;
1472 | }
1473 | else
1474 | {
1475 | //
1476 | // switch on the report id
1477 | //
1478 |
1479 | switch (transferPacket->reportId)
1480 | {
1481 | case REPORTID_MTOUCH:
1482 | {
1483 |
1484 | CyapaMaxCountReport* pReport = NULL;
1485 |
1486 | if (transferPacket->reportBufferLen >= sizeof(CyapaMaxCountReport))
1487 | {
1488 | pReport = (CyapaMaxCountReport*)transferPacket->reportBuffer;
1489 |
1490 | pReport->MaximumCount = MULTI_MAX_COUNT;
1491 |
1492 | pReport->PadType = 0;
1493 |
1494 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
1495 | "CyapaGetFeature MaximumCount = 0x%x\n", MULTI_MAX_COUNT);
1496 | }
1497 | else
1498 | {
1499 | status = STATUS_INVALID_PARAMETER;
1500 |
1501 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1502 | "CyapaGetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(CyapaMaxCountReport) (%d)\n",
1503 | transferPacket->reportBufferLen,
1504 | sizeof(CyapaMaxCountReport));
1505 | }
1506 |
1507 | break;
1508 | }
1509 |
1510 | case REPORTID_FEATURE:
1511 | {
1512 |
1513 | CyapaFeatureReport* pReport = NULL;
1514 |
1515 | if (transferPacket->reportBufferLen >= sizeof(CyapaFeatureReport))
1516 | {
1517 | pReport = (CyapaFeatureReport*)transferPacket->reportBuffer;
1518 |
1519 | pReport->DeviceMode = DevContext->DeviceMode;
1520 |
1521 | pReport->DeviceIdentifier = 0;
1522 |
1523 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
1524 | "CyapaGetFeature DeviceMode = 0x%x\n", DevContext->DeviceMode);
1525 | }
1526 | else
1527 | {
1528 | status = STATUS_INVALID_PARAMETER;
1529 |
1530 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1531 | "CyapaGetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(CyapaFeatureReport) (%d)\n",
1532 | transferPacket->reportBufferLen,
1533 | sizeof(CyapaFeatureReport));
1534 | }
1535 |
1536 | break;
1537 | }
1538 |
1539 | case REPORTID_PTPHQA:
1540 | {
1541 | uint8_t PTPHQA_BLOB[] = { REPORTID_PTPHQA, 0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, 0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, 0x07,\
1542 | 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, 0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, 0x2e, 0x84,\
1543 | 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, 0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, 0x47, 0x70, 0x1b,\
1544 | 0x59, 0x6f, 0x74, 0x43, 0xc4, 0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, 0xc7, 0x95, 0x0e, 0x31,\
1545 | 0x55, 0x21, 0xd3, 0xb5, 0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, 0x3e, 0xb3, 0xaf, 0x75, 0x81,\
1546 | 0x9d, 0x53, 0xb9, 0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, 0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d,\
1547 | 0xa7, 0x26, 0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, 0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0,\
1548 | 0x2a, 0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, 0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, 0x0b,\
1549 | 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, 0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, 0xe8, 0x8a,\
1550 | 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, 0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, 0x2b, 0x53, 0x5c,\
1551 | 0x69, 0x52, 0xd5, 0xc8, 0x73, 0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, 0x05, 0xd8, 0x2b, 0x79,\
1552 | 0x9a, 0xe2, 0x34, 0x60, 0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, 0x80, 0xe3, 0x0f, 0xbd, 0x65,\
1553 | 0x20, 0x08, 0x13, 0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, 0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe,\
1554 | 0x31, 0x48, 0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, 0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a,\
1555 | 0xe4, 0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, 0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2 };
1556 | if (transferPacket->reportBufferLen >= sizeof(PTPHQA_BLOB))
1557 | {
1558 | uint8_t *blobBuffer = (uint8_t*)transferPacket->reportBuffer;
1559 | for (int i = 0; i < sizeof(PTPHQA_BLOB); i++) {
1560 | blobBuffer[i] = PTPHQA_BLOB[i];
1561 | }
1562 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
1563 | "CyapaGetFeature PHPHQA\n");
1564 | }
1565 | else
1566 | {
1567 | status = STATUS_INVALID_PARAMETER;
1568 |
1569 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1570 | "CyapaGetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(PTPHEQ_BLOB) (%d)\n",
1571 | transferPacket->reportBufferLen,
1572 | sizeof(CyapaFeatureReport));
1573 | }
1574 | break;
1575 | }
1576 |
1577 | default:
1578 |
1579 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
1580 | "CyapaGetFeature Unhandled report type %d\n", transferPacket->reportId);
1581 |
1582 | status = STATUS_INVALID_PARAMETER;
1583 |
1584 | break;
1585 | }
1586 | }
1587 | }
1588 |
1589 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL,
1590 | "CyapaGetFeature Exit = 0x%x\n", status);
1591 |
1592 | return status;
1593 | }
1594 |
1595 | PCHAR
1596 | DbgHidInternalIoctlString(
1597 | IN ULONG IoControlCode
1598 | )
1599 | {
1600 | switch (IoControlCode)
1601 | {
1602 | case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
1603 | return "IOCTL_HID_GET_DEVICE_DESCRIPTOR";
1604 | case IOCTL_HID_GET_REPORT_DESCRIPTOR:
1605 | return "IOCTL_HID_GET_REPORT_DESCRIPTOR";
1606 | case IOCTL_HID_READ_REPORT:
1607 | return "IOCTL_HID_READ_REPORT";
1608 | case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
1609 | return "IOCTL_HID_GET_DEVICE_ATTRIBUTES";
1610 | case IOCTL_HID_WRITE_REPORT:
1611 | return "IOCTL_HID_WRITE_REPORT";
1612 | case IOCTL_HID_SET_FEATURE:
1613 | return "IOCTL_HID_SET_FEATURE";
1614 | case IOCTL_HID_GET_FEATURE:
1615 | return "IOCTL_HID_GET_FEATURE";
1616 | case IOCTL_HID_GET_STRING:
1617 | return "IOCTL_HID_GET_STRING";
1618 | case IOCTL_HID_ACTIVATE_DEVICE:
1619 | return "IOCTL_HID_ACTIVATE_DEVICE";
1620 | case IOCTL_HID_DEACTIVATE_DEVICE:
1621 | return "IOCTL_HID_DEACTIVATE_DEVICE";
1622 | case IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:
1623 | return "IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST";
1624 | case IOCTL_HID_SET_OUTPUT_REPORT:
1625 | return "IOCTL_HID_SET_OUTPUT_REPORT";
1626 | case IOCTL_HID_GET_INPUT_REPORT:
1627 | return "IOCTL_HID_GET_INPUT_REPORT";
1628 | default:
1629 | return "Unknown IOCTL";
1630 | }
1631 | }
1632 |
--------------------------------------------------------------------------------