├── crostouchpad ├── stdint.h ├── trace.h ├── hidcommon.h ├── crostouchpad.vcxproj.user ├── crostouchpad.vcxproj.filters ├── crostouchpad.inf ├── smbus.h ├── cyapa.h ├── smbus.c ├── driver.h ├── crostouchpad.vcxproj └── cyapa.c ├── crostouchpad Package ├── crostouchpad Package.vcxproj.user ├── crostouchpad Package.vcxproj.filters └── crostouchpad Package.vcxproj ├── README.md ├── LICENSE.txt ├── crostpint ├── crostpint │ ├── trace.h │ ├── crostpint.inf │ ├── driver.h │ ├── crostpint.c │ └── crostpint.vcxproj ├── crostpint.sln └── crostpint Package │ └── crostpint Package.vcxproj ├── .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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # crostouchpad4-smbus 2 | Cypress Gen3 SMBus Precision Touchpad Driver for Acer C7, C710, HP Pavilion 14, Samsung Series 5 550 Chromebooks. 3 | 4 | Tested and verified on Acer C710 chromebook. 5 | 6 | # Credits 7 | 8 | Huge thanks to the vmulti and DragonFlyBSD projects, which I used for references. Also thanks to Microsoft for documenting the Precision Touchpad Driver protocol. 9 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /crostpint/crostpint/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 ButtonsPressed; 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 | -------------------------------------------------------------------------------- /crostpint/crostpint/crostpint.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ;Copyright (c) CoolStar. All rights reserved. 4 | ; 5 | ;Module Name: 6 | ; crostpint.inf 7 | ; 8 | ;Abstract: 9 | ; INF file for installing the Cypress SMBus Interrupt 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 = 5/1/2022, 4.1.3 20 | CatalogFile = crostpint.cat 21 | PnpLockdown = 1 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | ; ================= Class section ===================== 27 | 28 | [SourceDisksNames] 29 | 1 = %DiskId1%,,,"" 30 | 31 | [SourceDisksFiles] 32 | crostpint.sys = 1,, 33 | 34 | ;***************************************** 35 | ; CrosTpInt 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 | %CrosTpInt.DeviceDesc%=Max98090_Device, ACPI\VEN_CYSM&DEV_0000&REV_0002 45 | 46 | [Max98090_Device.NT] 47 | CopyFiles=Drivers_Dir 48 | 49 | [Max98090_Device.NT.HW] 50 | AddReg=Max98090_AddReg 51 | 52 | [Drivers_Dir] 53 | crostpint.sys 54 | 55 | [Max98090_AddReg] 56 | ; Set to 1 to connect the first interrupt resource found, 0 to leave disconnected 57 | HKR,Settings,"ConnectInterrupt",0x00010001,0 58 | 59 | ;-------------- Service installation 60 | [Max98090_Device.NT.Services] 61 | AddService = CrosTpInt,%SPSVCINST_ASSOCSERVICE%, Max98090_Service_Inst 62 | 63 | ; -------------- Max98090 driver install sections 64 | [Max98090_Service_Inst] 65 | DisplayName = %CrosTpInt.SVCDESC% 66 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 67 | StartType = 3 ; SERVICE_DEMAND_START 68 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 69 | ServiceBinary = %12%\crostpint.sys 70 | LoadOrderGroup = Base 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | StdMfg = "CoolStar" 75 | DiskId1 = "CrosTouchpad Installation Disk #1" 76 | CrosTpInt.DeviceDesc = "Chromebook Cypress Touchpad (SMBus Interrupt)" 77 | CrosTpInt.SVCDESC = "CrosTpInt Service" 78 | -------------------------------------------------------------------------------- /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, PCI\VEN_8086&DEV_1E22&SUBSYS_04B418D1 45 | %CrosTouchpad.DeviceDesc%=CrosTouchpad_Device, PCI\VEN_8086&DEV_1C22&SUBSYS_04B418D1 46 | 47 | [CrosTouchpad_Device.NT] 48 | CopyFiles=Drivers_Dir 49 | 50 | [CrosTouchpad_Device.NT.HW] 51 | AddReg=CrosTouchpad_AddReg 52 | 53 | [Drivers_Dir] 54 | crostouchpad.sys 55 | 56 | [CrosTouchpad_AddReg] 57 | ; Set to 1 to connect the first interrupt resource found, 0 to leave disconnected 58 | HKR,Settings,"ConnectInterrupt",0x00010001,0 59 | HKR,,"UpperFilters",0x00010000,"mshidkmdf" 60 | 61 | ;-------------- Service installation 62 | [CrosTouchpad_Device.NT.Services] 63 | AddService = CrosTouchpad,%SPSVCINST_ASSOCSERVICE%, CrosTouchpad_Service_Inst 64 | 65 | ; -------------- CrosTouchpad driver install sections 66 | [CrosTouchpad_Service_Inst] 67 | DisplayName = %CrosTouchpad.SVCDESC% 68 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 69 | StartType = 3 ; SERVICE_DEMAND_START 70 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 71 | ServiceBinary = %12%\crostouchpad.sys 72 | LoadOrderGroup = Base 73 | 74 | [Strings] 75 | SPSVCINST_ASSOCSERVICE= 0x00000002 76 | StdMfg = "CoolStar" 77 | DiskId1 = "CrosTouchpad Installation Disk #1" 78 | CrosTouchpad.DeviceDesc = "Chromebook Cypress v3 SMBus Touchpad" 79 | CrosTouchpad.SVCDESC = "CrosTouchpad Service" 80 | -------------------------------------------------------------------------------- /crostpint/crostpint/driver.h: -------------------------------------------------------------------------------- 1 | #if !defined(_CROSTPINT_H_) 2 | #define _CROSTPINT_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 | #include 10 | 11 | #pragma warning(default:4200) 12 | #pragma warning(default:4201) 13 | #pragma warning(default:4214) 14 | #include 15 | 16 | #pragma warning(disable:4201) // suppress nameless struct/union warning 17 | #pragma warning(disable:4214) // suppress bit field types other than int warning 18 | 19 | // 20 | // String definitions 21 | // 22 | 23 | #define DRIVERNAME "crostpint.sys: " 24 | 25 | #define CROSTPINT_POOL_TAG (ULONG) 'msyC' 26 | 27 | #define true 1 28 | #define false 0 29 | 30 | #define CrosTpSig 'ptyC' 31 | 32 | typedef enum { 33 | CrosTpCallbackSourceTouchpad = 0, 34 | CrosTpCallbackSourceInterrupt = 1 35 | } CrosTpCallbackSource; 36 | 37 | typedef enum { 38 | CrosTPCallbackActionRegister = 0, 39 | CrosTPCallbackActionUnregister = 1 40 | } CrosTPCallbackAction; 41 | 42 | typedef BOOLEAN(*CrosTPInt_Callback)(PVOID devContext); 43 | 44 | typedef struct _CROSTPCALLBACK_PKT 45 | { 46 | UINT32 signature; 47 | 48 | CrosTPCallbackAction action; 49 | CrosTpCallbackSource actionSource; 50 | NTSTATUS actionStatus; 51 | 52 | union { 53 | struct { 54 | PVOID devContext; 55 | CrosTPInt_Callback callbackFunction; 56 | } registrationParameters; 57 | } actionParameters; 58 | } CROSTPCALLBACK_PKT, *PCROSTPCALLBACK_PKT; 59 | 60 | typedef struct _CROSTPINT_CONTEXT 61 | { 62 | 63 | // 64 | // Handle back to the WDFDEVICE 65 | // 66 | 67 | WDFDEVICE FxDevice; 68 | 69 | WDFINTERRUPT Interrupt; 70 | 71 | PCALLBACK_OBJECT CrosTpIntCallback; 72 | PVOID CrosTpCallbackObj; 73 | CROSTPCALLBACK_PKT CrosTpCallbackTempContext; 74 | 75 | PVOID touchpadDevContext; 76 | CrosTPInt_Callback touchpadCallbackFunction; 77 | 78 | BOOLEAN ConnectInterrupt; 79 | 80 | } CROSTPINT_CONTEXT, *PCROSTPINT_CONTEXT; 81 | 82 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CROSTPINT_CONTEXT, GetDeviceContext) 83 | 84 | // 85 | // Function definitions 86 | // 87 | 88 | DRIVER_INITIALIZE DriverEntry; 89 | 90 | EVT_WDF_DRIVER_UNLOAD CrosTpIntDriverUnload; 91 | 92 | EVT_WDF_DRIVER_DEVICE_ADD CrosTpIntEvtDeviceAdd; 93 | 94 | EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL CrosTpIntEvtInternalDeviceControl; 95 | 96 | // 97 | // Helper macros 98 | // 99 | 100 | #define DEBUG_LEVEL_ERROR 1 101 | #define DEBUG_LEVEL_INFO 2 102 | #define DEBUG_LEVEL_VERBOSE 3 103 | 104 | #define DBG_INIT 1 105 | #define DBG_PNP 2 106 | #define DBG_IOCTL 4 107 | 108 | #if 0 109 | #define CrosTpIntPrint(dbglevel, dbgcatagory, fmt, ...) { \ 110 | if (CrosTpIntDebugLevel >= dbglevel && \ 111 | (CrosTpIntDebugCatagories && dbgcatagory)) \ 112 | { \ 113 | DbgPrint(DRIVERNAME); \ 114 | DbgPrint(fmt, __VA_ARGS__); \ 115 | } \ 116 | } 117 | #else 118 | #define CrosTpIntPrint(dbglevel, fmt, ...) { \ 119 | } 120 | #endif 121 | #endif -------------------------------------------------------------------------------- /crostouchpad/smbus.h: -------------------------------------------------------------------------------- 1 | /* i2c_smbus_xfer read or write markers */ 2 | #define I2C_SMBUS_READ 1 3 | #define I2C_SMBUS_WRITE 0 4 | 5 | /* SMBus transaction types (size parameter in the above functions) 6 | Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ 7 | #define I2C_SMBUS_QUICK 0 8 | #define I2C_SMBUS_BYTE 1 9 | #define I2C_SMBUS_BYTE_DATA 2 10 | #define I2C_SMBUS_WORD_DATA 3 11 | #define I2C_SMBUS_PROC_CALL 4 12 | #define I2C_SMBUS_BLOCK_DATA 5 13 | #define I2C_SMBUS_I2C_BLOCK_BROKEN 6 14 | #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ 15 | #define I2C_SMBUS_I2C_BLOCK_DATA 8 16 | 17 | /* flags for the client struct: */ 18 | #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ 19 | 20 | /* 21 | * Data for SMBus Messages 22 | */ 23 | #define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ 24 | union i2c_smbus_data { 25 | uint8_t byte; 26 | uint16_t word; 27 | uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; 28 | }; 29 | 30 | /* I801 SMBus address offsets */ 31 | #define SMBHSTSTS(p) (0 + (p)->SMBusBase) 32 | #define SMBHSTCNT(p) (2 + (p)->SMBusBase) 33 | #define SMBHSTCMD(p) (3 + (p)->SMBusBase) 34 | #define SMBHSTADD(p) (4 + (p)->SMBusBase) 35 | #define SMBHSTDAT0(p) (5 + (p)->SMBusBase) 36 | #define SMBHSTDAT1(p) (6 + (p)->SMBusBase) 37 | #define SMBBLKDAT(p) (7 + (p)->SMBusBase) 38 | #define SMBPEC(p) (8 + (p)->SMBusBase) /* ICH3 and later */ 39 | #define SMBAUXSTS(p) (12 + (p)->SMBusBase) /* ICH4 and later */ 40 | #define SMBAUXCTL(p) (13 + (p)->SMBusBase) /* ICH4 and later */ 41 | #define SMBSLVSTS(p) (16 + (p)->SMBusBase) /* ICH3 and later */ 42 | #define SMBSLVCMD(p) (17 + (p)->SMBusBase) /* ICH3 and later */ 43 | #define SMBNTFDADD(p) (20 + (p)->SMBusBase) /* ICH3 and later */ 44 | #define SMBNTFDDAT(p) (22 + (p)->SMBusBase) /* ICH3 and later */ 45 | 46 | /* PCI Address Constants */ 47 | #define SMBBAR 4 48 | #define SMBPCICTL 0x004 49 | #define SMBPCISTS 0x006 50 | #define SMBHSTCFG 0x040 51 | #define TCOBASE 0x050 52 | #define TCOCTL 0x054 53 | 54 | #define ACPIBASE 0x040 55 | #define ACPIBASE_SMI_OFF 0x030 56 | #define ACPICTRL 0x044 57 | #define ACPICTRL_EN 0x080 58 | 59 | #define SBREG_BAR 0x10 60 | #define SBREG_SMBCTRL 0xc6000c 61 | 62 | /* Host status bits for SMBPCISTS */ 63 | #define SMBPCISTS_INTS 0x08 64 | 65 | /* Control bits for SMBPCICTL */ 66 | #define SMBPCICTL_INTDIS 0x0400 67 | 68 | /* Host configuration bits for SMBHSTCFG */ 69 | #define SMBHSTCFG_HST_EN 1 70 | #define SMBHSTCFG_SMB_SMI_EN 2 71 | #define SMBHSTCFG_I2C_EN 4 72 | 73 | /* TCO configuration bits for TCOCTL */ 74 | #define TCOCTL_EN 0x0100 75 | 76 | /* Auxiliary status register bits, ICH4+ only */ 77 | #define SMBAUXSTS_CRCE 1 78 | #define SMBAUXSTS_STCO 2 79 | 80 | /* Auxiliary control register bits, ICH4+ only */ 81 | #define SMBAUXCTL_CRC 1 82 | #define SMBAUXCTL_E32B 2 83 | 84 | /* Other settings */ 85 | #define MAX_RETRIES 400 86 | 87 | /* I801 command constants */ 88 | #define I801_QUICK 0x00 89 | #define I801_BYTE 0x04 90 | #define I801_BYTE_DATA 0x08 91 | #define I801_WORD_DATA 0x0C 92 | #define I801_PROC_CALL 0x10 /* unimplemented */ 93 | #define I801_BLOCK_DATA 0x14 94 | #define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ 95 | 96 | /* I801 Host Control register bits */ 97 | #define SMBHSTCNT_INTREN 0x01 98 | #define SMBHSTCNT_KILL 0x02 99 | #define SMBHSTCNT_LAST_BYTE 0x20 100 | #define SMBHSTCNT_START 0x40 101 | #define SMBHSTCNT_PEC_EN 0x80 /* ICH3 and later */ 102 | 103 | /* I801 Hosts Status register bits */ 104 | #define SMBHSTSTS_BYTE_DONE 0x80 105 | #define SMBHSTSTS_INUSE_STS 0x40 106 | #define SMBHSTSTS_SMBALERT_STS 0x20 107 | #define SMBHSTSTS_FAILED 0x10 108 | #define SMBHSTSTS_BUS_ERR 0x08 109 | #define SMBHSTSTS_DEV_ERR 0x04 110 | #define SMBHSTSTS_INTR 0x02 111 | #define SMBHSTSTS_HOST_BUSY 0x01 112 | 113 | /* Host Notify Status registers bits */ 114 | #define SMBSLVSTS_HST_NTFY_STS 1 115 | 116 | /* Host Notify Command registers bits */ 117 | #define SMBSLVCMD_HST_NTFY_INTREN 0x01 118 | 119 | #define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ 120 | SMBHSTSTS_DEV_ERR) 121 | 122 | #define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \ 123 | STATUS_ERROR_FLAGS) -------------------------------------------------------------------------------- /crostpint/crostpint.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31829.152 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crostpint", "crostpint\crostpint.vcxproj", "{B3E71397-9BE4-492B-AAED-4D056E59CB1F}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crostpint Package", "crostpint Package\crostpint 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 | Win8 Debug|Win32 = Win8 Debug|Win32 16 | Win8 Debug|x64 = Win8 Debug|x64 17 | Win8 Release|Win32 = Win8 Release|Win32 18 | Win8 Release|x64 = Win8 Release|x64 19 | Win8.1 Debug|Win32 = Win8.1 Debug|Win32 20 | Win8.1 Debug|x64 = Win8.1 Debug|x64 21 | Win8.1 Release|Win32 = Win8.1 Release|Win32 22 | Win8.1 Release|x64 = Win8.1 Release|x64 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 26 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 27 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 28 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 29 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 30 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 31 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 32 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 33 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 34 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 35 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|x64.Build.0 = Win8 Release|x64 36 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 37 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32 38 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32 39 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32 40 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 41 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 42 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 43 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32 44 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32 45 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32 46 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 47 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 48 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 49 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 50 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 51 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 52 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 53 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 54 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 55 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 56 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 57 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 58 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 59 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|x64.Build.0 = Win8 Release|x64 60 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 61 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32 62 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32 63 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32 64 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 65 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 66 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 67 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32 68 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32 69 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32 70 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 71 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 72 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 73 | EndGlobalSection 74 | GlobalSection(SolutionProperties) = preSolution 75 | HideSolutionNode = FALSE 76 | EndGlobalSection 77 | GlobalSection(ExtensibilityGlobals) = postSolution 78 | SolutionGuid = {86D249D6-FF1E-41F4-AA9B-3813428D6C1A} 79 | EndGlobalSection 80 | EndGlobal 81 | -------------------------------------------------------------------------------- /.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/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 << 3 139 | #define CYAPA_FNGR_RIGHT 0x02 << 3 140 | #define CYAPA_FNGR_LEFT 0x01 << 3 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_POWER_MODE_OFF 0x00 150 | #define CMD_POWER_MODE_IDLE 0x14 151 | #define CMD_POWER_MODE_FULL 0xFC 152 | 153 | /* for byte read/write command */ 154 | #define CMD_RESET 0 155 | #define CMD_POWER_MODE 1 156 | #define CMD_DEV_STATUS 2 157 | #define CMD_REPORT_MAX_BASELINE 3 158 | #define CMD_REPORT_MIN_BASELINE 4 159 | #define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1) 160 | #define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET) 161 | #define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE) 162 | #define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS) 163 | #define CYAPA_SMBUS_MAX_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MAX_BASELINE) 164 | #define CYAPA_SMBUS_MIN_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MIN_BASELINE) 165 | 166 | /* for group registers read/write command */ 167 | #define REG_GROUP_DATA 0 168 | #define REG_GROUP_CMD 2 169 | #define REG_GROUP_QUERY 3 170 | #define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3)) 171 | 172 | #define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA) 173 | #define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD) 174 | #define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY) 175 | 176 | /* for register block read/write command */ 177 | #define CMD_BL_STATUS 0 178 | #define CMD_BL_HEAD 1 179 | #define CMD_BL_CMD 2 180 | #define CMD_BL_DATA 3 181 | #define CMD_BL_ALL 4 182 | #define CMD_BLK_PRODUCT_ID 5 183 | #define CMD_BLK_HEAD 6 184 | #define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1)) 185 | 186 | /* register block read/write command in bootloader mode */ 187 | #define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS) 188 | #define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD) 189 | #define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD) 190 | #define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA) 191 | #define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL) 192 | 193 | /* register block read/write command in operational mode */ 194 | #define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID) 195 | #define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD) 196 | 197 | #define SMBUS_READ 0x01 198 | #define SMBUS_WRITE 0x00 199 | #define SMBUS_ENCODE_IDX(cmd, idx) ((cmd) | (((idx) & 0x03) << 1)) 200 | #define SMBUS_ENCODE_RW(cmd, rw) ((cmd) | ((rw) & 0x01)) 201 | 202 | 203 | /*struct cyapa_softc { 204 | uint32_t x; 205 | uint32_t y; 206 | bool mousedown; 207 | int mousebutton; 208 | int lastnfingers; 209 | int lastid = -1; 210 | bool mousedownfromtap; 211 | int tick = 0; 212 | int tickssincelastclick = 0; 213 | 214 | int multitaskinggesturetick = 0; 215 | int multitaskingx; 216 | int multitaskingy; 217 | bool multitaskingdone; 218 | bool hasmoved; 219 | 220 | int scrollratelimit = 0; 221 | };*/ 222 | 223 | static int cyapa_minpressure = 16; 224 | static int cyapa_norm_freq = 100; 225 | 226 | #define ZSCALE 10 227 | #define SIMULATE_BUT4 0x0100 228 | #define SIMULATE_BUT5 0x0200 229 | #define SIMULATE_LOCK 0x8000 230 | 231 | #define MXT_T9_RELEASE (1 << 5) 232 | #define MXT_T9_PRESS (1 << 6) 233 | #define MXT_T9_DETECT (1 << 7) 234 | 235 | #endif -------------------------------------------------------------------------------- /crostouchpad/smbus.c: -------------------------------------------------------------------------------- 1 | #include "driver.h" 2 | #include 3 | #include 4 | 5 | static ULONG CyapaDebugLevel = 100; 6 | static ULONG CyapaDebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL; 7 | 8 | static unsigned char inb_p(unsigned short int port) { 9 | unsigned char value = __inbyte(port); 10 | return value; 11 | } 12 | 13 | static void outb_p(unsigned char value, unsigned short int port) { 14 | __outbyte(port, value); 15 | } 16 | 17 | static void cyapa_set_slave_addr(PCYAPA_CONTEXT pDevice, uint8_t smbusread) { 18 | outb_p(((0x67 & 0x7f) << 1) | (smbusread & 0x01), SMBHSTADD(pDevice)); // 0x67 19 | } 20 | 21 | BOOLEAN cyapa_read_byte_callback(PCYAPA_CONTEXT pDevice, uint8_t status); 22 | uint32_t cyapa_read_byte(PCYAPA_CONTEXT pDevice, uint8_t cmd, SMBUS_USER_CALLBACK callback, PVOID arg) { 23 | if (pDevice->SMBusLocked) { 24 | return 1; 25 | } 26 | pDevice->SMBusLocked = true; 27 | pDevice->InterruptRaised = false; 28 | 29 | cyapa_set_slave_addr(pDevice, 1); 30 | outb_p(cmd, SMBHSTCMD(pDevice)); 31 | 32 | //Disable Hardware PEC 33 | outb_p(inb_p(SMBAUXCTL(pDevice)) & (~SMBAUXCTL_CRC), 34 | SMBAUXCTL(pDevice)); 35 | 36 | //check if ready 37 | uint8_t status = inb_p(SMBHSTSTS(pDevice)); 38 | if (status & SMBHSTSTS_HOST_BUSY) { 39 | DbgPrint("SMBus is Busy! Can't use it :(\n"); 40 | return 1; 41 | } 42 | 43 | outb_p(0x49, SMBHSTCNT(pDevice)); 44 | 45 | pDevice->SMBusInternalCallback = cyapa_read_byte_callback; 46 | pDevice->SMBusUserCallback = callback; 47 | pDevice->SMBusUserCallbackArg = arg; 48 | 49 | //wait for interrupt 50 | return 0; 51 | } 52 | 53 | BOOLEAN cyapa_read_byte_callback(PCYAPA_CONTEXT pDevice, uint8_t status) { 54 | status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; 55 | if (status) { 56 | outb_p(status, SMBHSTSTS(pDevice)); 57 | } 58 | 59 | uint8_t data = inb_p(SMBHSTDAT0(pDevice)); 60 | 61 | pDevice->SMBusLocked = false; 62 | pDevice->InterruptRaised = false; 63 | 64 | if (pDevice->SMBusUserCallback) { 65 | SMBUS_USER_CALLBACK callback = pDevice->SMBusUserCallback; 66 | PVOID arg = pDevice->SMBusUserCallbackArg; 67 | pDevice->SMBusUserCallback = NULL; 68 | pDevice->SMBusUserCallbackArg = NULL; 69 | 70 | callback(pDevice, true, &data, 1, arg); 71 | } 72 | return true; 73 | } 74 | 75 | BOOLEAN cyapa_write_byte_callback(PCYAPA_CONTEXT pDevice, uint8_t status); 76 | uint32_t cyapa_write_byte(PCYAPA_CONTEXT pDevice, uint8_t cmd, uint8_t value, SMBUS_USER_CALLBACK callback, PVOID arg) { 77 | if (pDevice->SMBusLocked) { 78 | return 1; 79 | } 80 | pDevice->SMBusLocked = true; 81 | pDevice->InterruptRaised = false; 82 | 83 | cyapa_set_slave_addr(pDevice, 0); 84 | outb_p(cmd, SMBHSTCMD(pDevice)); 85 | outb_p(value, SMBHSTDAT0(pDevice)); 86 | 87 | //Disable Hardware PEC 88 | outb_p(inb_p(SMBAUXCTL(pDevice)) & (~SMBAUXCTL_CRC), 89 | SMBAUXCTL(pDevice)); 90 | 91 | //check if ready 92 | uint8_t status = inb_p(SMBHSTSTS(pDevice)); 93 | if (status & SMBHSTSTS_HOST_BUSY) { 94 | DbgPrint("SMBus is Busy! Can't use it :(\n"); 95 | return 1; 96 | } 97 | 98 | outb_p(0x49, SMBHSTCNT(pDevice)); 99 | 100 | pDevice->SMBusInternalCallback = cyapa_write_byte_callback; 101 | pDevice->SMBusUserCallback = callback; 102 | pDevice->SMBusUserCallbackArg = arg; 103 | //wait for interrupt 104 | return 0; 105 | } 106 | 107 | BOOLEAN cyapa_write_byte_callback(PCYAPA_CONTEXT pDevice, uint8_t status) { 108 | status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; 109 | if (status) { 110 | outb_p(status, SMBHSTSTS(pDevice)); 111 | } 112 | 113 | pDevice->SMBusLocked = false; 114 | pDevice->InterruptRaised = false; 115 | 116 | if (pDevice->SMBusUserCallback) { 117 | SMBUS_USER_CALLBACK callback = pDevice->SMBusUserCallback; 118 | PVOID arg = pDevice->SMBusUserCallbackArg; 119 | pDevice->SMBusUserCallback = NULL; 120 | pDevice->SMBusUserCallbackArg = NULL; 121 | 122 | callback(pDevice, true, NULL, 0, arg); 123 | } 124 | return true; 125 | } 126 | 127 | BOOLEAN cyapa_read_block_callback(PCYAPA_CONTEXT pDevice, uint8_t status); 128 | uint32_t cyapa_read_block(PCYAPA_CONTEXT pDevice, uint8_t cmd, SMBUS_USER_CALLBACK callback, PVOID arg) { 129 | if (pDevice->SMBusLocked) { 130 | return 1; 131 | } 132 | 133 | /* Clear special mode bits */ 134 | outb_p(inb_p(SMBAUXCTL(pDevice)) & 135 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(pDevice)); 136 | 137 | pDevice->SMBusLocked = true; 138 | pDevice->InterruptRaised = false; 139 | 140 | cyapa_set_slave_addr(pDevice, 1); 141 | outb_p(cmd, SMBHSTCMD(pDevice)); 142 | 143 | //Enable Hardware PEC 144 | outb_p(inb_p(SMBAUXCTL(pDevice)) & (~SMBAUXCTL_CRC), 145 | SMBAUXCTL(pDevice)); 146 | 147 | //set block buffer mode 148 | outb_p(inb_p(SMBAUXCTL(pDevice)) | SMBAUXCTL_E32B, SMBAUXCTL(pDevice)); 149 | if ((inb_p(SMBAUXCTL(pDevice)) & SMBAUXCTL_E32B) == 0) { 150 | DbgPrint("SMBus was unable to set block buffer mode :(\n"); 151 | return 1; 152 | } 153 | 154 | inb_p(SMBHSTCNT(pDevice)); /* reset the data buffer index */ 155 | 156 | //check if ready 157 | uint8_t status = inb_p(SMBHSTSTS(pDevice)); 158 | if (status & SMBHSTSTS_HOST_BUSY) { 159 | DbgPrint("SMBus is Busy! Can't use it :(\n"); 160 | return 1; 161 | } 162 | 163 | outb_p(0x55, SMBHSTCNT(pDevice)); 164 | 165 | pDevice->SMBusInternalCallback = cyapa_read_block_callback; 166 | pDevice->SMBusUserCallback = callback; 167 | pDevice->SMBusUserCallbackArg = arg; 168 | 169 | //wait for interrupt 170 | return 0; 171 | } 172 | 173 | BOOLEAN cyapa_read_block_callback(PCYAPA_CONTEXT pDevice, uint8_t status) { 174 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "SMB Read Status: 0x%x\n", status); 175 | status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; 176 | if (status) { 177 | outb_p(status, SMBHSTSTS(pDevice)); 178 | } 179 | 180 | unsigned char len = inb_p(SMBHSTDAT0(pDevice)); 181 | if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) { 182 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "SMBus invalid length received... %d\n", len); 183 | outb_p(inb_p(SMBAUXCTL(pDevice)) & 184 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(pDevice)); 185 | 186 | pDevice->SMBusLocked = false; 187 | pDevice->InterruptRaised = false; 188 | 189 | if (pDevice->SMBusUserCallback) { 190 | SMBUS_USER_CALLBACK callback = pDevice->SMBusUserCallback; 191 | PVOID arg = pDevice->SMBusUserCallbackArg; 192 | pDevice->SMBusUserCallback = NULL; 193 | pDevice->SMBusUserCallbackArg = NULL; 194 | 195 | callback(pDevice, false, NULL, 0, arg); 196 | } 197 | return TRUE; 198 | } 199 | 200 | uint8_t val[256]; 201 | for (int i = 0; i < len; i++) { 202 | val[i] = inb_p(SMBBLKDAT(pDevice)); 203 | } 204 | //disable hardware PEC 205 | outb_p(inb_p(SMBAUXCTL(pDevice)) & 206 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(pDevice)); 207 | 208 | pDevice->SMBusLocked = false; 209 | pDevice->InterruptRaised = false; 210 | 211 | if (pDevice->SMBusUserCallback) { 212 | SMBUS_USER_CALLBACK callback = pDevice->SMBusUserCallback; 213 | PVOID arg = pDevice->SMBusUserCallbackArg; 214 | pDevice->SMBusUserCallback = NULL; 215 | pDevice->SMBusUserCallbackArg = NULL; 216 | 217 | callback(pDevice, true, val, len, arg); 218 | } 219 | return TRUE; 220 | } 221 | 222 | BOOLEAN cyapa_write_block_callback(PCYAPA_CONTEXT pDevice, uint8_t status); 223 | BOOLEAN cyapa_write_block_callback_done(PCYAPA_CONTEXT pDevice, uint8_t status); 224 | 225 | uint8_t cyapa_write_block(PCYAPA_CONTEXT pDevice, uint8_t cmd, uint8_t *buf, uint8_t len, SMBUS_USER_CALLBACK callback, PVOID arg) { 226 | if (pDevice->SMBusLocked) { 227 | return 1; 228 | } 229 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "SMB Write block, cmd: 0x%x, len: 0x%x\n", cmd, len); 230 | 231 | // 232 | // Get the BUS_INTERFACE_STANDARD for our device so that we can 233 | // read & write to PCI config space. 234 | // 235 | NTSTATUS ntstatus = WdfFdoQueryForInterface(pDevice->FxDevice, 236 | &GUID_BUS_INTERFACE_STANDARD, 237 | (PINTERFACE)&pDevice->BusInterface, 238 | sizeof(BUS_INTERFACE_STANDARD), 239 | 1, // Version 240 | NULL); //InterfaceSpecificData 241 | if (!NT_SUCCESS(ntstatus)) 242 | return 1; 243 | 244 | /* Clear special mode bits */ 245 | outb_p(inb_p(SMBAUXCTL(pDevice)) & 246 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(pDevice)); 247 | 248 | pDevice->SMBusLocked = true; 249 | pDevice->InterruptRaised = false; 250 | 251 | cyapa_set_slave_addr(pDevice, 0); 252 | outb_p(cmd, SMBHSTCMD(pDevice)); 253 | 254 | //Disable Hardware PEC 255 | outb_p(inb_p(SMBAUXCTL(pDevice)) & (~SMBAUXCTL_CRC), 256 | SMBAUXCTL(pDevice)); 257 | 258 | uint8_t hostc = 0; 259 | pDevice->BusInterface.GetBusData( 260 | pDevice->BusInterface.Context, 261 | PCI_WHICHSPACE_CONFIG, //READ config 262 | &hostc, 263 | SMBHSTCFG, 264 | 1); 265 | 266 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "PCI Config hostc byte: 0x%x\n", hostc); 267 | 268 | uint8_t newhostc = hostc | SMBHSTCFG_I2C_EN; 269 | pDevice->BusInterface.SetBusData( 270 | pDevice->BusInterface.Context, 271 | PCI_WHICHSPACE_CONFIG, //WRITE config 272 | &newhostc, 273 | SMBHSTCFG, 274 | 1); // set I2C_EN 275 | 276 | //check if ready 277 | uint8_t status = inb_p(SMBHSTSTS(pDevice)); 278 | if (status & SMBHSTSTS_HOST_BUSY) { 279 | DbgPrint("SMBus is Busy! Can't use it :(\n"); 280 | goto exit; 281 | } 282 | 283 | outb_p(len, SMBHSTDAT0(pDevice)); 284 | outb_p(buf[0], SMBBLKDAT(pDevice)); 285 | 286 | outb_p(0x55, SMBHSTCNT(pDevice)); 287 | 288 | pDevice->SMBusBlockWriteBuf = buf; 289 | pDevice->SMBusBlockWriteIdx = 0; 290 | pDevice->SMBusBlockWriteLen = len; 291 | 292 | pDevice->SMBusHostc = hostc; 293 | 294 | pDevice->SMBusInternalCallback = cyapa_write_block_callback; 295 | pDevice->SMBusUserCallback = callback; 296 | pDevice->SMBusUserCallbackArg = arg; 297 | 298 | //wait for interrupt 299 | return 0; 300 | 301 | exit: 302 | pDevice->BusInterface.SetBusData( 303 | pDevice->BusInterface.Context, 304 | PCI_WHICHSPACE_CONFIG, //WRITE config 305 | &hostc, 306 | SMBHSTCFG, 307 | 1); //restore I2C_EN 308 | return 1; 309 | } 310 | 311 | BOOLEAN cyapa_write_block_callback_internal(PCYAPA_CONTEXT pDevice, uint8_t status, BOOLEAN done) { 312 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "SMB Write Done: %d, Status: 0x%x\n", done, status); 313 | if (!done && status & SMBHSTSTS_BYTE_DONE) { 314 | pDevice->SMBusBlockWriteIdx++; 315 | if (pDevice->SMBusBlockWriteIdx < pDevice->SMBusBlockWriteLen) { 316 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "SMB Wrote Byte %d of %d: 0x%x\n", pDevice->SMBusBlockWriteIdx, pDevice->SMBusBlockWriteLen, pDevice->SMBusBlockWriteBuf[pDevice->SMBusBlockWriteIdx]); 317 | outb_p(pDevice->SMBusBlockWriteBuf[pDevice->SMBusBlockWriteIdx], SMBBLKDAT(pDevice)); 318 | pDevice->SMBusInternalCallback = cyapa_write_block_callback; 319 | } 320 | else { 321 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "SMB Write Done next!\n"); 322 | pDevice->SMBusInternalCallback = cyapa_write_block_callback_done; 323 | } 324 | 325 | /* Clear BYTE_DONE to continue with next byte */ 326 | outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(pDevice)); 327 | return TRUE; 328 | } 329 | 330 | status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; 331 | if (status) { 332 | outb_p(status, SMBHSTSTS(pDevice)); 333 | 334 | if (NT_SUCCESS(status)) { 335 | pDevice->BusInterface.SetBusData( 336 | pDevice->BusInterface.Context, 337 | PCI_WHICHSPACE_CONFIG, //WRITE config 338 | &pDevice->SMBusHostc, 339 | SMBHSTCFG, 340 | 1); //restore I2C_EN 341 | } 342 | 343 | //SMBus Error raised! 344 | pDevice->SMBusLocked = false; 345 | pDevice->InterruptRaised = false; 346 | 347 | if (status & STATUS_ERROR_FLAGS) { 348 | DbgPrint("SMB Write Returning due to error.\n"); 349 | } 350 | else { 351 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "Finished SMB write without errors!\n"); 352 | } 353 | 354 | if (pDevice->SMBusUserCallback) { 355 | SMBUS_USER_CALLBACK callback = pDevice->SMBusUserCallback; 356 | PVOID arg = pDevice->SMBusUserCallbackArg; 357 | pDevice->SMBusUserCallback = NULL; 358 | pDevice->SMBusUserCallbackArg = NULL; 359 | 360 | callback(pDevice, !(status & STATUS_ERROR_FLAGS), NULL, 0, arg); 361 | } 362 | return TRUE; 363 | } 364 | return FALSE; 365 | } 366 | 367 | BOOLEAN cyapa_write_block_callback(PCYAPA_CONTEXT pDevice, uint8_t status) { 368 | return cyapa_write_block_callback_internal(pDevice, status, FALSE); 369 | } 370 | 371 | BOOLEAN cyapa_write_block_callback_done(PCYAPA_CONTEXT pDevice, uint8_t status) { 372 | return cyapa_write_block_callback_internal(pDevice, status, TRUE); 373 | } -------------------------------------------------------------------------------- /crostpint/crostpint/crostpint.c: -------------------------------------------------------------------------------- 1 | #define DESCRIPTOR_DEF 2 | #include "driver.h" 3 | #include "stdint.h" 4 | 5 | #define bool int 6 | #define MHz 1000000 7 | 8 | static ULONG CrosTpIntDebugLevel = 100; 9 | static ULONG CrosTpIntDebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL; 10 | 11 | NTSTATUS 12 | DriverEntry( 13 | __in PDRIVER_OBJECT DriverObject, 14 | __in PUNICODE_STRING RegistryPath 15 | ) 16 | { 17 | NTSTATUS status = STATUS_SUCCESS; 18 | WDF_DRIVER_CONFIG config; 19 | WDF_OBJECT_ATTRIBUTES attributes; 20 | 21 | CrosTpIntPrint(DEBUG_LEVEL_INFO, DBG_INIT, 22 | "Driver Entry\n"); 23 | 24 | WDF_DRIVER_CONFIG_INIT(&config, CrosTpIntEvtDeviceAdd); 25 | 26 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 27 | 28 | // 29 | // Create a framework driver object to represent our driver. 30 | // 31 | 32 | status = WdfDriverCreate(DriverObject, 33 | RegistryPath, 34 | &attributes, 35 | &config, 36 | WDF_NO_HANDLE 37 | ); 38 | 39 | if (!NT_SUCCESS(status)) 40 | { 41 | CrosTpIntPrint(DEBUG_LEVEL_ERROR, DBG_INIT, 42 | "WdfDriverCreate failed with status 0x%x\n", status); 43 | } 44 | 45 | return status; 46 | } 47 | 48 | int CrosTpArg2 = 1; 49 | 50 | VOID 51 | CrosTpIntCallback( 52 | IN PCROSTPINT_CONTEXT pDevice, 53 | PCROSTPCALLBACK_PKT tpContext, 54 | PVOID Argument2 55 | ) { 56 | if (Argument2 == &CrosTpArg2) { 57 | return; 58 | } 59 | 60 | if (!tpContext) { 61 | return; 62 | } 63 | 64 | if (tpContext->signature != CrosTpSig) { 65 | return; 66 | } 67 | 68 | if (tpContext->actionSource != CrosTpCallbackSourceTouchpad) { 69 | return; 70 | } 71 | 72 | switch (tpContext->action) { 73 | case CrosTPCallbackActionRegister: 74 | { 75 | pDevice->touchpadDevContext = tpContext->actionParameters.registrationParameters.devContext; 76 | pDevice->touchpadCallbackFunction = tpContext->actionParameters.registrationParameters.callbackFunction; 77 | tpContext->actionStatus = STATUS_SUCCESS; 78 | break; 79 | } 80 | case CrosTPCallbackActionUnregister: 81 | { 82 | pDevice->touchpadDevContext = NULL; 83 | pDevice->touchpadCallbackFunction = NULL; 84 | tpContext->actionStatus = STATUS_SUCCESS; 85 | break; 86 | } 87 | default: 88 | break; 89 | } 90 | } 91 | 92 | NTSTATUS 93 | OnPrepareHardware( 94 | _In_ WDFDEVICE FxDevice, 95 | _In_ WDFCMRESLIST FxResourcesRaw, 96 | _In_ WDFCMRESLIST FxResourcesTranslated 97 | ) 98 | /*++ 99 | 100 | Routine Description: 101 | 102 | This routine caches the SPB resource connection ID. 103 | 104 | Arguments: 105 | 106 | FxDevice - a handle to the framework device object 107 | FxResourcesRaw - list of translated hardware resources that 108 | the PnP manager has assigned to the device 109 | FxResourcesTranslated - list of raw hardware resources that 110 | the PnP manager has assigned to the device 111 | 112 | Return Value: 113 | 114 | Status 115 | 116 | --*/ 117 | { 118 | PCROSTPINT_CONTEXT pDevice = GetDeviceContext(FxDevice); 119 | NTSTATUS status = STATUS_SUCCESS; 120 | 121 | UNREFERENCED_PARAMETER(FxResourcesRaw); 122 | 123 | // 124 | // Parse the peripheral's resources. 125 | // 126 | 127 | ULONG resourceCount = WdfCmResourceListGetCount(FxResourcesTranslated); 128 | 129 | for (ULONG i = 0; i < resourceCount; i++) 130 | { 131 | PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor; 132 | 133 | pDescriptor = WdfCmResourceListGetDescriptor( 134 | FxResourcesTranslated, i); 135 | 136 | switch (pDescriptor->Type) 137 | { 138 | default: 139 | // 140 | // Ignoring all other resource types. 141 | // 142 | break; 143 | } 144 | } 145 | 146 | UNICODE_STRING CrosTpSMBusInterrupt; 147 | RtlInitUnicodeString(&CrosTpSMBusInterrupt, L"\\CallBack\\CrosTpSMBusInterrupt"); 148 | 149 | OBJECT_ATTRIBUTES attributes; 150 | InitializeObjectAttributes(&attributes, 151 | &CrosTpSMBusInterrupt, 152 | OBJ_KERNEL_HANDLE | OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 153 | NULL, 154 | NULL 155 | ); 156 | 157 | status = ExCreateCallback(&pDevice->CrosTpIntCallback, &attributes, TRUE, TRUE); 158 | if (!NT_SUCCESS(status)) { 159 | 160 | return status; 161 | } 162 | pDevice->CrosTpCallbackObj = ExRegisterCallback(pDevice->CrosTpIntCallback, 163 | CrosTpIntCallback, 164 | pDevice 165 | ); 166 | if (!pDevice->CrosTpCallbackObj) { 167 | 168 | return STATUS_NO_CALLBACK_ACTIVE; 169 | } 170 | 171 | RtlZeroMemory(&pDevice->CrosTpCallbackTempContext, sizeof(CROSTPCALLBACK_PKT)); 172 | pDevice->CrosTpCallbackTempContext.signature = CrosTpSig; 173 | pDevice->CrosTpCallbackTempContext.action = CrosTPCallbackActionRegister; 174 | pDevice->CrosTpCallbackTempContext.actionSource = CrosTpCallbackSourceInterrupt; 175 | pDevice->CrosTpCallbackTempContext.actionStatus = STATUS_DEVICE_NOT_READY; 176 | ExNotifyCallback(pDevice->CrosTpIntCallback, &pDevice->CrosTpCallbackTempContext, &CrosTpArg2); 177 | 178 | return status; 179 | } 180 | 181 | NTSTATUS 182 | OnReleaseHardware( 183 | _In_ WDFDEVICE FxDevice, 184 | _In_ WDFCMRESLIST FxResourcesTranslated 185 | ) 186 | /*++ 187 | 188 | Routine Description: 189 | 190 | Arguments: 191 | 192 | FxDevice - a handle to the framework device object 193 | FxResourcesTranslated - list of raw hardware resources that 194 | the PnP manager has assigned to the device 195 | 196 | Return Value: 197 | 198 | Status 199 | 200 | --*/ 201 | { 202 | PCROSTPINT_CONTEXT pDevice = GetDeviceContext(FxDevice); 203 | NTSTATUS status = STATUS_SUCCESS; 204 | 205 | UNREFERENCED_PARAMETER(FxResourcesTranslated); 206 | 207 | if (pDevice->CrosTpCallbackObj) { 208 | RtlZeroMemory(&pDevice->CrosTpCallbackTempContext, sizeof(CROSTPCALLBACK_PKT)); 209 | pDevice->CrosTpCallbackTempContext.signature = CrosTpSig; 210 | pDevice->CrosTpCallbackTempContext.action = CrosTPCallbackActionUnregister; 211 | pDevice->CrosTpCallbackTempContext.actionSource = CrosTpCallbackSourceInterrupt; 212 | pDevice->CrosTpCallbackTempContext.actionStatus = STATUS_DEVICE_NOT_READY; 213 | ExNotifyCallback(pDevice->CrosTpIntCallback, &pDevice->CrosTpCallbackTempContext, &CrosTpArg2); //Notify one last time before unregistration 214 | 215 | ExUnregisterCallback(pDevice->CrosTpCallbackObj); 216 | pDevice->CrosTpCallbackObj = NULL; 217 | } 218 | 219 | if (pDevice->CrosTpIntCallback) { 220 | ObDereferenceObject(pDevice->CrosTpIntCallback); 221 | pDevice->CrosTpIntCallback = NULL; 222 | } 223 | 224 | return status; 225 | } 226 | 227 | NTSTATUS 228 | OnD0Entry( 229 | _In_ WDFDEVICE FxDevice, 230 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 231 | ) 232 | /*++ 233 | 234 | Routine Description: 235 | 236 | This routine allocates objects needed by the driver. 237 | 238 | Arguments: 239 | 240 | FxDevice - a handle to the framework device object 241 | FxPreviousState - previous power state 242 | 243 | Return Value: 244 | 245 | Status 246 | 247 | --*/ 248 | { 249 | UNREFERENCED_PARAMETER(FxPreviousState); 250 | 251 | PCROSTPINT_CONTEXT pDevice = GetDeviceContext(FxDevice); 252 | NTSTATUS status = STATUS_SUCCESS; 253 | 254 | pDevice->ConnectInterrupt = true; 255 | 256 | return status; 257 | } 258 | 259 | NTSTATUS 260 | OnD0Exit( 261 | _In_ WDFDEVICE FxDevice, 262 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 263 | ) 264 | /*++ 265 | 266 | Routine Description: 267 | 268 | This routine destroys objects needed by the driver. 269 | 270 | Arguments: 271 | 272 | FxDevice - a handle to the framework device object 273 | FxPreviousState - previous power state 274 | 275 | Return Value: 276 | 277 | Status 278 | 279 | --*/ 280 | { 281 | UNREFERENCED_PARAMETER(FxPreviousState); 282 | 283 | PCROSTPINT_CONTEXT pDevice = GetDeviceContext(FxDevice); 284 | 285 | pDevice->ConnectInterrupt = false; 286 | 287 | return STATUS_SUCCESS; 288 | } 289 | 290 | BOOLEAN OnInterruptIsr( 291 | WDFINTERRUPT Interrupt, 292 | ULONG MessageID) { 293 | UNREFERENCED_PARAMETER(MessageID); 294 | 295 | WDFDEVICE Device = WdfInterruptGetDevice(Interrupt); 296 | PCROSTPINT_CONTEXT pDevice = GetDeviceContext(Device); 297 | 298 | if (!pDevice->ConnectInterrupt) 299 | return false; 300 | 301 | BOOLEAN retVal = false; 302 | if (pDevice->touchpadCallbackFunction) { 303 | retVal = pDevice->touchpadCallbackFunction(pDevice->touchpadDevContext); 304 | } 305 | 306 | return retVal; 307 | } 308 | 309 | NTSTATUS 310 | CrosTpIntEvtDeviceAdd( 311 | IN WDFDRIVER Driver, 312 | IN PWDFDEVICE_INIT DeviceInit 313 | ) 314 | { 315 | NTSTATUS status = STATUS_SUCCESS; 316 | WDF_IO_QUEUE_CONFIG queueConfig; 317 | WDF_OBJECT_ATTRIBUTES attributes; 318 | WDFDEVICE device; 319 | WDF_INTERRUPT_CONFIG interruptConfig; 320 | WDFQUEUE queue; 321 | PCROSTPINT_CONTEXT devContext; 322 | 323 | UNREFERENCED_PARAMETER(Driver); 324 | 325 | PAGED_CODE(); 326 | 327 | CrosTpIntPrint(DEBUG_LEVEL_INFO, DBG_PNP, 328 | "CrosTpIntEvtDeviceAdd called\n"); 329 | 330 | { 331 | WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; 332 | WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); 333 | 334 | pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware; 335 | pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware; 336 | pnpCallbacks.EvtDeviceD0Entry = OnD0Entry; 337 | pnpCallbacks.EvtDeviceD0Exit = OnD0Exit; 338 | 339 | WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks); 340 | } 341 | 342 | // 343 | // Setup the device context 344 | // 345 | 346 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CROSTPINT_CONTEXT); 347 | 348 | // 349 | // Create a framework device object.This call will in turn create 350 | // a WDM device object, attach to the lower stack, and set the 351 | // appropriate flags and attributes. 352 | // 353 | 354 | status = WdfDeviceCreate(&DeviceInit, &attributes, &device); 355 | 356 | if (!NT_SUCCESS(status)) 357 | { 358 | CrosTpIntPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 359 | "WdfDeviceCreate failed with status code 0x%x\n", status); 360 | 361 | return status; 362 | } 363 | 364 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel); 365 | 366 | queueConfig.EvtIoInternalDeviceControl = CrosTpIntEvtInternalDeviceControl; 367 | 368 | status = WdfIoQueueCreate(device, 369 | &queueConfig, 370 | WDF_NO_OBJECT_ATTRIBUTES, 371 | &queue 372 | ); 373 | 374 | if (!NT_SUCCESS(status)) 375 | { 376 | CrosTpIntPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 377 | "WdfIoQueueCreate failed 0x%x\n", status); 378 | 379 | return status; 380 | } 381 | 382 | // 383 | // Create manual I/O queue to take care of hid report read requests 384 | // 385 | 386 | devContext = GetDeviceContext(device); 387 | devContext->FxDevice = device; 388 | 389 | // 390 | // Create an interrupt object for hardware notifications 391 | // 392 | WDF_INTERRUPT_CONFIG_INIT( 393 | &interruptConfig, 394 | OnInterruptIsr, 395 | NULL); 396 | interruptConfig.PassiveHandling = TRUE; 397 | 398 | status = WdfInterruptCreate( 399 | device, 400 | &interruptConfig, 401 | WDF_NO_OBJECT_ATTRIBUTES, 402 | &devContext->Interrupt); 403 | 404 | if (!NT_SUCCESS(status)) 405 | { 406 | CrosTpIntPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 407 | "Error creating WDF interrupt object - %!STATUS!", 408 | status); 409 | 410 | return status; 411 | } 412 | 413 | WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings; 414 | WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings); 415 | wakeSettings.DxState = PowerDeviceD3; 416 | wakeSettings.UserControlOfWakeSettings = WakeAllowUserControl; 417 | wakeSettings.Enabled = WdfTrue; 418 | 419 | status = WdfDeviceAssignSxWakeSettings(device, &wakeSettings); 420 | 421 | if (!NT_SUCCESS(status)) 422 | { 423 | CrosTpIntPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 424 | "Error setting Wake Settings - %!STATUS!", 425 | status); 426 | 427 | return status; 428 | } 429 | 430 | return status; 431 | } 432 | 433 | VOID 434 | CrosTpIntEvtInternalDeviceControl( 435 | IN WDFQUEUE Queue, 436 | IN WDFREQUEST Request, 437 | IN size_t OutputBufferLength, 438 | IN size_t InputBufferLength, 439 | IN ULONG IoControlCode 440 | ) 441 | { 442 | NTSTATUS status = STATUS_SUCCESS; 443 | WDFDEVICE device; 444 | PCROSTPINT_CONTEXT devContext; 445 | 446 | UNREFERENCED_PARAMETER(OutputBufferLength); 447 | UNREFERENCED_PARAMETER(InputBufferLength); 448 | 449 | device = WdfIoQueueGetDevice(Queue); 450 | devContext = GetDeviceContext(device); 451 | 452 | switch (IoControlCode) 453 | { 454 | default: 455 | status = STATUS_NOT_SUPPORTED; 456 | break; 457 | } 458 | 459 | WdfRequestComplete(Request, status); 460 | 461 | return; 462 | } 463 | -------------------------------------------------------------------------------- /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 "stdint.h" 21 | #include "smbus.h" 22 | #include "cyapa.h" 23 | 24 | // 25 | // String definitions 26 | // 27 | 28 | #define DRIVERNAME "crostouchpad4-smbus.sys: " 29 | 30 | #define CYAPA_POOL_TAG (ULONG) 'payC' 31 | #define CYAPA_HARDWARE_IDS L"CoolStar\\CYAP0000\0\0" 32 | #define CYAPA_HARDWARE_IDS_LENGTH sizeof(CYAPA_HARDWARE_IDS) 33 | 34 | #define NTDEVICE_NAME_STRING L"\\Device\\CYAP0000" 35 | #define SYMBOLIC_NAME_STRING L"\\DosDevices\\CYAP0000" 36 | 37 | #define MT_TOUCH_COLLECTION0 \ 38 | 0xa1, 0x02, /* COLLECTION (Logical) */ \ 39 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ 40 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ 41 | 0x09, 0x47, /* USAGE (Confidence) */ \ 42 | 0x09, 0x42, /* USAGE (Tip switch) */ \ 43 | 0x95, 0x02, /* REPORT_COUNT (2) */ \ 44 | 0x75, 0x01, /* REPORT_SIZE (1) */ \ 45 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 46 | 0x95, 0x06, /* REPORT_COUNT (6) */ \ 47 | 0x81, 0x03, /* INPUT (Cnst,Ary,Abs) */ \ 48 | 0x95, 0x01, /* REPORT_COUNT (1) */ \ 49 | 0x75, 0x04, /* REPORT_SIZE (4) */ \ 50 | 0x25, 0x10, /* LOGICAL_MAXIMUM (16) */ \ 51 | 0x09, 0x51, /* USAGE (Contact Identifier)*/ \ 52 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 53 | 0x75, 0x01, /* REPORT_SIZE (1) */ \ 54 | 0x95, 0x04, /* REPORT_COUNT (4) */ \ 55 | 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \ 56 | 0x05, 0x01, /* USAGE_PAGE (Generic Desk..*/ \ 57 | 0x75, 0x10, /* REPORT_SIZE (16) */ \ 58 | 0x55, 0x0e, /* UNIT_EXPONENT (-2) */ \ 59 | /*0x65, 0x13, /* UNIT(Inch,EngLinear) */ \ 60 | 0x65, 0x11, /* UNIT(Cm,SiLinear) */ \ 61 | 0x09, 0x30, /* USAGE (X) */ \ 62 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \ 63 | 0x35, 0x00, /* PHYSICAL_MINIMUM (0) */ \ 64 | 65 | #define MT_TOUCH_COLLECTION1 \ 66 | 0x95, 0x01, /* REPORT_COUNT (1) */ \ 67 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 68 | 69 | #define MT_TOUCH_COLLECTION2 \ 70 | 0x09, 0x31, /* USAGE (Y) */ \ 71 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 72 | 0x05, 0x0d, /* USAGE PAGE (Digitizers) */ \ 73 | 0x25, 0x28, /* LOGICAL_MAXIMUM (40) */ \ 74 | 0x09, 0x30, /* USAGE (Tip Pressure) */ \ 75 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 76 | 0xc0, /* END_COLLECTION */ 77 | 78 | #define MT_REF_TOUCH_COLLECTION \ 79 | MT_TOUCH_COLLECTION0 \ 80 | 0x26, 0x66, 0x03, /* LOGICAL_MAXIMUM (870) */ \ 81 | 0x46, 0x8E, 0x03, /* PHYSICAL_MAXIMUM (910) */ \ 82 | MT_TOUCH_COLLECTION1 \ 83 | 0x26, 0xE0, 0x01, /* LOGICAL_MAXIMUM (480) */ \ 84 | 0x46, 0xFE, 0x01, /* PHYSICAL_MAXIMUM (550) */ \ 85 | MT_TOUCH_COLLECTION2 86 | 87 | #define USAGE_PAGES \ 88 | 0x55, 0x0C, /* UNIT_EXPONENT (-4) */ \ 89 | 0x66, 0x01, 0x10, /* UNIT (Seconds) */ \ 90 | 0x47, 0xff, 0xff, 0x00, 0x00, /* PHYSICAL_MAXIMUM (65535) */ \ 91 | 0x27, 0xff, 0xff, 0x00, 0x00, /* LOGICAL_MAXIMUM (65535) */ \ 92 | 0x75, 0x10, /* REPORT_SIZE (16) */ \ 93 | 0x95, 0x01, /* REPORT_COUNT (1) */ \ 94 | 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */ \ 95 | 0x09, 0x56, /* USAGE (Scan Time) */ \ 96 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 97 | 0x09, 0x54, /* USAGE (Contact count) */ \ 98 | 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ \ 99 | 0x95, 0x01, /* REPORT_COUNT (1) */ \ 100 | 0x75, 0x08, /* REPORT_SIZE (8) */ \ 101 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 102 | 0x05, 0x09, /* USAGE_PAGE (Button) */ \ 103 | 0x75, 0x01, /* REPORT_SIZE (1) */ \ 104 | 0x95, 0x01, /* REPORT_COUNT (1) */ \ 105 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ 106 | 0x09, 0x01, /* USAGE_(Button 1) */ \ 107 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 108 | 0x09, 0x02, /* USAGE_(Button 2) */ \ 109 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 110 | 0x09, 0x03, /* USAGE_(Button 3) */ \ 111 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 112 | 0x95, 0x05, /* REPORT_COUNT (5) */ \ 113 | 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \ 114 | 0x05, 0x0d, /* USAGE_PAGE (Digitizer) */ \ 115 | 0x85, REPORTID_MTOUCH, /* REPORT_ID (Feature) */ \ 116 | 0x09, 0x55, /* USAGE (Contact Count Maximum) */ \ 117 | 0x09, 0x59, /* USAGE (Pad TYpe) */ \ 118 | 0x75, 0x08, /* REPORT_SIZE (8) */ \ 119 | 0x95, 0x02, /* REPORT_COUNT (2) */ \ 120 | 0x25, 0x0f, /* LOGICAL_MAXIMUM (15) */ \ 121 | 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */ \ 122 | 0x85, REPORTID_PTPHQA, /* Report ID (Certification) */ \ 123 | 0x09, 0xC5, /* Usage (0xC5) */ \ 124 | 0x15, 0x00, /* Logical Minimum (0) */ \ 125 | 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ \ 126 | 0x75, 0x08, /* Report Size (8) */ \ 127 | 0x96, 0x00, 0x01, /* Report Count (256) */ \ 128 | 0xB1, 0x02, /* Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */ \ 129 | 0xc0, /* END_COLLECTION */ \ 130 | \ 131 | /*MOUSE TLC */ \ 132 | 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \ 133 | 0x09, 0x02, /* USAGE (Mouse) */ \ 134 | 0xa1, 0x01, /* COLLECTION (Application) */ \ 135 | 0x85, REPORTID_MOUSE, /* REPORT_ID (Mouse) */ \ 136 | 0x09, 0x01, /* USAGE (Pointer) */ \ 137 | 0xa1, 0x00, /* COLLECTION (Physical) */ \ 138 | 0x05, 0x09, /* USAGE_PAGE (Button) */ \ 139 | 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ \ 140 | 0x29, 0x02, /* USAGE_MAXIMUM (Button 2) */ \ 141 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \ 142 | 0x75, 0x01, /* REPORT_SIZE (1) */ \ 143 | 0x95, 0x02, /* REPORT_COUNT (2) */ \ 144 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */ \ 145 | 0x95, 0x06, /* REPORT_COUNT (6) */ \ 146 | 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ \ 147 | 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \ 148 | 0x09, 0x30, /* USAGE (X) */ \ 149 | 0x09, 0x31, /* USAGE (Y) */ \ 150 | 0x75, 0x10, /* REPORT_SIZE (16) */ \ 151 | 0x95, 0x02, /* REPORT_COUNT (2) */ \ 152 | 0x25, 0x0a, /* LOGICAL_MAXIMUM (10) */ \ 153 | 0x81, 0x06, /* INPUT (Data,Var,Rel) */ \ 154 | 0xc0, /* END_COLLECTION */ \ 155 | 0xc0, /*END_COLLECTION */ 156 | // 157 | // This is the default report descriptor for the Hid device provided 158 | // by the mini driver in response to IOCTL_HID_GET_REPORT_DESCRIPTOR. 159 | // 160 | 161 | typedef UCHAR HID_REPORT_DESCRIPTOR, *PHID_REPORT_DESCRIPTOR; 162 | 163 | #ifdef DESCRIPTOR_DEF 164 | HID_REPORT_DESCRIPTOR DefaultReportDescriptor[] = { 165 | // 166 | // Multitouch report starts here 167 | // 168 | //TOUCH PAD input TLC 169 | 0x05, 0x0d, // USAGE_PAGE (Digitizers) 170 | 0x09, 0x05, // USAGE (Touch Pad) 171 | 0xa1, 0x01, // COLLECTION (Application) 172 | 0x85, REPORTID_MTOUCH, // REPORT_ID (Touch pad) 173 | 0x09, 0x22, // USAGE (Finger) 174 | MT_REF_TOUCH_COLLECTION 175 | MT_REF_TOUCH_COLLECTION 176 | MT_REF_TOUCH_COLLECTION 177 | MT_REF_TOUCH_COLLECTION 178 | MT_REF_TOUCH_COLLECTION 179 | USAGE_PAGES 180 | }; 181 | 182 | 183 | // 184 | // This is the default HID descriptor returned by the mini driver 185 | // in response to IOCTL_HID_GET_DEVICE_DESCRIPTOR. The size 186 | // of report descriptor is currently the size of DefaultReportDescriptor. 187 | // 188 | 189 | CONST HID_DESCRIPTOR DefaultHidDescriptor = { 190 | 0x09, // length of HID descriptor 191 | 0x21, // descriptor type == HID 0x21 192 | 0x0100, // hid spec release 193 | 0x00, // country code == Not Specified 194 | 0x01, // number of HID class descriptors 195 | { 0x22, // descriptor type 196 | sizeof(DefaultReportDescriptor) } // total length of report descriptor 197 | }; 198 | #endif 199 | 200 | #define true 1 201 | #define false 0 202 | 203 | #define CrosTpSig 'ptyC' 204 | 205 | typedef enum { 206 | CrosTpCallbackSourceTouchpad = 0, 207 | CrosTpCallbackSourceInterrupt = 1 208 | } CrosTpCallbackSource; 209 | 210 | typedef enum { 211 | CrosTPCallbackActionRegister = 0, 212 | CrosTPCallbackActionUnregister = 1 213 | } CrosTPCallbackAction; 214 | 215 | typedef BOOLEAN(*CrosTPInt_Callback)(PVOID devContext); 216 | 217 | typedef struct _CROSTPCALLBACK_PKT 218 | { 219 | UINT32 signature; 220 | 221 | CrosTPCallbackAction action; 222 | CrosTpCallbackSource actionSource; 223 | NTSTATUS actionStatus; 224 | 225 | union { 226 | struct { 227 | PVOID devContext; 228 | CrosTPInt_Callback callbackFunction; 229 | } registrationParameters; 230 | } actionParameters; 231 | } CROSTPCALLBACK_PKT, * PCROSTPCALLBACK_PKT; 232 | 233 | struct _CYAPA_CONTEXT; 234 | 235 | typedef BOOLEAN(*SMBUS_INTERNAL_CALLBACK)(struct _CYAPA_CONTEXT* pDevice, uint8_t status); 236 | typedef void (*SMBUS_USER_CALLBACK)(struct _CYAPA_CONTEXT* pDevice, BOOLEAN success, void *readbuf, int readlen, PVOID userArg); 237 | 238 | 239 | typedef struct _CYAPA_CONTEXT 240 | { 241 | 242 | // 243 | // Handle back to the WDFDEVICE 244 | // 245 | 246 | WDFDEVICE FxDevice; 247 | 248 | BUS_INTERFACE_STANDARD BusInterface; 249 | 250 | WDFQUEUE ReportQueue; 251 | 252 | BOOLEAN SMBusLocked; 253 | unsigned short SMBusBase; 254 | ULONG SMBusLen; 255 | 256 | SMBUS_INTERNAL_CALLBACK SMBusInternalCallback; 257 | 258 | uint8_t *SMBusBlockWriteBuf; 259 | uint8_t SMBusBlockWriteIdx; 260 | uint8_t SMBusBlockWriteLen; 261 | 262 | SMBUS_USER_CALLBACK SMBusUserCallback; 263 | PVOID SMBusUserCallbackArg; 264 | 265 | BOOLEAN TrackpadIsBooted; 266 | 267 | uint8_t SMBusHostc; 268 | 269 | BYTE DeviceMode; 270 | 271 | WDFINTERRUPT Interrupt; 272 | 273 | PCALLBACK_OBJECT CrosTpIntCallback; 274 | PVOID CrosTpCallbackObj; 275 | CROSTPCALLBACK_PKT CrosTpCallbackTempContext; 276 | 277 | BOOLEAN ConnectInterrupt; 278 | 279 | BOOLEAN InterruptRaised; 280 | 281 | BOOLEAN RegsSet; 282 | 283 | uint8_t Flags[15]; 284 | 285 | USHORT XValue[15]; 286 | 287 | USHORT YValue[15]; 288 | 289 | USHORT PValue[15]; 290 | 291 | uint8_t buttonCap; 292 | 293 | BYTE BUTTONSPRESSED; 294 | 295 | USHORT TIMEINT; 296 | 297 | LARGE_INTEGER LastTime; 298 | 299 | uint16_t max_x; 300 | uint16_t max_y; 301 | 302 | uint8_t max_x_hid[2]; 303 | uint8_t max_y_hid[2]; 304 | 305 | uint16_t phy_x; 306 | uint16_t phy_y; 307 | 308 | uint8_t phy_x_hid[2]; 309 | uint8_t phy_y_hid[2]; 310 | 311 | WDFREQUEST lastRequest; 312 | 313 | } CYAPA_CONTEXT, *PCYAPA_CONTEXT; 314 | 315 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CYAPA_CONTEXT, GetDeviceContext) 316 | 317 | // 318 | // Function definitions 319 | // 320 | 321 | DRIVER_INITIALIZE DriverEntry; 322 | 323 | EVT_WDF_DRIVER_UNLOAD CyapaDriverUnload; 324 | 325 | EVT_WDF_DRIVER_DEVICE_ADD CyapaEvtDeviceAdd; 326 | 327 | EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL CyapaEvtInternalDeviceControl; 328 | 329 | NTSTATUS 330 | CyapaGetHidDescriptor( 331 | IN WDFDEVICE Device, 332 | IN WDFREQUEST Request 333 | ); 334 | 335 | NTSTATUS 336 | CyapaGetReportDescriptor( 337 | IN WDFDEVICE Device, 338 | IN WDFREQUEST Request, 339 | IN BOOLEAN Retried, 340 | OUT BOOLEAN* CompleteRequest 341 | ); 342 | 343 | NTSTATUS 344 | CyapaGetDeviceAttributes( 345 | IN WDFREQUEST Request 346 | ); 347 | 348 | NTSTATUS 349 | CyapaGetString( 350 | IN WDFREQUEST Request 351 | ); 352 | 353 | NTSTATUS 354 | CyapaWriteReport( 355 | IN PCYAPA_CONTEXT DevContext, 356 | IN WDFREQUEST Request 357 | ); 358 | 359 | NTSTATUS 360 | CyapaProcessVendorReport( 361 | IN PCYAPA_CONTEXT DevContext, 362 | IN PVOID ReportBuffer, 363 | IN ULONG ReportBufferLen, 364 | OUT size_t* BytesWritten 365 | ); 366 | 367 | NTSTATUS 368 | CyapaReadReport( 369 | IN PCYAPA_CONTEXT DevContext, 370 | IN WDFREQUEST Request, 371 | OUT BOOLEAN* CompleteRequest 372 | ); 373 | 374 | NTSTATUS 375 | CyapaSetFeature( 376 | IN PCYAPA_CONTEXT DevContext, 377 | IN WDFREQUEST Request, 378 | OUT BOOLEAN* CompleteRequest 379 | ); 380 | 381 | NTSTATUS 382 | CyapaGetFeature( 383 | IN PCYAPA_CONTEXT DevContext, 384 | IN WDFREQUEST Request, 385 | OUT BOOLEAN* CompleteRequest 386 | ); 387 | 388 | PCHAR 389 | DbgHidInternalIoctlString( 390 | IN ULONG IoControlCode 391 | ); 392 | 393 | // 394 | // Helper macros 395 | // 396 | 397 | #define DEBUG_LEVEL_ERROR 1 398 | #define DEBUG_LEVEL_INFO 2 399 | #define DEBUG_LEVEL_VERBOSE 3 400 | 401 | #define DBG_INIT 1 402 | #define DBG_PNP 2 403 | #define DBG_IOCTL 4 404 | 405 | #if 0 406 | #define CyapaPrint(dbglevel, dbgcatagory, fmt, ...) { \ 407 | if (CyapaDebugLevel >= dbglevel && \ 408 | (CyapaDebugCatagories && dbgcatagory)) \ 409 | { \ 410 | DbgPrint(DRIVERNAME); \ 411 | DbgPrint(fmt, __VA_ARGS__); \ 412 | } \ 413 | } 414 | #else 415 | #define CyapaPrint(dbglevel, fmt, ...) { \ 416 | } 417 | #endif 418 | 419 | #endif 420 | -------------------------------------------------------------------------------- /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 | true 306 | trace.h 307 | true 308 | false 309 | 310 | 311 | 4.1.3 312 | 313 | 314 | 315 | 316 | true 317 | trace.h 318 | true 319 | false 320 | 321 | 322 | 4.1.3 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /crostpint/crostpint/crostpint.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 | crostpint 61 | 10.0.22000.0 62 | crostpint 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 | 207 | 208 | 209 | 210 | true 211 | trace.h 212 | true 213 | false 214 | 215 | 216 | 4.1.3 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | true 226 | trace.h 227 | true 228 | false 229 | 230 | 231 | 4.1.3 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | true 241 | trace.h 242 | true 243 | false 244 | 245 | 246 | 4.1.3 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | true 256 | trace.h 257 | true 258 | false 259 | 260 | 261 | 4.1.3 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | true 271 | trace.h 272 | true 273 | false 274 | 275 | 276 | 4.1.3 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | true 286 | trace.h 287 | true 288 | false 289 | 290 | 291 | 4.1.3 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | true 301 | trace.h 302 | true 303 | false 304 | 305 | 306 | 4.1.3 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | true 316 | trace.h 317 | true 318 | false 319 | 320 | 321 | 4.1.3 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | true 331 | trace.h 332 | true 333 | false 334 | 335 | 336 | 4.1.3 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | true 346 | trace.h 347 | true 348 | false 349 | 350 | 351 | 4.1.3 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | true 361 | trace.h 362 | true 363 | false 364 | 365 | 366 | 4.1.3 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | -------------------------------------------------------------------------------- /crostpint/crostpint Package/crostpint 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 | crostpint_Package 61 | 10.0.22000.0 62 | crostpint 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 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 | #include 4 | #include 5 | 6 | #define bool int 7 | 8 | static ULONG CyapaDebugLevel = 100; 9 | static ULONG CyapaDebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL; 10 | 11 | static bool deviceLoaded = false; 12 | 13 | static unsigned char inb_p(unsigned short int port) { 14 | unsigned char value = __inbyte(port); 15 | //DbgPrint("SMBus Read 0x%x: 0x%x\n", port, value); 16 | return value; 17 | } 18 | 19 | static void outb_p(unsigned char value, unsigned short int port) { 20 | //DbgPrint("SMBus Write 0x%x: 0x%x\n", port, value); 21 | __outbyte(port, value); 22 | } 23 | 24 | uint32_t cyapa_read_byte(PCYAPA_CONTEXT pDevice, uint8_t cmd, SMBUS_USER_CALLBACK callback, PVOID arg); 25 | uint32_t cyapa_write_byte(PCYAPA_CONTEXT pDevice, uint8_t cmd, uint8_t value, SMBUS_USER_CALLBACK callback, PVOID arg); 26 | uint32_t cyapa_read_block(PCYAPA_CONTEXT pDevice, uint8_t cmd, SMBUS_USER_CALLBACK callback, PVOID arg); 27 | uint8_t cyapa_write_block(PCYAPA_CONTEXT pDevice, uint8_t cmd, uint8_t *buf, uint8_t len, SMBUS_USER_CALLBACK callback, PVOID arg); 28 | 29 | static int sqr(int num) { 30 | return num * num; 31 | } 32 | 33 | static int diffsig(int x, int y, int lastx, int lasty) { 34 | uint32_t distsq = sqr(x - lastx) + sqr(y - lasty); 35 | if (distsq < 4) 36 | return 0; 37 | return 1; 38 | } 39 | 40 | NTSTATUS 41 | DriverEntry( 42 | __in PDRIVER_OBJECT DriverObject, 43 | __in PUNICODE_STRING RegistryPath 44 | ) 45 | { 46 | NTSTATUS status = STATUS_SUCCESS; 47 | WDF_DRIVER_CONFIG config; 48 | WDF_OBJECT_ATTRIBUTES attributes; 49 | 50 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_INIT, 51 | "Driver Entry\n"); 52 | 53 | WDF_DRIVER_CONFIG_INIT(&config, CyapaEvtDeviceAdd); 54 | 55 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 56 | 57 | // 58 | // Create a framework driver object to represent our driver. 59 | // 60 | 61 | status = WdfDriverCreate(DriverObject, 62 | RegistryPath, 63 | &attributes, 64 | &config, 65 | WDF_NO_HANDLE 66 | ); 67 | 68 | if (!NT_SUCCESS(status)) 69 | { 70 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_INIT, 71 | "WdfDriverCreate failed with status 0x%x\n", status); 72 | } 73 | 74 | return status; 75 | } 76 | 77 | VOID cyapa_set_full_power( 78 | IN PCYAPA_CONTEXT pDevice, 79 | BOOLEAN success, 80 | void* readbuf, 81 | int readlen, 82 | PVOID userArg 83 | ) { 84 | UNREFERENCED_PARAMETER(userArg); 85 | 86 | if (!success || readlen != 1) { 87 | return; 88 | } 89 | 90 | uint8_t power_mode = CMD_POWER_MODE_FULL; 91 | 92 | //DbgPrint("Read Power Mode: 0x%x\n", power); 93 | 94 | uint8_t power = ((uint8_t *)readbuf)[0]; 95 | power = (power & ~0xFC); 96 | power |= power_mode & 0xFc; 97 | 98 | cyapa_write_byte(pDevice, SMBUS_ENCODE_RW(CYAPA_SMBUS_POWER_MODE, SMBUS_WRITE), power, NULL, NULL); 99 | } 100 | 101 | VOID CyapaReadCapabilities( 102 | IN PCYAPA_CONTEXT pDevice, 103 | BOOLEAN success, 104 | void* readbuf, 105 | int readlen, 106 | PVOID userArg 107 | ) { 108 | UNREFERENCED_PARAMETER(userArg); 109 | 110 | if (!success || readlen < sizeof(struct cyapa_cap)) { 111 | return; 112 | } 113 | 114 | struct cyapa_cap* cap = (struct cyapa_cap*)readbuf; 115 | if (strncmp((const char*)cap->prod_ida, "CYTRA", 5) != 0) { 116 | DbgPrint("[cyapainit] Product ID \"%5.5s\" mismatch\n", 117 | cap->prod_ida); 118 | } 119 | 120 | pDevice->max_x = ((cap->max_abs_xy_high << 4) & 0x0F00) | 121 | cap->max_abs_x_low; 122 | pDevice->max_y = ((cap->max_abs_xy_high << 8) & 0x0F00) | 123 | cap->max_abs_y_low; 124 | 125 | pDevice->phy_x = ((cap->phy_siz_xy_high << 4) & 0x0F00) | 126 | cap->phy_siz_x_low; 127 | pDevice->phy_y = ((cap->phy_siz_xy_high << 8) & 0x0F00) | 128 | cap->phy_siz_y_low; 129 | 130 | DbgPrint("[cyapainit] %5.5s-%6.6s-%2.2s buttons=%c%c%c res=%dx%d\n", 131 | cap->prod_ida, cap->prod_idb, cap->prod_idc, 132 | ((cap->buttons & CYAPA_FNGR_LEFT) ? 'L' : '-'), 133 | ((cap->buttons & CYAPA_FNGR_MIDDLE) ? 'M' : '-'), 134 | ((cap->buttons & CYAPA_FNGR_RIGHT) ? 'R' : '-'), 135 | pDevice->max_x, 136 | pDevice->max_y); 137 | 138 | pDevice->buttonCap = cap->buttons; 139 | 140 | DbgPrint("Max X: %d Y: %d Phys X: %d Y: %d\n", pDevice->max_x, pDevice->max_y, pDevice->phy_x, pDevice->phy_y); 141 | 142 | uint16_t max_x[] = { pDevice->max_x }; 143 | uint16_t max_y[] = { pDevice->max_y }; 144 | 145 | uint8_t* max_x8bit = (uint8_t*)max_x; 146 | uint8_t* max_y8bit = (uint8_t*)max_y; 147 | 148 | pDevice->max_x_hid[0] = max_x8bit[0]; 149 | pDevice->max_x_hid[1] = max_x8bit[1]; 150 | 151 | pDevice->max_y_hid[0] = max_y8bit[0]; 152 | pDevice->max_y_hid[1] = max_y8bit[1]; 153 | 154 | 155 | uint16_t phy_x[] = { pDevice->phy_x * 10 }; 156 | uint16_t phy_y[] = { pDevice->phy_y * 10 }; 157 | 158 | uint8_t* phy_x8bit = (uint8_t*)phy_x; 159 | uint8_t* phy_y8bit = (uint8_t*)phy_y; 160 | 161 | pDevice->phy_x_hid[0] = phy_x8bit[0]; 162 | pDevice->phy_x_hid[1] = phy_x8bit[1]; 163 | 164 | pDevice->phy_y_hid[0] = phy_y8bit[0]; 165 | pDevice->phy_y_hid[1] = phy_y8bit[1]; 166 | 167 | cyapa_read_byte(pDevice, SMBUS_ENCODE_RW(CYAPA_SMBUS_POWER_MODE, SMBUS_READ), cyapa_set_full_power, NULL); //read power mode 168 | 169 | pDevice->TrackpadIsBooted = TRUE; 170 | } 171 | 172 | VOID 173 | CyapaBootWorkItem( 174 | IN WDFWORKITEM WorkItem 175 | ) 176 | { 177 | WDFDEVICE Device = (WDFDEVICE)WdfWorkItemGetParentObject(WorkItem); 178 | PCYAPA_CONTEXT pDevice = GetDeviceContext(Device); 179 | 180 | WdfObjectDelete(WorkItem); 181 | 182 | cyapa_read_block(pDevice, SMBUS_ENCODE_RW(CYAPA_SMBUS_GROUP_QUERY, SMBUS_READ), CyapaReadCapabilities, NULL); 183 | } 184 | 185 | void CyapaBootTimer(_In_ WDFTIMER hTimer) { 186 | WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer); 187 | 188 | WDF_OBJECT_ATTRIBUTES attributes; 189 | WDF_WORKITEM_CONFIG workitemConfig; 190 | WDFWORKITEM hWorkItem; 191 | 192 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 193 | WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, CYAPA_CONTEXT); 194 | attributes.ParentObject = Device; 195 | WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CyapaBootWorkItem); 196 | 197 | WdfWorkItemCreate(&workitemConfig, 198 | &attributes, 199 | &hWorkItem); 200 | 201 | WdfWorkItemEnqueue(hWorkItem); 202 | 203 | WdfTimerStop(hTimer, FALSE); 204 | } 205 | 206 | static char bl_exit[] = { 207 | 0x00, 0xff, 0xa5, 0x00, 0x01, 208 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; 209 | 210 | #define TPAD_BOOT_CHECK 0x10 211 | #define TPAD_BOOT_ATTEMPTS_MASK 0xF 212 | 213 | VOID BOOTTRACKPAD2( 214 | _In_ PCYAPA_CONTEXT pDevice, 215 | BOOLEAN success, 216 | void* readbuf, 217 | int readlen, 218 | int bootdata 219 | ) { 220 | bool bootchecked = bootdata & TPAD_BOOT_CHECK; 221 | bool booted = false; 222 | if (bootchecked) { 223 | DbgPrint("Checked boot... %d\n", success); 224 | if (success) { 225 | if (readlen >= sizeof(struct cyapa_boot_regs)) { 226 | struct cyapa_boot_regs* boot = readbuf; 227 | if (boot->stat & CYAPA_STAT_RUNNING) { 228 | booted = true; 229 | DbgPrint("Device is already running! No need to boot!\n"); 230 | } 231 | else { 232 | DbgPrint("Device needs to boot!\n"); 233 | if (boot->error & CYAPA_ERROR_BOOTLOADER) { 234 | DbgPrint("Device is errored in bootloader!\n"); 235 | } 236 | } 237 | } 238 | } 239 | } 240 | else { 241 | booted = success; 242 | } 243 | 244 | int attempts = bootdata & TPAD_BOOT_ATTEMPTS_MASK; 245 | if (booted || attempts == 2) { 246 | if (!success) { 247 | DbgPrint("Warning: Device won't function if not already booted!\n"); 248 | } 249 | 250 | WDF_TIMER_CONFIG timerConfig; 251 | WDFTIMER hTimer; 252 | WDF_OBJECT_ATTRIBUTES attributes; 253 | 254 | WDF_TIMER_CONFIG_INIT(&timerConfig, CyapaBootTimer); 255 | 256 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 257 | attributes.ParentObject = pDevice->FxDevice; 258 | WdfTimerCreate(&timerConfig, &attributes, &hTimer); 259 | 260 | WdfTimerStart(hTimer, WDF_REL_TIMEOUT_IN_MS(75)); 261 | } 262 | else if (attempts < 2) { 263 | attempts += 1; 264 | cyapa_write_block(pDevice, SMBUS_ENCODE_RW(0, SMBUS_WRITE), (uint8_t*)bl_exit, sizeof(bl_exit), (SMBUS_USER_CALLBACK)BOOTTRACKPAD2, (PVOID)attempts); 265 | } 266 | } 267 | 268 | NTSTATUS BOOTTRACKPAD( 269 | _In_ PCYAPA_CONTEXT pDevice 270 | ) 271 | { 272 | NTSTATUS status = 0; 273 | 274 | pDevice->TrackpadIsBooted = false; 275 | 276 | cyapa_read_block(pDevice, SMBUS_ENCODE_RW(CYAPA_SMBUS_BL_STATUS, SMBUS_READ), (SMBUS_USER_CALLBACK)BOOTTRACKPAD2, (PVOID)TPAD_BOOT_CHECK); 277 | 278 | return status; 279 | } 280 | 281 | VOID CyapaReadWriteCallback( 282 | IN PCYAPA_CONTEXT pDevice, 283 | BOOLEAN success, 284 | void* readbuf, 285 | int readlen, 286 | PVOID userArg 287 | ) { 288 | UNREFERENCED_PARAMETER(userArg); 289 | if (!success || readlen < sizeof(struct cyapa_regs)) { 290 | return; 291 | } 292 | //DbgPrint("Reading Multitouch Report!\n"); 293 | 294 | LARGE_INTEGER CurrentTime; 295 | 296 | KeQuerySystemTime(&CurrentTime); 297 | 298 | LARGE_INTEGER DIFF; 299 | 300 | DIFF.QuadPart = 0; 301 | 302 | if (pDevice->LastTime.QuadPart != 0) 303 | DIFF.QuadPart = (CurrentTime.QuadPart - pDevice->LastTime.QuadPart) / 1000; 304 | 305 | struct cyapa_regs* regs = (struct cyapa_regs*)readbuf; 306 | 307 | struct _CYAPA_MULTITOUCH_REPORT report; 308 | report.ReportID = REPORTID_MTOUCH; 309 | 310 | int nfingers; 311 | 312 | nfingers = CYAPA_FNGR_NUMFINGERS(regs->fngr); 313 | 314 | int x[15]; 315 | int y[15]; 316 | int p[15]; 317 | for (int i = 0; i < 15; i++) { 318 | x[i] = -1; 319 | y[i] = -1; 320 | p[i] = -1; 321 | } 322 | for (int i = 0; i < nfingers; i++) { 323 | int a = regs->touch[i].id; 324 | int rawx = CYAPA_TOUCH_X(regs, i); 325 | int rawy = CYAPA_TOUCH_Y(regs, i); 326 | int rawp = CYAPA_TOUCH_P(regs, i); 327 | x[a] = rawx; 328 | y[a] = rawy; 329 | p[a] = rawp; 330 | } 331 | for (int i = 0; i < 15; i++) { 332 | if (pDevice->Flags[i] == MXT_T9_DETECT && x[i] == -1) { 333 | pDevice->Flags[i] = MXT_T9_RELEASE; 334 | } 335 | if (x[i] != -1) { 336 | bool updateValues = false; 337 | 338 | if (pDevice->Flags[i] == 0 || pDevice->Flags[i] == MXT_T9_RELEASE) 339 | updateValues = true; 340 | 341 | pDevice->Flags[i] = MXT_T9_DETECT; 342 | 343 | //if (diffsig(x[i], y[i], pDevice->XValue[i], pDevice->YValue[i]) == 1) 344 | updateValues = true; 345 | 346 | if (updateValues) { 347 | pDevice->XValue[i] = (USHORT)x[i]; 348 | pDevice->YValue[i] = (USHORT)y[i]; 349 | pDevice->PValue[i] = (USHORT)p[i]; 350 | } 351 | } 352 | } 353 | 354 | uint8_t lbtnShift = 0; 355 | if (pDevice->buttonCap & CYAPA_FNGR_RIGHT) { 356 | lbtnShift = 1; 357 | } 358 | 359 | pDevice->BUTTONSPRESSED = 0; 360 | pDevice->BUTTONSPRESSED |= (((regs->fngr & OP_DATA_LEFT_BTN) != 0) << lbtnShift); 361 | pDevice->BUTTONSPRESSED |= (((regs->fngr & OP_DATA_RIGHT_BTN) != 0) << 2); 362 | 363 | pDevice->TIMEINT += (USHORT)DIFF.QuadPart; 364 | 365 | pDevice->LastTime = CurrentTime; 366 | 367 | BYTE count = 0, i = 0; 368 | while (count < 5 && i < 15) { 369 | if (pDevice->Flags[i] != 0) { 370 | report.Touch[count].ContactID = i; 371 | 372 | report.Touch[count].XValue = pDevice->XValue[i]; 373 | report.Touch[count].YValue = pDevice->YValue[i]; 374 | report.Touch[count].Pressure = pDevice->PValue[i]; 375 | 376 | uint8_t flags = pDevice->Flags[i]; 377 | if (flags & MXT_T9_DETECT) { 378 | report.Touch[count].Status = MULTI_CONFIDENCE_BIT | MULTI_TIPSWITCH_BIT; 379 | } 380 | else if (flags & MXT_T9_PRESS) { 381 | report.Touch[count].Status = MULTI_CONFIDENCE_BIT | MULTI_TIPSWITCH_BIT; 382 | } 383 | else if (flags & MXT_T9_RELEASE) { 384 | report.Touch[count].Status = MULTI_CONFIDENCE_BIT; 385 | pDevice->Flags[i] = 0; 386 | } 387 | else 388 | report.Touch[count].Status = 0; 389 | 390 | count++; 391 | } 392 | i++; 393 | } 394 | 395 | report.ScanTime = pDevice->TIMEINT; 396 | report.ButtonsPressed = pDevice->BUTTONSPRESSED; 397 | 398 | report.ContactCount = count; 399 | 400 | size_t bytesWritten; 401 | CyapaProcessVendorReport(pDevice, &report, sizeof(report), &bytesWritten); 402 | 403 | pDevice->RegsSet = true; 404 | } 405 | 406 | int CyapaArg2 = 1; 407 | 408 | BOOLEAN 409 | CyapaInterrupt( 410 | IN PCYAPA_CONTEXT pDevice 411 | ) { 412 | if (!pDevice) { 413 | return false; 414 | } 415 | 416 | if (!pDevice->ConnectInterrupt) { 417 | return false; 418 | } 419 | 420 | if (pDevice->max_x == 0) { 421 | return false; 422 | } 423 | 424 | if (!pDevice->TrackpadIsBooted) { 425 | return false; 426 | } 427 | 428 | cyapa_read_block(pDevice, SMBUS_ENCODE_RW(CYAPA_SMBUS_GROUP_DATA, SMBUS_READ), CyapaReadWriteCallback, NULL); 429 | return true; 430 | } 431 | 432 | VOID 433 | CyapaIntCallback( 434 | IN PCYAPA_CONTEXT pDevice, 435 | PCROSTPCALLBACK_PKT tpContext, 436 | PVOID Argument2 437 | ) { 438 | if (Argument2 == &CyapaArg2) { 439 | return; 440 | } 441 | 442 | if (!tpContext) { 443 | return; 444 | } 445 | 446 | if (tpContext->signature != CrosTpSig) { 447 | return; 448 | } 449 | 450 | if (tpContext->actionSource != CrosTpCallbackSourceInterrupt) { 451 | return; 452 | } 453 | 454 | switch (tpContext->action) { 455 | case CrosTPCallbackActionRegister: 456 | { 457 | tpContext->actionStatus = STATUS_SUCCESS; 458 | 459 | RtlZeroMemory(&pDevice->CrosTpCallbackTempContext, sizeof(CROSTPCALLBACK_PKT)); 460 | pDevice->CrosTpCallbackTempContext.signature = CrosTpSig; 461 | pDevice->CrosTpCallbackTempContext.action = CrosTPCallbackActionRegister; 462 | pDevice->CrosTpCallbackTempContext.actionSource = CrosTpCallbackSourceTouchpad; 463 | pDevice->CrosTpCallbackTempContext.actionParameters.registrationParameters.devContext = pDevice; 464 | pDevice->CrosTpCallbackTempContext.actionParameters.registrationParameters.callbackFunction = CyapaInterrupt; 465 | pDevice->CrosTpCallbackTempContext.actionStatus = STATUS_DEVICE_NOT_READY; 466 | ExNotifyCallback(pDevice->CrosTpIntCallback, &pDevice->CrosTpCallbackTempContext, &CyapaArg2); 467 | } 468 | case CrosTPCallbackActionUnregister: 469 | { 470 | tpContext->actionStatus = STATUS_SUCCESS; 471 | break; 472 | } 473 | default: 474 | break; 475 | } 476 | } 477 | 478 | NTSTATUS 479 | OnPrepareHardware( 480 | _In_ WDFDEVICE FxDevice, 481 | _In_ WDFCMRESLIST FxResourcesRaw, 482 | _In_ WDFCMRESLIST FxResourcesTranslated 483 | ) 484 | /*++ 485 | 486 | Routine Description: 487 | 488 | This routine caches the SPB resource connection ID. 489 | 490 | Arguments: 491 | 492 | FxDevice - a handle to the framework device object 493 | FxResourcesRaw - list of translated hardware resources that 494 | the PnP manager has assigned to the device 495 | FxResourcesTranslated - list of raw hardware resources that 496 | the PnP manager has assigned to the device 497 | 498 | Return Value: 499 | 500 | Status 501 | 502 | --*/ 503 | { 504 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice); 505 | NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES; 506 | 507 | UNREFERENCED_PARAMETER(FxResourcesRaw); 508 | 509 | // 510 | // Parse the peripheral's resources. 511 | // 512 | 513 | ULONG resourceCount = WdfCmResourceListGetCount(FxResourcesTranslated); 514 | 515 | for (ULONG i = 0; i < resourceCount; i++) 516 | { 517 | PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor; 518 | 519 | pDescriptor = WdfCmResourceListGetDescriptor( 520 | FxResourcesTranslated, i); 521 | 522 | switch (pDescriptor->Type) 523 | { 524 | case CmResourceTypePort: 525 | pDevice->SMBusBase = (unsigned short)pDescriptor->u.Port.Start.LowPart; 526 | pDevice->SMBusLen = pDescriptor->u.Port.Length; 527 | 528 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, "crostrackpad-smbus: Got IO Port 0x%x (len 0x%x)\n", pDevice->SMBusBase, pDevice->SMBusLen); 529 | 530 | status = STATUS_SUCCESS; 531 | break; 532 | default: 533 | // 534 | // Ignoring all other resource types. 535 | // 536 | break; 537 | } 538 | } 539 | 540 | UNICODE_STRING CrosTpSMBusInterrupt; 541 | RtlInitUnicodeString(&CrosTpSMBusInterrupt, L"\\CallBack\\CrosTpSMBusInterrupt"); 542 | 543 | OBJECT_ATTRIBUTES attributes; 544 | InitializeObjectAttributes(&attributes, 545 | &CrosTpSMBusInterrupt, 546 | OBJ_KERNEL_HANDLE | OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 547 | NULL, 548 | NULL 549 | ); 550 | 551 | status = ExCreateCallback(&pDevice->CrosTpIntCallback, &attributes, TRUE, TRUE); 552 | if (!NT_SUCCESS(status)) { 553 | 554 | return status; 555 | } 556 | pDevice->CrosTpCallbackObj = ExRegisterCallback(pDevice->CrosTpIntCallback, 557 | CyapaIntCallback, 558 | pDevice 559 | ); 560 | if (!pDevice->CrosTpCallbackObj) { 561 | 562 | return STATUS_NO_CALLBACK_ACTIVE; 563 | } 564 | 565 | RtlZeroMemory(&pDevice->CrosTpCallbackTempContext, sizeof(CROSTPCALLBACK_PKT)); 566 | pDevice->CrosTpCallbackTempContext.signature = CrosTpSig; 567 | pDevice->CrosTpCallbackTempContext.action = CrosTPCallbackActionRegister; 568 | pDevice->CrosTpCallbackTempContext.actionSource = CrosTpCallbackSourceTouchpad; 569 | pDevice->CrosTpCallbackTempContext.actionParameters.registrationParameters.devContext = pDevice; 570 | pDevice->CrosTpCallbackTempContext.actionParameters.registrationParameters.callbackFunction = CyapaInterrupt; 571 | pDevice->CrosTpCallbackTempContext.actionStatus = STATUS_DEVICE_NOT_READY; 572 | ExNotifyCallback(pDevice->CrosTpIntCallback, &pDevice->CrosTpCallbackTempContext, &CyapaArg2); 573 | 574 | pDevice->SMBusLocked = false; 575 | pDevice->SMBusUserCallback = NULL; 576 | pDevice->SMBusInternalCallback = NULL; 577 | return status; 578 | } 579 | 580 | NTSTATUS 581 | OnReleaseHardware( 582 | _In_ WDFDEVICE FxDevice, 583 | _In_ WDFCMRESLIST FxResourcesTranslated 584 | ) 585 | /*++ 586 | 587 | Routine Description: 588 | 589 | Arguments: 590 | 591 | FxDevice - a handle to the framework device object 592 | FxResourcesTranslated - list of raw hardware resources that 593 | the PnP manager has assigned to the device 594 | 595 | Return Value: 596 | 597 | Status 598 | 599 | --*/ 600 | { 601 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice); 602 | NTSTATUS status = STATUS_SUCCESS; 603 | 604 | UNREFERENCED_PARAMETER(FxResourcesTranslated); 605 | 606 | if (pDevice->CrosTpCallbackObj) { 607 | RtlZeroMemory(&pDevice->CrosTpCallbackTempContext, sizeof(CROSTPCALLBACK_PKT)); 608 | pDevice->CrosTpCallbackTempContext.signature = CrosTpSig; 609 | pDevice->CrosTpCallbackTempContext.action = CrosTPCallbackActionUnregister; 610 | pDevice->CrosTpCallbackTempContext.actionSource = CrosTpCallbackSourceTouchpad; 611 | pDevice->CrosTpCallbackTempContext.actionStatus = STATUS_DEVICE_NOT_READY; 612 | ExNotifyCallback(pDevice->CrosTpIntCallback, &pDevice->CrosTpCallbackTempContext, &CyapaArg2); //Notify one last time before unregistration 613 | 614 | ExUnregisterCallback(pDevice->CrosTpCallbackObj); 615 | pDevice->CrosTpCallbackObj = NULL; 616 | } 617 | 618 | if (pDevice->CrosTpIntCallback) { 619 | ObDereferenceObject(pDevice->CrosTpIntCallback); 620 | pDevice->CrosTpIntCallback = NULL; 621 | } 622 | 623 | return status; 624 | } 625 | 626 | NTSTATUS 627 | OnD0Entry( 628 | _In_ WDFDEVICE FxDevice, 629 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 630 | ) 631 | /*++ 632 | 633 | Routine Description: 634 | 635 | This routine allocates objects needed by the driver. 636 | 637 | Arguments: 638 | 639 | FxDevice - a handle to the framework device object 640 | FxPreviousState - previous power state 641 | 642 | Return Value: 643 | 644 | Status 645 | 646 | --*/ 647 | { 648 | UNREFERENCED_PARAMETER(FxPreviousState); 649 | 650 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice); 651 | NTSTATUS status = STATUS_SUCCESS; 652 | 653 | for (int i = 0; i < 15; i++){ 654 | pDevice->Flags[i] = 0; 655 | } 656 | 657 | pDevice->TrackpadIsBooted = false; 658 | 659 | BOOTTRACKPAD(pDevice); 660 | 661 | pDevice->RegsSet = false; 662 | pDevice->ConnectInterrupt = true; 663 | 664 | return status; 665 | } 666 | 667 | NTSTATUS 668 | OnD0Exit( 669 | _In_ WDFDEVICE FxDevice, 670 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 671 | ) 672 | /*++ 673 | 674 | Routine Description: 675 | 676 | This routine destroys objects needed by the driver. 677 | 678 | Arguments: 679 | 680 | FxDevice - a handle to the framework device object 681 | FxPreviousState - previous power state 682 | 683 | Return Value: 684 | 685 | Status 686 | 687 | --*/ 688 | { 689 | UNREFERENCED_PARAMETER(FxPreviousState); 690 | 691 | PCYAPA_CONTEXT pDevice = GetDeviceContext(FxDevice); 692 | 693 | pDevice->ConnectInterrupt = false; 694 | 695 | /* Clear special mode bits */ 696 | outb_p(inb_p(SMBAUXCTL(pDevice)) & 697 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(pDevice)); 698 | 699 | return STATUS_SUCCESS; 700 | } 701 | 702 | BOOLEAN OnInterruptIsr( 703 | WDFINTERRUPT Interrupt, 704 | ULONG MessageID) { 705 | UNREFERENCED_PARAMETER(MessageID); 706 | 707 | WDFDEVICE Device = WdfInterruptGetDevice(Interrupt); 708 | PCYAPA_CONTEXT pDevice = GetDeviceContext(Device); 709 | 710 | if (!pDevice->ConnectInterrupt) 711 | return false; 712 | 713 | if (!pDevice->SMBusLocked) 714 | return false; 715 | 716 | if (pDevice->SMBusInternalCallback == NULL) 717 | return false; 718 | 719 | //DbgPrint("SMBus Interrupt Raised!\n"); 720 | pDevice->InterruptRaised = true; 721 | 722 | uint8_t status = inb_p(SMBHSTSTS(pDevice)); 723 | 724 | if (pDevice->SMBusInternalCallback) { 725 | SMBUS_INTERNAL_CALLBACK callback = pDevice->SMBusInternalCallback; 726 | pDevice->SMBusInternalCallback = NULL; 727 | 728 | BOOLEAN ret = callback(pDevice, status); 729 | if (ret) { 730 | return ret; 731 | } 732 | else { 733 | status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; 734 | if (status) { 735 | outb_p(status, SMBHSTSTS(pDevice)); 736 | } 737 | return true; 738 | } 739 | } 740 | else { 741 | DbgPrint("Warning: No Internal Callback... Spurious interrupt?\n"); 742 | } 743 | 744 | status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; 745 | if (status) { 746 | outb_p(status, SMBHSTSTS(pDevice)); 747 | } 748 | 749 | return true; 750 | } 751 | 752 | NTSTATUS 753 | CyapaEvtDeviceAdd( 754 | IN WDFDRIVER Driver, 755 | IN PWDFDEVICE_INIT DeviceInit 756 | ) 757 | { 758 | NTSTATUS status = STATUS_SUCCESS; 759 | WDF_IO_QUEUE_CONFIG queueConfig; 760 | WDF_OBJECT_ATTRIBUTES attributes; 761 | WDFDEVICE device; 762 | WDF_INTERRUPT_CONFIG interruptConfig; 763 | WDFQUEUE queue; 764 | PCYAPA_CONTEXT devContext; 765 | 766 | UNREFERENCED_PARAMETER(Driver); 767 | 768 | PAGED_CODE(); 769 | 770 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_PNP, 771 | "CyapaEvtDeviceAdd called\n"); 772 | 773 | // 774 | // Tell framework this is a filter driver. Filter drivers by default are 775 | // not power policy owners. This works well for this driver because 776 | // HIDclass driver is the power policy owner for HID minidrivers. 777 | // 778 | 779 | WdfFdoInitSetFilter(DeviceInit); 780 | 781 | { 782 | WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; 783 | WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); 784 | 785 | pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware; 786 | pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware; 787 | pnpCallbacks.EvtDeviceD0Entry = OnD0Entry; 788 | pnpCallbacks.EvtDeviceD0Exit = OnD0Exit; 789 | 790 | WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks); 791 | } 792 | 793 | // 794 | // Setup the device context 795 | // 796 | 797 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CYAPA_CONTEXT); 798 | 799 | // 800 | // Create a framework device object.This call will in turn create 801 | // a WDM device object, attach to the lower stack, and set the 802 | // appropriate flags and attributes. 803 | // 804 | 805 | status = WdfDeviceCreate(&DeviceInit, &attributes, &device); 806 | 807 | if (!NT_SUCCESS(status)) 808 | { 809 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 810 | "WdfDeviceCreate failed with status code 0x%x\n", status); 811 | 812 | return status; 813 | } 814 | 815 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel); 816 | 817 | queueConfig.EvtIoInternalDeviceControl = CyapaEvtInternalDeviceControl; 818 | 819 | status = WdfIoQueueCreate(device, 820 | &queueConfig, 821 | WDF_NO_OBJECT_ATTRIBUTES, 822 | &queue 823 | ); 824 | 825 | if (!NT_SUCCESS(status)) 826 | { 827 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 828 | "WdfIoQueueCreate failed 0x%x\n", status); 829 | 830 | return status; 831 | } 832 | 833 | // 834 | // Create manual I/O queue to take care of hid report read requests 835 | // 836 | 837 | devContext = GetDeviceContext(device); 838 | 839 | WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual); 840 | 841 | queueConfig.PowerManaged = WdfFalse; 842 | 843 | status = WdfIoQueueCreate(device, 844 | &queueConfig, 845 | WDF_NO_OBJECT_ATTRIBUTES, 846 | &devContext->ReportQueue 847 | ); 848 | 849 | if (!NT_SUCCESS(status)) 850 | { 851 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 852 | "WdfIoQueueCreate failed 0x%x\n", status); 853 | 854 | return status; 855 | } 856 | 857 | // 858 | // Create an interrupt object for hardware notifications 859 | // 860 | WDF_INTERRUPT_CONFIG_INIT( 861 | &interruptConfig, 862 | OnInterruptIsr, 863 | NULL); 864 | interruptConfig.PassiveHandling = TRUE; 865 | 866 | status = WdfInterruptCreate( 867 | device, 868 | &interruptConfig, 869 | WDF_NO_OBJECT_ATTRIBUTES, 870 | &devContext->Interrupt); 871 | 872 | if (!NT_SUCCESS(status)) 873 | { 874 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 875 | "Error creating WDF interrupt object - %!STATUS!", 876 | status); 877 | 878 | return status; 879 | } 880 | 881 | // 882 | // Initialize DeviceMode 883 | // 884 | 885 | devContext->DeviceMode = DEVICE_MODE_MOUSE; 886 | devContext->FxDevice = device; 887 | 888 | return status; 889 | } 890 | 891 | VOID 892 | CyapaEvtInternalDeviceControl( 893 | IN WDFQUEUE Queue, 894 | IN WDFREQUEST Request, 895 | IN size_t OutputBufferLength, 896 | IN size_t InputBufferLength, 897 | IN ULONG IoControlCode 898 | ) 899 | { 900 | NTSTATUS status = STATUS_SUCCESS; 901 | WDFDEVICE device; 902 | PCYAPA_CONTEXT devContext; 903 | BOOLEAN completeRequest = TRUE; 904 | 905 | UNREFERENCED_PARAMETER(OutputBufferLength); 906 | UNREFERENCED_PARAMETER(InputBufferLength); 907 | 908 | device = WdfIoQueueGetDevice(Queue); 909 | devContext = GetDeviceContext(device); 910 | 911 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 912 | "%s, Queue:0x%p, Request:0x%p\n", 913 | DbgHidInternalIoctlString(IoControlCode), 914 | Queue, 915 | Request 916 | ); 917 | 918 | // 919 | // Please note that HIDCLASS provides the buffer in the Irp->UserBuffer 920 | // field irrespective of the ioctl buffer type. However, framework is very 921 | // strict about type checking. You cannot get Irp->UserBuffer by using 922 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER 923 | // internal ioctl. So depending on the ioctl code, we will either 924 | // use retreive function or escape to WDM to get the UserBuffer. 925 | // 926 | 927 | switch (IoControlCode) 928 | { 929 | 930 | case IOCTL_HID_GET_DEVICE_DESCRIPTOR: 931 | // 932 | // Retrieves the device's HID descriptor. 933 | // 934 | status = CyapaGetHidDescriptor(device, Request); 935 | break; 936 | 937 | case IOCTL_HID_GET_DEVICE_ATTRIBUTES: 938 | // 939 | //Retrieves a device's attributes in a HID_DEVICE_ATTRIBUTES structure. 940 | // 941 | status = CyapaGetDeviceAttributes(Request); 942 | break; 943 | 944 | case IOCTL_HID_GET_REPORT_DESCRIPTOR: 945 | // 946 | //Obtains the report descriptor for the HID device. 947 | // 948 | status = CyapaGetReportDescriptor(device, Request, FALSE, &completeRequest); 949 | break; 950 | 951 | case IOCTL_HID_GET_STRING: 952 | // 953 | // Requests that the HID minidriver retrieve a human-readable string 954 | // for either the manufacturer ID, the product ID, or the serial number 955 | // from the string descriptor of the device. The minidriver must send 956 | // a Get String Descriptor request to the device, in order to retrieve 957 | // the string descriptor, then it must extract the string at the 958 | // appropriate index from the string descriptor and return it in the 959 | // output buffer indicated by the IRP. Before sending the Get String 960 | // Descriptor request, the minidriver must retrieve the appropriate 961 | // index for the manufacturer ID, the product ID or the serial number 962 | // from the device extension of a top level collection associated with 963 | // the device. 964 | // 965 | status = CyapaGetString(Request); 966 | break; 967 | 968 | case IOCTL_HID_WRITE_REPORT: 969 | case IOCTL_HID_SET_OUTPUT_REPORT: 970 | // 971 | //Transmits a class driver-supplied report to the device. 972 | // 973 | status = CyapaWriteReport(devContext, Request); 974 | break; 975 | 976 | case IOCTL_HID_READ_REPORT: 977 | case IOCTL_HID_GET_INPUT_REPORT: 978 | // 979 | // Returns a report from the device into a class driver-supplied buffer. 980 | // 981 | status = CyapaReadReport(devContext, Request, &completeRequest); 982 | break; 983 | 984 | case IOCTL_HID_SET_FEATURE: 985 | // 986 | // This sends a HID class feature report to a top-level collection of 987 | // a HID class device. 988 | // 989 | status = CyapaSetFeature(devContext, Request, &completeRequest); 990 | break; 991 | 992 | case IOCTL_HID_GET_FEATURE: 993 | // 994 | // returns a feature report associated with a top-level collection 995 | // 996 | status = CyapaGetFeature(devContext, Request, &completeRequest); 997 | break; 998 | 999 | case IOCTL_HID_ACTIVATE_DEVICE: 1000 | // 1001 | // Makes the device ready for I/O operations. 1002 | // 1003 | case IOCTL_HID_DEACTIVATE_DEVICE: 1004 | // 1005 | // Causes the device to cease operations and terminate all outstanding 1006 | // I/O requests. 1007 | // 1008 | default: 1009 | status = STATUS_NOT_SUPPORTED; 1010 | break; 1011 | } 1012 | 1013 | if (completeRequest) 1014 | { 1015 | WdfRequestComplete(Request, status); 1016 | 1017 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1018 | "%s completed, Queue:0x%p, Request:0x%p\n", 1019 | DbgHidInternalIoctlString(IoControlCode), 1020 | Queue, 1021 | Request 1022 | ); 1023 | } 1024 | else 1025 | { 1026 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1027 | "%s deferred, Queue:0x%p, Request:0x%p\n", 1028 | DbgHidInternalIoctlString(IoControlCode), 1029 | Queue, 1030 | Request 1031 | ); 1032 | } 1033 | 1034 | return; 1035 | } 1036 | 1037 | NTSTATUS 1038 | CyapaGetHidDescriptor( 1039 | IN WDFDEVICE Device, 1040 | IN WDFREQUEST Request 1041 | ) 1042 | { 1043 | NTSTATUS status = STATUS_SUCCESS; 1044 | size_t bytesToCopy = 0; 1045 | WDFMEMORY memory; 1046 | 1047 | UNREFERENCED_PARAMETER(Device); 1048 | 1049 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1050 | "CyapaGetHidDescriptor Entry\n"); 1051 | 1052 | // 1053 | // This IOCTL is METHOD_NEITHER so WdfRequestRetrieveOutputMemory 1054 | // will correctly retrieve buffer from Irp->UserBuffer. 1055 | // Remember that HIDCLASS provides the buffer in the Irp->UserBuffer 1056 | // field irrespective of the ioctl buffer type. However, framework is very 1057 | // strict about type checking. You cannot get Irp->UserBuffer by using 1058 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER 1059 | // internal ioctl. 1060 | // 1061 | status = WdfRequestRetrieveOutputMemory(Request, &memory); 1062 | 1063 | if (!NT_SUCCESS(status)) 1064 | { 1065 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1066 | "WdfRequestRetrieveOutputMemory failed 0x%x\n", status); 1067 | 1068 | return status; 1069 | } 1070 | 1071 | // 1072 | // Use hardcoded "HID Descriptor" 1073 | // 1074 | bytesToCopy = DefaultHidDescriptor.bLength; 1075 | 1076 | if (bytesToCopy == 0) 1077 | { 1078 | status = STATUS_INVALID_DEVICE_STATE; 1079 | 1080 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1081 | "DefaultHidDescriptor is zero, 0x%x\n", status); 1082 | 1083 | return status; 1084 | } 1085 | 1086 | status = WdfMemoryCopyFromBuffer(memory, 1087 | 0, // Offset 1088 | (PVOID)&DefaultHidDescriptor, 1089 | bytesToCopy); 1090 | 1091 | if (!NT_SUCCESS(status)) 1092 | { 1093 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1094 | "WdfMemoryCopyFromBuffer failed 0x%x\n", status); 1095 | 1096 | return status; 1097 | } 1098 | 1099 | // 1100 | // Report how many bytes were copied 1101 | // 1102 | WdfRequestSetInformation(Request, bytesToCopy); 1103 | 1104 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1105 | "CyapaGetHidDescriptor Exit = 0x%x\n", status); 1106 | 1107 | return status; 1108 | } 1109 | 1110 | void CyapaDescriptorTimer(_In_ WDFTIMER hTimer) { 1111 | WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer); 1112 | PCYAPA_CONTEXT pDevice = GetDeviceContext(Device); 1113 | 1114 | WdfRequestForwardToIoQueue(pDevice->lastRequest, pDevice->ReportQueue); 1115 | 1116 | pDevice->lastRequest = NULL; 1117 | 1118 | WdfTimerStop(hTimer, FALSE); 1119 | } 1120 | 1121 | NTSTATUS 1122 | CyapaGetReportDescriptor( 1123 | IN WDFDEVICE Device, 1124 | IN WDFREQUEST Request, 1125 | IN BOOLEAN Retried, 1126 | OUT BOOLEAN* CompleteRequest 1127 | ) 1128 | { 1129 | NTSTATUS status = STATUS_SUCCESS; 1130 | ULONG_PTR bytesToCopy; 1131 | WDFMEMORY memory; 1132 | 1133 | PCYAPA_CONTEXT devContext = GetDeviceContext(Device); 1134 | 1135 | if (devContext->max_x == 0) { 1136 | devContext->lastRequest = Request; 1137 | WDF_TIMER_CONFIG timerConfig; 1138 | WDFTIMER hTimer; 1139 | WDF_OBJECT_ATTRIBUTES attributes; 1140 | 1141 | WDF_TIMER_CONFIG_INIT(&timerConfig, CyapaDescriptorTimer); 1142 | 1143 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 1144 | attributes.ParentObject = Device; 1145 | status = WdfTimerCreate(&timerConfig, &attributes, &hTimer); 1146 | 1147 | WdfTimerStart(hTimer, WDF_REL_TIMEOUT_IN_MS(200)); 1148 | *CompleteRequest = FALSE; 1149 | } 1150 | 1151 | UNREFERENCED_PARAMETER(Device); 1152 | 1153 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1154 | "CyapaGetReportDescriptor Entry\n"); 1155 | 1156 | #define MT_TOUCH_COLLECTION \ 1157 | MT_TOUCH_COLLECTION0 \ 1158 | 0x26, devContext->max_x_hid[0], devContext->max_x_hid[1], /* LOGICAL_MAXIMUM (WIDTH) */ \ 1159 | 0x46, devContext->phy_x_hid[0], devContext->phy_x_hid[1], /* PHYSICAL_MAXIMUM (WIDTH) */ \ 1160 | MT_TOUCH_COLLECTION1 \ 1161 | 0x26, devContext->max_y_hid[0], devContext->max_y_hid[1], /* LOGICAL_MAXIMUM (HEIGHT) */ \ 1162 | 0x46, devContext->phy_y_hid[0], devContext->phy_y_hid[1], /* PHYSICAL_MAXIMUM (HEIGHT) */ \ 1163 | MT_TOUCH_COLLECTION2 1164 | 1165 | HID_REPORT_DESCRIPTOR ReportDescriptor[] = { 1166 | // 1167 | // Multitouch report starts here 1168 | // 1169 | //TOUCH PAD input TLC 1170 | 0x05, 0x0d, // USAGE_PAGE (Digitizers) 1171 | 0x09, 0x05, // USAGE (Touch Pad) 1172 | 0xa1, 0x01, // COLLECTION (Application) 1173 | 0x85, REPORTID_MTOUCH, // REPORT_ID (Touch pad) 1174 | 0x09, 0x22, // USAGE (Finger) 1175 | MT_TOUCH_COLLECTION 1176 | MT_TOUCH_COLLECTION 1177 | MT_TOUCH_COLLECTION 1178 | MT_TOUCH_COLLECTION 1179 | MT_TOUCH_COLLECTION 1180 | USAGE_PAGES 1181 | }; 1182 | 1183 | // 1184 | // This IOCTL is METHOD_NEITHER so WdfRequestRetrieveOutputMemory 1185 | // will correctly retrieve buffer from Irp->UserBuffer. 1186 | // Remember that HIDCLASS provides the buffer in the Irp->UserBuffer 1187 | // field irrespective of the ioctl buffer type. However, framework is very 1188 | // strict about type checking. You cannot get Irp->UserBuffer by using 1189 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER 1190 | // internal ioctl. 1191 | // 1192 | status = WdfRequestRetrieveOutputMemory(Request, &memory); 1193 | if (!NT_SUCCESS(status)) 1194 | { 1195 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1196 | "WdfRequestRetrieveOutputMemory failed 0x%x\n", status); 1197 | 1198 | return status; 1199 | } 1200 | 1201 | // 1202 | // Use hardcoded Report descriptor 1203 | // 1204 | bytesToCopy = DefaultHidDescriptor.DescriptorList[0].wReportLength; 1205 | 1206 | if (bytesToCopy == 0) 1207 | { 1208 | status = STATUS_INVALID_DEVICE_STATE; 1209 | 1210 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1211 | "DefaultHidDescriptor's reportLength is zero, 0x%x\n", status); 1212 | 1213 | return status; 1214 | } 1215 | 1216 | status = WdfMemoryCopyFromBuffer(memory, 1217 | 0, 1218 | (PVOID)ReportDescriptor, 1219 | bytesToCopy); 1220 | if (!NT_SUCCESS(status)) 1221 | { 1222 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1223 | "WdfMemoryCopyFromBuffer failed 0x%x\n", status); 1224 | 1225 | return status; 1226 | } 1227 | 1228 | // 1229 | // Report how many bytes were copied 1230 | // 1231 | WdfRequestSetInformation(Request, bytesToCopy); 1232 | 1233 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1234 | "CyapaGetReportDescriptor Exit = 0x%x\n", status); 1235 | 1236 | if (Retried) { 1237 | WdfRequestComplete(Request, status); 1238 | } 1239 | 1240 | return status; 1241 | } 1242 | 1243 | 1244 | NTSTATUS 1245 | CyapaGetDeviceAttributes( 1246 | IN WDFREQUEST Request 1247 | ) 1248 | { 1249 | NTSTATUS status = STATUS_SUCCESS; 1250 | PHID_DEVICE_ATTRIBUTES deviceAttributes = NULL; 1251 | 1252 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1253 | "CyapaGetDeviceAttributes Entry\n"); 1254 | 1255 | // 1256 | // This IOCTL is METHOD_NEITHER so WdfRequestRetrieveOutputMemory 1257 | // will correctly retrieve buffer from Irp->UserBuffer. 1258 | // Remember that HIDCLASS provides the buffer in the Irp->UserBuffer 1259 | // field irrespective of the ioctl buffer type. However, framework is very 1260 | // strict about type checking. You cannot get Irp->UserBuffer by using 1261 | // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER 1262 | // internal ioctl. 1263 | // 1264 | status = WdfRequestRetrieveOutputBuffer(Request, 1265 | sizeof(HID_DEVICE_ATTRIBUTES), 1266 | &deviceAttributes, 1267 | NULL); 1268 | if (!NT_SUCCESS(status)) 1269 | { 1270 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1271 | "WdfRequestRetrieveOutputBuffer failed 0x%x\n", status); 1272 | 1273 | return status; 1274 | } 1275 | 1276 | // 1277 | // Set USB device descriptor 1278 | // 1279 | 1280 | deviceAttributes->Size = sizeof(HID_DEVICE_ATTRIBUTES); 1281 | deviceAttributes->VendorID = CYAPA_VID; 1282 | deviceAttributes->ProductID = CYAPA_PID; 1283 | deviceAttributes->VersionNumber = CYAPA_VERSION; 1284 | 1285 | // 1286 | // Report how many bytes were copied 1287 | // 1288 | WdfRequestSetInformation(Request, sizeof(HID_DEVICE_ATTRIBUTES)); 1289 | 1290 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1291 | "CyapaGetDeviceAttributes Exit = 0x%x\n", status); 1292 | 1293 | return status; 1294 | } 1295 | 1296 | NTSTATUS 1297 | CyapaGetString( 1298 | IN WDFREQUEST Request 1299 | ) 1300 | { 1301 | 1302 | NTSTATUS status = STATUS_SUCCESS; 1303 | PWSTR pwstrID; 1304 | size_t lenID; 1305 | WDF_REQUEST_PARAMETERS params; 1306 | void *pStringBuffer = NULL; 1307 | 1308 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1309 | "CyapaGetString Entry\n"); 1310 | 1311 | WDF_REQUEST_PARAMETERS_INIT(¶ms); 1312 | WdfRequestGetParameters(Request, ¶ms); 1313 | 1314 | switch ((ULONG_PTR)params.Parameters.DeviceIoControl.Type3InputBuffer & 0xFFFF) 1315 | { 1316 | case HID_STRING_ID_IMANUFACTURER: 1317 | pwstrID = L"Cyapa.\0"; 1318 | break; 1319 | 1320 | case HID_STRING_ID_IPRODUCT: 1321 | pwstrID = L"MaxTouch Touch Screen\0"; 1322 | break; 1323 | 1324 | case HID_STRING_ID_ISERIALNUMBER: 1325 | pwstrID = L"123123123\0"; 1326 | break; 1327 | 1328 | default: 1329 | pwstrID = NULL; 1330 | break; 1331 | } 1332 | 1333 | lenID = pwstrID ? wcslen(pwstrID)*sizeof(WCHAR) + sizeof(UNICODE_NULL) : 0; 1334 | 1335 | if (pwstrID == NULL) 1336 | { 1337 | 1338 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1339 | "CyapaGetString Invalid request type\n"); 1340 | 1341 | status = STATUS_INVALID_PARAMETER; 1342 | 1343 | return status; 1344 | } 1345 | 1346 | status = WdfRequestRetrieveOutputBuffer(Request, 1347 | lenID, 1348 | &pStringBuffer, 1349 | &lenID); 1350 | 1351 | if (!NT_SUCCESS(status)) 1352 | { 1353 | 1354 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1355 | "CyapaGetString WdfRequestRetrieveOutputBuffer failed Status 0x%x\n", status); 1356 | 1357 | return status; 1358 | } 1359 | 1360 | RtlCopyMemory(pStringBuffer, pwstrID, lenID); 1361 | 1362 | WdfRequestSetInformation(Request, lenID); 1363 | 1364 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1365 | "CyapaGetString Exit = 0x%x\n", status); 1366 | 1367 | return status; 1368 | } 1369 | 1370 | NTSTATUS 1371 | CyapaWriteReport( 1372 | IN PCYAPA_CONTEXT DevContext, 1373 | IN WDFREQUEST Request 1374 | ) 1375 | { 1376 | UNREFERENCED_PARAMETER(DevContext); 1377 | 1378 | NTSTATUS status = STATUS_SUCCESS; 1379 | WDF_REQUEST_PARAMETERS params; 1380 | PHID_XFER_PACKET transferPacket = NULL; 1381 | 1382 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1383 | "CyapaWriteReport Entry\n"); 1384 | 1385 | WDF_REQUEST_PARAMETERS_INIT(¶ms); 1386 | WdfRequestGetParameters(Request, ¶ms); 1387 | 1388 | if (params.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET)) 1389 | { 1390 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1391 | "CyapaWriteReport Xfer packet too small\n"); 1392 | 1393 | status = STATUS_BUFFER_TOO_SMALL; 1394 | } 1395 | else 1396 | { 1397 | 1398 | transferPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer; 1399 | 1400 | if (transferPacket == NULL) 1401 | { 1402 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1403 | "CyapaWriteReport No xfer packet\n"); 1404 | 1405 | status = STATUS_INVALID_DEVICE_REQUEST; 1406 | } 1407 | else 1408 | { 1409 | // 1410 | // switch on the report id 1411 | // 1412 | 1413 | switch (transferPacket->reportId) 1414 | { 1415 | default: 1416 | 1417 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1418 | "CyapaWriteReport Unhandled report type %d\n", transferPacket->reportId); 1419 | 1420 | status = STATUS_INVALID_PARAMETER; 1421 | 1422 | break; 1423 | } 1424 | } 1425 | } 1426 | 1427 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1428 | "CyapaWriteReport Exit = 0x%x\n", status); 1429 | 1430 | return status; 1431 | 1432 | } 1433 | 1434 | NTSTATUS 1435 | CyapaProcessVendorReport( 1436 | IN PCYAPA_CONTEXT DevContext, 1437 | IN PVOID ReportBuffer, 1438 | IN ULONG ReportBufferLen, 1439 | OUT size_t* BytesWritten 1440 | ) 1441 | { 1442 | NTSTATUS status = STATUS_SUCCESS; 1443 | WDFREQUEST reqRead; 1444 | PVOID pReadReport = NULL; 1445 | size_t bytesReturned = 0; 1446 | 1447 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1448 | "CyapaProcessVendorReport Entry\n"); 1449 | 1450 | status = WdfIoQueueRetrieveNextRequest(DevContext->ReportQueue, 1451 | &reqRead); 1452 | 1453 | if (NT_SUCCESS(status)) 1454 | { 1455 | status = WdfRequestRetrieveOutputBuffer(reqRead, 1456 | ReportBufferLen, 1457 | &pReadReport, 1458 | &bytesReturned); 1459 | 1460 | if (NT_SUCCESS(status)) 1461 | { 1462 | // 1463 | // Copy ReportBuffer into read request 1464 | // 1465 | 1466 | if (bytesReturned > ReportBufferLen) 1467 | { 1468 | bytesReturned = ReportBufferLen; 1469 | } 1470 | 1471 | RtlCopyMemory(pReadReport, 1472 | ReportBuffer, 1473 | bytesReturned); 1474 | 1475 | // 1476 | // Complete read with the number of bytes returned as info 1477 | // 1478 | 1479 | WdfRequestCompleteWithInformation(reqRead, 1480 | status, 1481 | bytesReturned); 1482 | 1483 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1484 | "CyapaProcessVendorReport %d bytes returned\n", bytesReturned); 1485 | 1486 | // 1487 | // Return the number of bytes written for the write request completion 1488 | // 1489 | 1490 | *BytesWritten = bytesReturned; 1491 | 1492 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1493 | "%s completed, Queue:0x%p, Request:0x%p\n", 1494 | DbgHidInternalIoctlString(IOCTL_HID_READ_REPORT), 1495 | DevContext->ReportQueue, 1496 | reqRead); 1497 | } 1498 | else 1499 | { 1500 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1501 | "WdfRequestRetrieveOutputBuffer failed Status 0x%x\n", status); 1502 | } 1503 | } 1504 | else 1505 | { 1506 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1507 | "WdfIoQueueRetrieveNextRequest failed Status 0x%x\n", status); 1508 | } 1509 | 1510 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1511 | "CyapaProcessVendorReport Exit = 0x%x\n", status); 1512 | 1513 | return status; 1514 | } 1515 | 1516 | NTSTATUS 1517 | CyapaReadReport( 1518 | IN PCYAPA_CONTEXT DevContext, 1519 | IN WDFREQUEST Request, 1520 | OUT BOOLEAN* CompleteRequest 1521 | ) 1522 | { 1523 | NTSTATUS status = STATUS_SUCCESS; 1524 | 1525 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1526 | "CyapaReadReport Entry\n"); 1527 | 1528 | // 1529 | // Forward this read request to our manual queue 1530 | // (in other words, we are going to defer this request 1531 | // until we have a corresponding write request to 1532 | // match it with) 1533 | // 1534 | 1535 | status = WdfRequestForwardToIoQueue(Request, DevContext->ReportQueue); 1536 | 1537 | if (!NT_SUCCESS(status)) 1538 | { 1539 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1540 | "WdfRequestForwardToIoQueue failed Status 0x%x\n", status); 1541 | } 1542 | else 1543 | { 1544 | *CompleteRequest = FALSE; 1545 | } 1546 | 1547 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1548 | "CyapaReadReport Exit = 0x%x\n", status); 1549 | 1550 | return status; 1551 | } 1552 | 1553 | NTSTATUS 1554 | CyapaSetFeature( 1555 | IN PCYAPA_CONTEXT DevContext, 1556 | IN WDFREQUEST Request, 1557 | OUT BOOLEAN* CompleteRequest 1558 | ) 1559 | { 1560 | UNREFERENCED_PARAMETER(CompleteRequest); 1561 | 1562 | NTSTATUS status = STATUS_SUCCESS; 1563 | WDF_REQUEST_PARAMETERS params; 1564 | PHID_XFER_PACKET transferPacket = NULL; 1565 | CyapaFeatureReport* pReport = NULL; 1566 | 1567 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1568 | "CyapaSetFeature Entry\n"); 1569 | 1570 | WDF_REQUEST_PARAMETERS_INIT(¶ms); 1571 | WdfRequestGetParameters(Request, ¶ms); 1572 | 1573 | if (params.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET)) 1574 | { 1575 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1576 | "CyapaSetFeature Xfer packet too small\n"); 1577 | 1578 | status = STATUS_BUFFER_TOO_SMALL; 1579 | } 1580 | else 1581 | { 1582 | 1583 | transferPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer; 1584 | 1585 | if (transferPacket == NULL) 1586 | { 1587 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1588 | "CyapaWriteReport No xfer packet\n"); 1589 | 1590 | status = STATUS_INVALID_DEVICE_REQUEST; 1591 | } 1592 | else 1593 | { 1594 | // 1595 | // switch on the report id 1596 | // 1597 | 1598 | switch (transferPacket->reportId) 1599 | { 1600 | case REPORTID_FEATURE: 1601 | 1602 | if (transferPacket->reportBufferLen == sizeof(CyapaFeatureReport)) 1603 | { 1604 | pReport = (CyapaFeatureReport*)transferPacket->reportBuffer; 1605 | 1606 | DevContext->DeviceMode = pReport->DeviceMode; 1607 | 1608 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1609 | "CyapaSetFeature DeviceMode = 0x%x\n", DevContext->DeviceMode); 1610 | } 1611 | else 1612 | { 1613 | status = STATUS_INVALID_PARAMETER; 1614 | 1615 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1616 | "CyapaSetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(CyapaFeatureReport) (%d)\n", 1617 | transferPacket->reportBufferLen, 1618 | sizeof(CyapaFeatureReport)); 1619 | } 1620 | 1621 | break; 1622 | 1623 | default: 1624 | 1625 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1626 | "CyapaSetFeature Unhandled report type %d\n", transferPacket->reportId); 1627 | 1628 | status = STATUS_INVALID_PARAMETER; 1629 | 1630 | break; 1631 | } 1632 | } 1633 | } 1634 | 1635 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1636 | "CyapaSetFeature Exit = 0x%x\n", status); 1637 | 1638 | return status; 1639 | } 1640 | 1641 | NTSTATUS 1642 | CyapaGetFeature( 1643 | IN PCYAPA_CONTEXT DevContext, 1644 | IN WDFREQUEST Request, 1645 | OUT BOOLEAN* CompleteRequest 1646 | ) 1647 | { 1648 | UNREFERENCED_PARAMETER(CompleteRequest); 1649 | 1650 | NTSTATUS status = STATUS_SUCCESS; 1651 | WDF_REQUEST_PARAMETERS params; 1652 | PHID_XFER_PACKET transferPacket = NULL; 1653 | 1654 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1655 | "CyapaGetFeature Entry\n"); 1656 | 1657 | WDF_REQUEST_PARAMETERS_INIT(¶ms); 1658 | WdfRequestGetParameters(Request, ¶ms); 1659 | 1660 | if (params.Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_XFER_PACKET)) 1661 | { 1662 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1663 | "CyapaGetFeature Xfer packet too small\n"); 1664 | 1665 | status = STATUS_BUFFER_TOO_SMALL; 1666 | } 1667 | else 1668 | { 1669 | 1670 | transferPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer; 1671 | 1672 | if (transferPacket == NULL) 1673 | { 1674 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1675 | "CyapaGetFeature No xfer packet\n"); 1676 | 1677 | status = STATUS_INVALID_DEVICE_REQUEST; 1678 | } 1679 | else 1680 | { 1681 | // 1682 | // switch on the report id 1683 | // 1684 | 1685 | switch (transferPacket->reportId) 1686 | { 1687 | case REPORTID_MTOUCH: 1688 | { 1689 | 1690 | CyapaMaxCountReport* pReport = NULL; 1691 | 1692 | if (transferPacket->reportBufferLen >= sizeof(CyapaMaxCountReport)) 1693 | { 1694 | pReport = (CyapaMaxCountReport*)transferPacket->reportBuffer; 1695 | 1696 | pReport->MaximumCount = MULTI_MAX_COUNT; 1697 | 1698 | pReport->PadType = 0; 1699 | 1700 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1701 | "CyapaGetFeature MaximumCount = 0x%x\n", MULTI_MAX_COUNT); 1702 | } 1703 | else 1704 | { 1705 | status = STATUS_INVALID_PARAMETER; 1706 | 1707 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1708 | "CyapaGetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(CyapaMaxCountReport) (%d)\n", 1709 | transferPacket->reportBufferLen, 1710 | sizeof(CyapaMaxCountReport)); 1711 | } 1712 | 1713 | break; 1714 | } 1715 | 1716 | case REPORTID_FEATURE: 1717 | { 1718 | 1719 | CyapaFeatureReport* pReport = NULL; 1720 | 1721 | if (transferPacket->reportBufferLen >= sizeof(CyapaFeatureReport)) 1722 | { 1723 | pReport = (CyapaFeatureReport*)transferPacket->reportBuffer; 1724 | 1725 | pReport->DeviceMode = DevContext->DeviceMode; 1726 | 1727 | pReport->DeviceIdentifier = 0; 1728 | 1729 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1730 | "CyapaGetFeature DeviceMode = 0x%x\n", DevContext->DeviceMode); 1731 | } 1732 | else 1733 | { 1734 | status = STATUS_INVALID_PARAMETER; 1735 | 1736 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1737 | "CyapaGetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(CyapaFeatureReport) (%d)\n", 1738 | transferPacket->reportBufferLen, 1739 | sizeof(CyapaFeatureReport)); 1740 | } 1741 | 1742 | break; 1743 | } 1744 | 1745 | case REPORTID_PTPHQA: 1746 | { 1747 | uint8_t PTPHQA_BLOB[] = { REPORTID_PTPHQA, 0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, 0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, 0x07,\ 1748 | 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, 0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, 0x2e, 0x84,\ 1749 | 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, 0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, 0x47, 0x70, 0x1b,\ 1750 | 0x59, 0x6f, 0x74, 0x43, 0xc4, 0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, 0xc7, 0x95, 0x0e, 0x31,\ 1751 | 0x55, 0x21, 0xd3, 0xb5, 0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, 0x3e, 0xb3, 0xaf, 0x75, 0x81,\ 1752 | 0x9d, 0x53, 0xb9, 0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, 0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d,\ 1753 | 0xa7, 0x26, 0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, 0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0,\ 1754 | 0x2a, 0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, 0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, 0x0b,\ 1755 | 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, 0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, 0xe8, 0x8a,\ 1756 | 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, 0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, 0x2b, 0x53, 0x5c,\ 1757 | 0x69, 0x52, 0xd5, 0xc8, 0x73, 0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, 0x05, 0xd8, 0x2b, 0x79,\ 1758 | 0x9a, 0xe2, 0x34, 0x60, 0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, 0x80, 0xe3, 0x0f, 0xbd, 0x65,\ 1759 | 0x20, 0x08, 0x13, 0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, 0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe,\ 1760 | 0x31, 0x48, 0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, 0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a,\ 1761 | 0xe4, 0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, 0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2 }; 1762 | if (transferPacket->reportBufferLen >= sizeof(PTPHQA_BLOB)) 1763 | { 1764 | uint8_t *blobBuffer = (uint8_t*)transferPacket->reportBuffer; 1765 | for (int i = 0; i < sizeof(PTPHQA_BLOB); i++) { 1766 | blobBuffer[i] = PTPHQA_BLOB[i]; 1767 | } 1768 | CyapaPrint(DEBUG_LEVEL_INFO, DBG_IOCTL, 1769 | "CyapaGetFeature PHPHQA\n"); 1770 | } 1771 | else 1772 | { 1773 | status = STATUS_INVALID_PARAMETER; 1774 | 1775 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1776 | "CyapaGetFeature Error transferPacket->reportBufferLen (%d) is different from sizeof(PTPHEQ_BLOB) (%d)\n", 1777 | transferPacket->reportBufferLen, 1778 | sizeof(CyapaFeatureReport)); 1779 | } 1780 | break; 1781 | } 1782 | 1783 | default: 1784 | 1785 | CyapaPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL, 1786 | "CyapaGetFeature Unhandled report type %d\n", transferPacket->reportId); 1787 | 1788 | status = STATUS_INVALID_PARAMETER; 1789 | 1790 | break; 1791 | } 1792 | } 1793 | } 1794 | 1795 | CyapaPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, 1796 | "CyapaGetFeature Exit = 0x%x\n", status); 1797 | 1798 | return status; 1799 | } 1800 | 1801 | PCHAR 1802 | DbgHidInternalIoctlString( 1803 | IN ULONG IoControlCode 1804 | ) 1805 | { 1806 | switch (IoControlCode) 1807 | { 1808 | case IOCTL_HID_GET_DEVICE_DESCRIPTOR: 1809 | return "IOCTL_HID_GET_DEVICE_DESCRIPTOR"; 1810 | case IOCTL_HID_GET_REPORT_DESCRIPTOR: 1811 | return "IOCTL_HID_GET_REPORT_DESCRIPTOR"; 1812 | case IOCTL_HID_READ_REPORT: 1813 | return "IOCTL_HID_READ_REPORT"; 1814 | case IOCTL_HID_GET_DEVICE_ATTRIBUTES: 1815 | return "IOCTL_HID_GET_DEVICE_ATTRIBUTES"; 1816 | case IOCTL_HID_WRITE_REPORT: 1817 | return "IOCTL_HID_WRITE_REPORT"; 1818 | case IOCTL_HID_SET_FEATURE: 1819 | return "IOCTL_HID_SET_FEATURE"; 1820 | case IOCTL_HID_GET_FEATURE: 1821 | return "IOCTL_HID_GET_FEATURE"; 1822 | case IOCTL_HID_GET_STRING: 1823 | return "IOCTL_HID_GET_STRING"; 1824 | case IOCTL_HID_ACTIVATE_DEVICE: 1825 | return "IOCTL_HID_ACTIVATE_DEVICE"; 1826 | case IOCTL_HID_DEACTIVATE_DEVICE: 1827 | return "IOCTL_HID_DEACTIVATE_DEVICE"; 1828 | case IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST: 1829 | return "IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST"; 1830 | case IOCTL_HID_SET_OUTPUT_REPORT: 1831 | return "IOCTL_HID_SET_OUTPUT_REPORT"; 1832 | case IOCTL_HID_GET_INPUT_REPORT: 1833 | return "IOCTL_HID_GET_INPUT_REPORT"; 1834 | default: 1835 | return "Unknown IOCTL"; 1836 | } 1837 | } 1838 | --------------------------------------------------------------------------------