-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathinterception.py
More file actions
283 lines (231 loc) · 9.16 KB
/
interception.py
File metadata and controls
283 lines (231 loc) · 9.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#
#
# Python wrappings for
# Interception by oblitum:
# http://oblita.com/Interception
# https://github.com/oblitum/Interception
# !!! Attention !!!
# WIP
# Not completely tested
# May not run at all or may cause your system to stop accepting input
# And if you do not use it properly it will definetely do the later
# I am not responsible for any damage that may be caused by the use of
# this incomplete code
from ctypes import *
from ctypes import _CFuncPtr
interceptionDll = cdll.interception
MAX_KEYBOARD = 10
MAX_MOUSE = 10
MAX_DEVICE = MAX_KEYBOARD + MAX_MOUSE
KEYBOARD = lambda index: index+1
MOUSE = lambda index: MAX_KEYBOARD + index + 1
class Context( c_void_p ):
pass
class Device( c_int ):
pass
class Precedence( c_int ):
pass
class Filter( c_ushort ):
pass
PredicateCache = {}
class PredicateType():
def __init__( self, func ):
if isinstance(func, _CFuncPtr):
self._as_parameter_ = func
self._as_parameter_.argtypes = [ c_int ]
self._as_parameter_.restype = c_bool
elif callable( func ):
self._as_parameter_ = CFUNCTYPE( c_bool, c_int )( func )
else:
raise TypeError
def from_param( self ):
return self._as_parameter_
def __call__( self, device ):
return self._as_parameter_( device )
def Predicate ( func ):
if isinstance( func, _CFuncPtr ):
hashValue = id( func )
elif callable( func ):
hashValue = id( func )
else:
raise TypeError("Wrong type for a Predicate ( should be something like a function")
predFunc = PredicateCache.get( hashValue , False )
if not predFunc:
predFunc = PredicateType(func)
PredicateCache [ hashValue ] = predFunc
return predFunc
KEY_DOWN = 0x00
KEY_UP = 0x01
KEY_E0 = 0x02
KEY_E1 = 0x04
KEY_TERMSRV_SET_LED = 0x08
KEY_TERMSRV_SHADOW = 0x10
KEY_TERMSRV_VKPACKET = 0x20
FILTER_KEY_NONE = 0x0000
FILTER_KEY_ALL = 0xFFFF
FILTER_KEY_DOWN = KEY_UP
FILTER_KEY_UP = KEY_UP << 1
FILTER_KEY_E0 = KEY_E0 << 1
FILTER_KEY_E1 = KEY_E1 << 1
FILTER_KEY_TERMSRV_SET_LED = KEY_TERMSRV_SET_LED << 1
FILTER_KEY_TERMSRV_SHADOW = KEY_TERMSRV_SHADOW << 1
FILTER_KEY_TERMSRV_VKPACKET = KEY_TERMSRV_VKPACKET << 1
MOUSE_LEFT_BUTTON_DOWN = 0x001
MOUSE_LEFT_BUTTON_UP = 0x002
MOUSE_RIGHT_BUTTON_DOWN = 0x004
MOUSE_RIGHT_BUTTON_UP = 0x008
MOUSE_MIDDLE_BUTTON_DOWN = 0x010
MOUSE_MIDDLE_BUTTON_UP = 0x020
MOUSE_BUTTON_1_DOWN = MOUSE_LEFT_BUTTON_DOWN
MOUSE_BUTTON_1_UP = MOUSE_LEFT_BUTTON_UP
MOUSE_BUTTON_2_DOWN = MOUSE_RIGHT_BUTTON_DOWN
MOUSE_BUTTON_2_UP = MOUSE_RIGHT_BUTTON_UP
MOUSE_BUTTON_3_DOWN = MOUSE_MIDDLE_BUTTON_DOWN
MOUSE_BUTTON_3_UP = MOUSE_MIDDLE_BUTTON_UP
MOUSE_BUTTON_4_DOWN = 0x040
MOUSE_BUTTON_4_UP = 0x080
MOUSE_BUTTON_5_DOWN = 0x100
MOUSE_BUTTON_5_UP = 0x200
MOUSE_WHEEL = 0x400
MOUSE_HWHEEL = 0x800
FILTER_MOUSE_NONE = 0x0000
FILTER_MOUSE_ALL = 0xFFFF
FILTER_MOUSE_LEFT_BUTTON_DOWN = MOUSE_LEFT_BUTTON_DOWN
FILTER_MOUSE_LEFT_BUTTON_UP = MOUSE_LEFT_BUTTON_UP
FILTER_MOUSE_RIGHT_BUTTON_DOWN = MOUSE_RIGHT_BUTTON_DOWN
FILTER_MOUSE_RIGHT_BUTTON_UP = MOUSE_RIGHT_BUTTON_UP
FILTER_MOUSE_MIDDLE_BUTTON_DOWN = MOUSE_MIDDLE_BUTTON_DOWN
FILTER_MOUSE_MIDDLE_BUTTON_UP = MOUSE_MIDDLE_BUTTON_UP
FILTER_MOUSE_BUTTON_1_DOWN = MOUSE_BUTTON_1_DOWN
FILTER_MOUSE_BUTTON_1_UP = MOUSE_BUTTON_1_UP
FILTER_MOUSE_BUTTON_2_DOWN = MOUSE_BUTTON_2_DOWN
FILTER_MOUSE_BUTTON_2_UP = MOUSE_BUTTON_2_UP
FILTER_MOUSE_BUTTON_3_DOWN = MOUSE_BUTTON_3_DOWN
FILTER_MOUSE_BUTTON_3_UP = MOUSE_BUTTON_3_UP
FILTER_MOUSE_BUTTON_4_DOWN = MOUSE_BUTTON_4_DOWN
FILTER_MOUSE_BUTTON_4_UP = MOUSE_BUTTON_4_UP
FILTER_MOUSE_BUTTON_5_DOWN = MOUSE_BUTTON_5_DOWN
FILTER_MOUSE_BUTTON_5_UP = MOUSE_BUTTON_5_UP
FILTER_MOUSE_WHEEL = MOUSE_WHEEL
FILTER_MOUSE_HWHEEL = MOUSE_HWHEEL
FILTER_MOUSE_MOVE = 0x1000
MOUSE_MOVE_RELATIVE = 0x000
MOUSE_MOVE_ABSOLUTE = 0x001
MOUSE_VIRTUAL_DESKTOP = 0x002
MOUSE_ATTRIBUTES_CHANGED = 0x004
MOUSE_MOVE_NOCOALESCE = 0x008
MOUSE_TERMSRV_SRC_SHADOW = 0x100
class MouseStroke( Structure ):
_fields_ = [
( "state", c_ushort ),
( "flags", c_ushort ),
( "rolling", c_short ),
( "x", c_int ),
( "y", c_int ),
( "information", c_uint )
]
class KeyStroke( Structure ):
_fields_ = [
( "code", c_ushort ),
( "state", c_ushort ),
( "information", c_uint )
]
def stroke2KeyStroke( stroke, dest = None ):
if not dest:
result = KeyStroke()
memmove( byref( result ), stroke, sizeof( result ) )
return result
else:
return memmove( byref( dest ), stroke, sizeof( KeyStroke ))
def stroke2MouseStroke( stroke, dest = None ):
if not dest:
result = MouseStroke()
memmove( byref( result ), stroke, sizeof( MouseStroke ) )
return result
else:
return memmove( byref( dest ), stroke, sizeof( MouseStroke ) )
class Stroke ():
def __init__( self, initial = None ):
if initial:
self._as_parameter_ = ( c_ushort * ( sizeof ( MouseStroke ) // sizeof( c_ushort ) ) ) (*initial)
else:
self._as_parameter_ = ( c_ushort * ( sizeof ( MouseStroke ) // sizeof( c_ushort ) ) ) ()
def from_param( self ):
return self._as_parameter_
def __getitem__( self, index):
return self.data[ index ]
def __setitem__( self, index, value):
self.data[ index ] = value
create_context = interceptionDll.interception_create_context
create_context.argtypes = []
create_context.restype = Context
destroy_context = interceptionDll.interception_destroy_context
destroy_context.argtypes= [Context]
destroy_context.restype = c_void_p
get_precedence = interceptionDll.interception_get_precedence
get_precedence.argtypes = [Context, Device]
get_precedence.restype = Precedence
set_precedence = interceptionDll.interception_set_precedence
set_precedence.argtypes = [Context, Device, Precedence]
set_precedence.restype = c_void_p
get_filter = interceptionDll.interception_get_filter
get_filter.argtypes = [Context, Device]
get_filter.restype = Filter
set_filter_proto = interceptionDll.interception_set_filter
set_filter_proto.argtypes = [Context, PredicateType, Filter]
set_filter_proto.restype = c_void_p
def set_filter(cont,pred,filt):
if isinstance(pred,PredicateType):
return set_filter_proto(cont,pred,filt)
else:
return set_filter_proto(cont,Predicate(pred),filt)
wait = interceptionDll.interception_wait
wait.argtypes = [Context]
wait.restype = Device
wait_with_timeout = interceptionDll.interception_wait_with_timeout
wait_with_timeout.argtypes = [Context, c_ulong]
wait_with_timeout.restype = Device
send_proto = interceptionDll.interception_send
send_proto.argtypes = [Context, Device, Stroke, c_uint]
send_proto.restype = c_int
__temp_Stroke = Stroke()
def send( context, device, stroke, nstroke ):
if isinstance( stroke, Stroke ):
return send_proto( context, device, stroke, nstroke)
if isinstance( stroke, ( KeyStroke, MouseStroke ) ):
memmove( __temp_Stroke, byref( stroke ), sizeof( stroke ))
return send_proto( context, device, __temp_Stroke, nstroke )
raise TypeError( "Argument 3. Expected <'Stroke'>, <'KeyStroke'> or <'MouseStroke'>, got {0} instead.".format( type( stroke ) ) )
receive = interceptionDll.interception_receive
receive.argtypes = [ Context, Device, Stroke, c_uint ]
receive.restype = c_int
get_hardware_id_proto = interceptionDll.interception_get_hardware_id
get_hardware_id_proto.argtypes = [ Context, Device, c_void_p, c_uint ]
get_hardware_id_proto.restype = c_uint
def memoryChunk2Strings( string, lenght = 0 ):
if lenght:
limit = lenght
else:
limit = sizeof(string)
result = []
offset = 0
while offset < sizeof( string ):
part = wstring_at( addressof( string ) + offset * 2 )
if part:
result.append( part )
offset += len( part )+1
else:
break
return result
__hardware_Id_Data = [ create_unicode_buffer( 300 ), 300 ]
def get_hardware_id ( context, device, max_size = 0):
if max_size > __hardware_Id_Data[ 1 ]:
__hardware_Id_Data[ 1 ] = max_size
__hardware_Id_Data[ 0 ] = create_unicode_buffer( max_size )
lenght = get_hardware_id_proto( context, device, __hardware_Id_Data[ 0 ], __hardware_Id_Data[ 1 ] )
if lenght > 0:
return memoryChunk2Strings( __hardware_Id_Data[ 0 ], lenght)
return None
is_invalid = Predicate( interceptionDll.interception_is_invalid )
is_keyboard = Predicate( interceptionDll.interception_is_keyboard )
is_mouse = Predicate( interceptionDll.interception_is_mouse )