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