1#! python
2#
3# Constants and types for use with Windows API, used by serialwin32.py
4#
5# This file is part of pySerial. https://github.com/pyserial/pyserial
6# (C) 2001-2015 Chris Liechti <[email protected]>
7#
8# SPDX-License-Identifier:    BSD-3-Clause
9
10# pylint: disable=invalid-name,too-few-public-methods,protected-access,too-many-instance-attributes
11
12from __future__ import absolute_import
13
14from ctypes import c_ulong, c_void_p, c_int64, c_char, \
15                   WinDLL, sizeof, Structure, Union, POINTER
16from ctypes.wintypes import HANDLE
17from ctypes.wintypes import BOOL
18from ctypes.wintypes import LPCWSTR
19from ctypes.wintypes import DWORD
20from ctypes.wintypes import WORD
21from ctypes.wintypes import BYTE
22_stdcall_libraries = {}
23_stdcall_libraries['kernel32'] = WinDLL('kernel32')
24
25INVALID_HANDLE_VALUE = HANDLE(-1).value
26
27
28# some details of the windows API differ between 32 and 64 bit systems..
29def is_64bit():
30    """Returns true when running on a 64 bit system"""
31    return sizeof(c_ulong) != sizeof(c_void_p)
32
33# ULONG_PTR is a an ordinary number, not a pointer and contrary to the name it
34# is either 32 or 64 bits, depending on the type of windows...
35# so test if this a 32 bit windows...
36if is_64bit():
37    ULONG_PTR = c_int64
38else:
39    ULONG_PTR = c_ulong
40
41
42class _SECURITY_ATTRIBUTES(Structure):
43    pass
44LPSECURITY_ATTRIBUTES = POINTER(_SECURITY_ATTRIBUTES)
45
46
47try:
48    CreateEventW = _stdcall_libraries['kernel32'].CreateEventW
49except AttributeError:
50    # Fallback to non wide char version for old OS...
51    from ctypes.wintypes import LPCSTR
52    CreateEventA = _stdcall_libraries['kernel32'].CreateEventA
53    CreateEventA.restype = HANDLE
54    CreateEventA.argtypes = [LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR]
55    CreateEvent = CreateEventA
56
57    CreateFileA = _stdcall_libraries['kernel32'].CreateFileA
58    CreateFileA.restype = HANDLE
59    CreateFileA.argtypes = [LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE]
60    CreateFile = CreateFileA
61else:
62    CreateEventW.restype = HANDLE
63    CreateEventW.argtypes = [LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR]
64    CreateEvent = CreateEventW  # alias
65
66    CreateFileW = _stdcall_libraries['kernel32'].CreateFileW
67    CreateFileW.restype = HANDLE
68    CreateFileW.argtypes = [LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE]
69    CreateFile = CreateFileW  # alias
70
71
72class _OVERLAPPED(Structure):
73    pass
74
75OVERLAPPED = _OVERLAPPED
76
77
78class _COMSTAT(Structure):
79    pass
80
81COMSTAT = _COMSTAT
82
83
84class _DCB(Structure):
85    pass
86
87DCB = _DCB
88
89
90class _COMMTIMEOUTS(Structure):
91    pass
92
93COMMTIMEOUTS = _COMMTIMEOUTS
94
95GetLastError = _stdcall_libraries['kernel32'].GetLastError
96GetLastError.restype = DWORD
97GetLastError.argtypes = []
98
99LPOVERLAPPED = POINTER(_OVERLAPPED)
100LPDWORD = POINTER(DWORD)
101
102GetOverlappedResult = _stdcall_libraries['kernel32'].GetOverlappedResult
103GetOverlappedResult.restype = BOOL
104GetOverlappedResult.argtypes = [HANDLE, LPOVERLAPPED, LPDWORD, BOOL]
105
106ResetEvent = _stdcall_libraries['kernel32'].ResetEvent
107ResetEvent.restype = BOOL
108ResetEvent.argtypes = [HANDLE]
109
110LPCVOID = c_void_p
111
112WriteFile = _stdcall_libraries['kernel32'].WriteFile
113WriteFile.restype = BOOL
114WriteFile.argtypes = [HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED]
115
116LPVOID = c_void_p
117
118ReadFile = _stdcall_libraries['kernel32'].ReadFile
119ReadFile.restype = BOOL
120ReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED]
121
122CloseHandle = _stdcall_libraries['kernel32'].CloseHandle
123CloseHandle.restype = BOOL
124CloseHandle.argtypes = [HANDLE]
125
126ClearCommBreak = _stdcall_libraries['kernel32'].ClearCommBreak
127ClearCommBreak.restype = BOOL
128ClearCommBreak.argtypes = [HANDLE]
129
130LPCOMSTAT = POINTER(_COMSTAT)
131
132ClearCommError = _stdcall_libraries['kernel32'].ClearCommError
133ClearCommError.restype = BOOL
134ClearCommError.argtypes = [HANDLE, LPDWORD, LPCOMSTAT]
135
136SetupComm = _stdcall_libraries['kernel32'].SetupComm
137SetupComm.restype = BOOL
138SetupComm.argtypes = [HANDLE, DWORD, DWORD]
139
140EscapeCommFunction = _stdcall_libraries['kernel32'].EscapeCommFunction
141EscapeCommFunction.restype = BOOL
142EscapeCommFunction.argtypes = [HANDLE, DWORD]
143
144GetCommModemStatus = _stdcall_libraries['kernel32'].GetCommModemStatus
145GetCommModemStatus.restype = BOOL
146GetCommModemStatus.argtypes = [HANDLE, LPDWORD]
147
148LPDCB = POINTER(_DCB)
149
150GetCommState = _stdcall_libraries['kernel32'].GetCommState
151GetCommState.restype = BOOL
152GetCommState.argtypes = [HANDLE, LPDCB]
153
154LPCOMMTIMEOUTS = POINTER(_COMMTIMEOUTS)
155
156GetCommTimeouts = _stdcall_libraries['kernel32'].GetCommTimeouts
157GetCommTimeouts.restype = BOOL
158GetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS]
159
160PurgeComm = _stdcall_libraries['kernel32'].PurgeComm
161PurgeComm.restype = BOOL
162PurgeComm.argtypes = [HANDLE, DWORD]
163
164SetCommBreak = _stdcall_libraries['kernel32'].SetCommBreak
165SetCommBreak.restype = BOOL
166SetCommBreak.argtypes = [HANDLE]
167
168SetCommMask = _stdcall_libraries['kernel32'].SetCommMask
169SetCommMask.restype = BOOL
170SetCommMask.argtypes = [HANDLE, DWORD]
171
172SetCommState = _stdcall_libraries['kernel32'].SetCommState
173SetCommState.restype = BOOL
174SetCommState.argtypes = [HANDLE, LPDCB]
175
176SetCommTimeouts = _stdcall_libraries['kernel32'].SetCommTimeouts
177SetCommTimeouts.restype = BOOL
178SetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS]
179
180WaitForSingleObject = _stdcall_libraries['kernel32'].WaitForSingleObject
181WaitForSingleObject.restype = DWORD
182WaitForSingleObject.argtypes = [HANDLE, DWORD]
183
184WaitCommEvent = _stdcall_libraries['kernel32'].WaitCommEvent
185WaitCommEvent.restype = BOOL
186WaitCommEvent.argtypes = [HANDLE, LPDWORD, LPOVERLAPPED]
187
188CancelIoEx = _stdcall_libraries['kernel32'].CancelIoEx
189CancelIoEx.restype = BOOL
190CancelIoEx.argtypes = [HANDLE, LPOVERLAPPED]
191
192ONESTOPBIT = 0  # Variable c_int
193TWOSTOPBITS = 2  # Variable c_int
194ONE5STOPBITS = 1
195
196NOPARITY = 0  # Variable c_int
197ODDPARITY = 1  # Variable c_int
198EVENPARITY = 2  # Variable c_int
199MARKPARITY = 3
200SPACEPARITY = 4
201
202RTS_CONTROL_HANDSHAKE = 2  # Variable c_int
203RTS_CONTROL_DISABLE = 0  # Variable c_int
204RTS_CONTROL_ENABLE = 1  # Variable c_int
205RTS_CONTROL_TOGGLE = 3  # Variable c_int
206SETRTS = 3
207CLRRTS = 4
208
209DTR_CONTROL_HANDSHAKE = 2  # Variable c_int
210DTR_CONTROL_DISABLE = 0  # Variable c_int
211DTR_CONTROL_ENABLE = 1  # Variable c_int
212SETDTR = 5
213CLRDTR = 6
214
215MS_DSR_ON = 32  # Variable c_ulong
216EV_RING = 256  # Variable c_int
217EV_PERR = 512  # Variable c_int
218EV_ERR = 128  # Variable c_int
219SETXOFF = 1  # Variable c_int
220EV_RXCHAR = 1  # Variable c_int
221GENERIC_WRITE = 1073741824  # Variable c_long
222PURGE_TXCLEAR = 4  # Variable c_int
223FILE_FLAG_OVERLAPPED = 1073741824  # Variable c_int
224EV_DSR = 16  # Variable c_int
225MAXDWORD = 4294967295  # Variable c_uint
226EV_RLSD = 32  # Variable c_int
227
228ERROR_SUCCESS = 0
229ERROR_NOT_ENOUGH_MEMORY = 8
230ERROR_OPERATION_ABORTED = 995
231ERROR_IO_INCOMPLETE = 996
232ERROR_IO_PENDING = 997  # Variable c_long
233ERROR_INVALID_USER_BUFFER = 1784
234
235MS_CTS_ON = 16  # Variable c_ulong
236EV_EVENT1 = 2048  # Variable c_int
237EV_RX80FULL = 1024  # Variable c_int
238PURGE_RXABORT = 2  # Variable c_int
239FILE_ATTRIBUTE_NORMAL = 128  # Variable c_int
240PURGE_TXABORT = 1  # Variable c_int
241SETXON = 2  # Variable c_int
242OPEN_EXISTING = 3  # Variable c_int
243MS_RING_ON = 64  # Variable c_ulong
244EV_TXEMPTY = 4  # Variable c_int
245EV_RXFLAG = 2  # Variable c_int
246MS_RLSD_ON = 128  # Variable c_ulong
247GENERIC_READ = 2147483648  # Variable c_ulong
248EV_EVENT2 = 4096  # Variable c_int
249EV_CTS = 8  # Variable c_int
250EV_BREAK = 64  # Variable c_int
251PURGE_RXCLEAR = 8  # Variable c_int
252INFINITE = 0xFFFFFFFF
253
254CE_RXOVER = 0x0001
255CE_OVERRUN = 0x0002
256CE_RXPARITY = 0x0004
257CE_FRAME = 0x0008
258CE_BREAK = 0x0010
259
260
261class N11_OVERLAPPED4DOLLAR_48E(Union):
262    pass
263
264
265class N11_OVERLAPPED4DOLLAR_484DOLLAR_49E(Structure):
266    pass
267
268
269N11_OVERLAPPED4DOLLAR_484DOLLAR_49E._fields_ = [
270    ('Offset', DWORD),
271    ('OffsetHigh', DWORD),
272]
273
274PVOID = c_void_p
275
276N11_OVERLAPPED4DOLLAR_48E._anonymous_ = ['_0']
277N11_OVERLAPPED4DOLLAR_48E._fields_ = [
278    ('_0', N11_OVERLAPPED4DOLLAR_484DOLLAR_49E),
279    ('Pointer', PVOID),
280]
281_OVERLAPPED._anonymous_ = ['_0']
282_OVERLAPPED._fields_ = [
283    ('Internal', ULONG_PTR),
284    ('InternalHigh', ULONG_PTR),
285    ('_0', N11_OVERLAPPED4DOLLAR_48E),
286    ('hEvent', HANDLE),
287]
288_SECURITY_ATTRIBUTES._fields_ = [
289    ('nLength', DWORD),
290    ('lpSecurityDescriptor', LPVOID),
291    ('bInheritHandle', BOOL),
292]
293_COMSTAT._fields_ = [
294    ('fCtsHold', DWORD, 1),
295    ('fDsrHold', DWORD, 1),
296    ('fRlsdHold', DWORD, 1),
297    ('fXoffHold', DWORD, 1),
298    ('fXoffSent', DWORD, 1),
299    ('fEof', DWORD, 1),
300    ('fTxim', DWORD, 1),
301    ('fReserved', DWORD, 25),
302    ('cbInQue', DWORD),
303    ('cbOutQue', DWORD),
304]
305_DCB._fields_ = [
306    ('DCBlength', DWORD),
307    ('BaudRate', DWORD),
308    ('fBinary', DWORD, 1),
309    ('fParity', DWORD, 1),
310    ('fOutxCtsFlow', DWORD, 1),
311    ('fOutxDsrFlow', DWORD, 1),
312    ('fDtrControl', DWORD, 2),
313    ('fDsrSensitivity', DWORD, 1),
314    ('fTXContinueOnXoff', DWORD, 1),
315    ('fOutX', DWORD, 1),
316    ('fInX', DWORD, 1),
317    ('fErrorChar', DWORD, 1),
318    ('fNull', DWORD, 1),
319    ('fRtsControl', DWORD, 2),
320    ('fAbortOnError', DWORD, 1),
321    ('fDummy2', DWORD, 17),
322    ('wReserved', WORD),
323    ('XonLim', WORD),
324    ('XoffLim', WORD),
325    ('ByteSize', BYTE),
326    ('Parity', BYTE),
327    ('StopBits', BYTE),
328    ('XonChar', c_char),
329    ('XoffChar', c_char),
330    ('ErrorChar', c_char),
331    ('EofChar', c_char),
332    ('EvtChar', c_char),
333    ('wReserved1', WORD),
334]
335_COMMTIMEOUTS._fields_ = [
336    ('ReadIntervalTimeout', DWORD),
337    ('ReadTotalTimeoutMultiplier', DWORD),
338    ('ReadTotalTimeoutConstant', DWORD),
339    ('WriteTotalTimeoutMultiplier', DWORD),
340    ('WriteTotalTimeoutConstant', DWORD),
341]
342__all__ = ['GetLastError', 'MS_CTS_ON', 'FILE_ATTRIBUTE_NORMAL',
343           'DTR_CONTROL_ENABLE', '_COMSTAT', 'MS_RLSD_ON',
344           'GetOverlappedResult', 'SETXON', 'PURGE_TXABORT',
345           'PurgeComm', 'N11_OVERLAPPED4DOLLAR_48E', 'EV_RING',
346           'ONESTOPBIT', 'SETXOFF', 'PURGE_RXABORT', 'GetCommState',
347           'RTS_CONTROL_ENABLE', '_DCB', 'CreateEvent',
348           '_COMMTIMEOUTS', '_SECURITY_ATTRIBUTES', 'EV_DSR',
349           'EV_PERR', 'EV_RXFLAG', 'OPEN_EXISTING', 'DCB',
350           'FILE_FLAG_OVERLAPPED', 'EV_CTS', 'SetupComm',
351           'LPOVERLAPPED', 'EV_TXEMPTY', 'ClearCommBreak',
352           'LPSECURITY_ATTRIBUTES', 'SetCommBreak', 'SetCommTimeouts',
353           'COMMTIMEOUTS', 'ODDPARITY', 'EV_RLSD',
354           'GetCommModemStatus', 'EV_EVENT2', 'PURGE_TXCLEAR',
355           'EV_BREAK', 'EVENPARITY', 'LPCVOID', 'COMSTAT', 'ReadFile',
356           'PVOID', '_OVERLAPPED', 'WriteFile', 'GetCommTimeouts',
357           'ResetEvent', 'EV_RXCHAR', 'LPCOMSTAT', 'ClearCommError',
358           'ERROR_IO_PENDING', 'EscapeCommFunction', 'GENERIC_READ',
359           'RTS_CONTROL_HANDSHAKE', 'OVERLAPPED',
360           'DTR_CONTROL_HANDSHAKE', 'PURGE_RXCLEAR', 'GENERIC_WRITE',
361           'LPDCB', 'CreateEventW', 'SetCommMask', 'EV_EVENT1',
362           'SetCommState', 'LPVOID', 'CreateFileW', 'LPDWORD',
363           'EV_RX80FULL', 'TWOSTOPBITS', 'LPCOMMTIMEOUTS', 'MAXDWORD',
364           'MS_DSR_ON', 'MS_RING_ON',
365           'N11_OVERLAPPED4DOLLAR_484DOLLAR_49E', 'EV_ERR',
366           'ULONG_PTR', 'CreateFile', 'NOPARITY', 'CloseHandle']
367