- forward port and apply patch from Giovanni Bajo to use ctypes on win32
- some minor refactoring
diff --git a/pyserial/CHANGES.txt b/pyserial/CHANGES.txt
index 2fd7d80..b1b366c 100644
--- a/pyserial/CHANGES.txt
+++ b/pyserial/CHANGES.txt
@@ -305,6 +305,8 @@
 - 1.5 stop bits (STOPBITS_ONE_POINT_FIVE, implemented on all platforms)
 - miniterm application extended
 - add scanlinux.py example
+- Support for Win32 is now written on the top of ctypes (bundled with
+  Python 2.5+) instead of pywin32 (patch by Giovanni Bajo).
 
 Bugfixes:
 
diff --git a/pyserial/serial/serialwin32.py b/pyserial/serial/serialwin32.py
index 656c5dd..35415db 100644
--- a/pyserial/serial/serialwin32.py
+++ b/pyserial/serial/serialwin32.py
@@ -5,17 +5,14 @@
 #
 # (C) 2001-2009 Chris Liechti <cliechti@gmx.net>
 # this is distributed under a free software license, see license.txt
+#
+# Initial patch to use ctypes by Giovanni Bajo <rasky@develer.com>
 
-import win32file  # The base COM port and file IO functions.
-import win32event # We use events and the WaitFor[Single|Multiple]Objects functions.
-import win32con   # constants.
+import ctypes
+import win32
+
 from serialutil import *
 
-#from winbase.h. these should really be in win32con
-MS_CTS_ON  = 16
-MS_DSR_ON  = 32
-MS_RING_ON = 64
-MS_RLSD_ON = 128
 
 def device(portnum):
     """Turn a port number into a device name"""
@@ -41,38 +38,39 @@
         if port.upper().startswith('COM') and int(port[3:]) > 8:
             port = '\\\\.\\' + port
         try:
-            self.hComPort = win32file.CreateFile(port,
-                   win32con.GENERIC_READ | win32con.GENERIC_WRITE,
+            self.hComPort = win32.CreateFile(port,
+                   win32.GENERIC_READ | win32.GENERIC_WRITE,
                    0, # exclusive access
                    None, # no security
-                   win32con.OPEN_EXISTING,
-                   win32con.FILE_FLAG_OVERLAPPED,
-                   None)
+                   win32.OPEN_EXISTING,
+                   win32.FILE_ATTRIBUTE_NORMAL | win32.FILE_FLAG_OVERLAPPED,
+                   0)
         except Exception, msg:
             self.hComPort = None    #'cause __del__ is called anyway
             raise SerialException("could not open port %s: %s" % (self.portstr, msg))
         # Setup a 4k buffer
-        win32file.SetupComm(self.hComPort, 4096, 4096)
+        win32.SetupComm(self.hComPort, 4096, 4096)
 
         # Save original timeout values:
-        self._orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
+        self._orgTimeouts = win32.COMMTIMEOUTS()
+        win32.GetCommTimeouts(self.hComPort, ctypes.byref(self._orgTimeouts))
 
-        self._rtsState = win32file.RTS_CONTROL_ENABLE
-        self._dtrState = win32file.DTR_CONTROL_ENABLE
+        self._rtsState = win32.RTS_CONTROL_ENABLE
+        self._dtrState = win32.DTR_CONTROL_ENABLE
 
         self._reconfigurePort()
 
         # Clear buffers:
         # Remove anything that was there
-        win32file.PurgeComm(self.hComPort,
-                            win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT |
-                            win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
+        win32.PurgeComm(self.hComPort,
+                            win32.PURGE_TXCLEAR | win32.PURGE_TXABORT |
+                            win32.PURGE_RXCLEAR | win32.PURGE_RXABORT)
 
-        self._overlappedRead = win32file.OVERLAPPED()
-        self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
-        self._overlappedWrite = win32file.OVERLAPPED()
-        #~ self._overlappedWrite.hEvent = win32event.CreateEvent(None, 1, 0, None)
-        self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
+        self._overlappedRead = win32.OVERLAPPED()
+        self._overlappedRead.hEvent = win32.CreateEvent(None, 1, 0, None)
+        self._overlappedWrite = win32.OVERLAPPED()
+        #~ self._overlappedWrite.hEvent = win32.CreateEvent(None, 1, 0, None)
+        self._overlappedWrite.hEvent = win32.CreateEvent(None, 0, 0, None)
         self._isOpen = True
 
     def _reconfigurePort(self):
@@ -88,7 +86,7 @@
         if self._timeout is None:
             timeouts = (0, 0, 0, 0, 0)
         elif self._timeout == 0:
-            timeouts = (win32con.MAXDWORD, 0, 0, 0, 0)
+            timeouts = (win32.MAXDWORD, 0, 0, 0, 0)
         else:
             timeouts = (0, 0, int(self._timeout*1000), 0, 0)
         if self._timeout != 0 and self._interCharTimeout is not None:
@@ -97,16 +95,17 @@
         if self._writeTimeout is None:
             pass
         elif self._writeTimeout == 0:
-            timeouts = timeouts[:-2] + (0, win32con.MAXDWORD)
+            timeouts = timeouts[:-2] + (0, win32.MAXDWORD)
         else:
             timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000))
-        win32file.SetCommTimeouts(self.hComPort, timeouts)
+        win32.SetCommTimeouts(self.hComPort, ctypes.byref(win32.COMMTIMEOUTS(*timeouts)))
 
-        win32file.SetCommMask(self.hComPort, win32file.EV_ERR)
+        win32.SetCommMask(self.hComPort, win32.EV_ERR)
 
         # Setup the connection info.
         # Get state and modify it:
-        comDCB = win32file.GetCommState(self.hComPort)
+        comDCB = win32.DCB()
+        win32.GetCommState(self.hComPort, ctypes.byref(comDCB))
         comDCB.BaudRate = self._baudrate
 
         if self._bytesize == FIVEBITS:
@@ -121,40 +120,40 @@
             raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
 
         if self._parity == PARITY_NONE:
-            comDCB.Parity       = win32file.NOPARITY
-            comDCB.fParity      = 0 # Dis/Enable Parity Check
+            comDCB.Parity       = win32.NOPARITY
+            comDCB.fParity      = 0 # Disable Parity Check
         elif self._parity == PARITY_EVEN:
-            comDCB.Parity       = win32file.EVENPARITY
-            comDCB.fParity      = 1 # Dis/Enable Parity Check
+            comDCB.Parity       = win32.EVENPARITY
+            comDCB.fParity      = 1 # Enable Parity Check
         elif self._parity == PARITY_ODD:
-            comDCB.Parity       = win32file.ODDPARITY
-            comDCB.fParity      = 1 # Dis/Enable Parity Check
+            comDCB.Parity       = win32.ODDPARITY
+            comDCB.fParity      = 1 # Enable Parity Check
         elif self._parity == PARITY_MARK:
-            comDCB.Parity       = win32file.MARKPARITY
-            comDCB.fParity      = 1 # Dis/Enable Parity Check
+            comDCB.Parity       = win32.MARKPARITY
+            comDCB.fParity      = 1 # Enable Parity Check
         elif self._parity == PARITY_SPACE:
-            comDCB.Parity       = win32file.SPACEPARITY
-            comDCB.fParity      = 1 # Dis/Enable Parity Check
+            comDCB.Parity       = win32.SPACEPARITY
+            comDCB.fParity      = 1 # Enable Parity Check
         else:
             raise ValueError("Unsupported parity mode: %r" % self._parity)
 
         if self._stopbits == STOPBITS_ONE:
-            comDCB.StopBits     = win32file.ONESTOPBIT
+            comDCB.StopBits     = win32.ONESTOPBIT
         elif self._stopbits == STOPBITS_ONE_POINT_FIVE:
-            comDCB.StopBits     = win32file.ONE5STOPBITS
+            comDCB.StopBits     = win32.ONE5STOPBITS
         elif self._stopbits == STOPBITS_TWO:
-            comDCB.StopBits     = win32file.TWOSTOPBITS
+            comDCB.StopBits     = win32.TWOSTOPBITS
         else:
             raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
 
         comDCB.fBinary          = 1 # Enable Binary Transmission
         # Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)
         if self._rtscts:
-            comDCB.fRtsControl  = win32file.RTS_CONTROL_HANDSHAKE
+            comDCB.fRtsControl  = win32.RTS_CONTROL_HANDSHAKE
         else:
             comDCB.fRtsControl  = self._rtsState
         if self._dsrdtr:
-            comDCB.fDtrControl  = win32file.DTR_CONTROL_HANDSHAKE
+            comDCB.fDtrControl  = win32.DTR_CONTROL_HANDSHAKE
         else:
             comDCB.fDtrControl  = self._dtrState
         comDCB.fOutxCtsFlow     = self._rtscts
@@ -167,9 +166,7 @@
         comDCB.XonChar          = XON
         comDCB.XoffChar         = XOFF
 
-        try:
-            win32file.SetCommState(self.hComPort, comDCB)
-        except win32file.error, e:
+        if not win32.SetCommState(self.hComPort, ctypes.byref(comDCB)):
             raise ValueError("Cannot configure port, some setting was wrong. Original message: %s" % e)
 
     #~ def __del__(self):
@@ -179,16 +176,12 @@
         """Close port"""
         if self._isOpen:
             if self.hComPort:
-                try:
-                    # Restore original timeout values:
-                    win32file.SetCommTimeouts(self.hComPort, self._orgTimeouts)
-                except win32file.error:
-                    # ignore errors. can happen for unplugged USB serial devices
-                    pass
+                # Restore original timeout values:
+                win32.SetCommTimeouts(self.hComPort, self._orgTimeouts)
                 # Close COM-Port:
-                win32file.CloseHandle(self.hComPort)
-                win32file.CloseHandle(self._overlappedRead.hEvent)
-                win32file.CloseHandle(self._overlappedWrite.hEvent)
+                win32.CloseHandle(self.hComPort)
+                win32.CloseHandle(self._overlappedRead.hEvent)
+                win32.CloseHandle(self._overlappedWrite.hEvent)
                 self.hComPort = None
             self._isOpen = False
 
@@ -199,7 +192,10 @@
 
     def inWaiting(self):
         """Return the number of characters currently in the input buffer."""
-        flags, comstat = win32file.ClearCommError(self.hComPort)
+        flags = win32.DWORD()
+        comstat = win32.COMSTAT()
+        if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)):
+            raise SerialException('call to ClearCommError failed')
         return comstat.cbInQue
 
     def read(self, size=1):
@@ -208,20 +204,31 @@
            until the requested number of bytes is read."""
         if not self.hComPort: raise portNotOpenError
         if size > 0:
-            win32event.ResetEvent(self._overlappedRead.hEvent)
-            flags, comstat = win32file.ClearCommError(self.hComPort)
+            win32.ResetEvent(self._overlappedRead.hEvent)
+            flags = win32.DWORD()
+            comstat = win32.COMSTAT()
+            if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)):
+                raise SerialException('call to ClearCommError failed')
             if self.timeout == 0:
                 n = min(comstat.cbInQue, size)
                 if n > 0:
-                    rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(n), self._overlappedRead)
-                    win32event.WaitForSingleObject(self._overlappedRead.hEvent, win32event.INFINITE)
-                    read = str(buf)
+                    buf = ctypes.create_string_buffer(n)
+                    rc = win32.DWORD()
+                    err = win32.ReadFile(self.hComPort, buf, size, ctypes.byref(rc), ctypes.byref(self._overlappedRead))
+                    if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
+                        raise SerialException("ReadFile failed (%s)" % WinError())
+                    err = win32.WaitForSingleObject(self._overlappedRead.hEvent, win32.INFINITE)
+                    read = buf.raw[:rc.value]
                 else:
                     read = ''
             else:
-                rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(size), self._overlappedRead)
-                n = win32file.GetOverlappedResult(self.hComPort, self._overlappedRead, 1)
-                read = str(buf[:n])
+                buf = ctypes.create_string_buffer(size)
+                rc = win32.DWORD()
+                err = win32.ReadFile(self.hComPort, buf, size, ctypes.byref(rc), ctypes.byref(self._overlappedRead))
+                if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
+                    raise SerialException("ReadFile failed (%s)" % WinError())
+                err = win32.GetOverlappedResult(self.hComPort, ctypes.byref(self._overlappedRead), ctypes.byref(rc), True)
+                read = buf.raw[:rc.value]
         else:
             read = ''
         return read
@@ -233,81 +240,88 @@
             raise TypeError('expected str, got %s' % type(data))
         if data:
             #~ win32event.ResetEvent(self._overlappedWrite.hEvent)
-            err, n = win32file.WriteFile(self.hComPort, data, self._overlappedWrite)
-            if err: #will be ERROR_IO_PENDING:
-                # Wait for the write to complete.
-                #~ win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
-                n = win32file.GetOverlappedResult(self.hComPort, self._overlappedWrite, 1)
-                if n != len(data):
-                    raise writeTimeoutError
+            n = win32.DWORD()
+            err = win32.WriteFile(self.hComPort, s, len(s), ctypes.byref(n), self._overlappedWrite)
+            if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
+                raise SerialException("WriteFile failed (%s)" % WinError())
+            # Wait for the write to complete.
+            #~ win32.WaitForSingleObject(self._overlappedWrite.hEvent, win32.INFINITE)
+            win32.GetOverlappedResult(self.hComPort, self._overlappedWrite, ctypes.byref(n), True)
+            if n != len(s):
+                raise writeTimeoutError
 
 
     def flushInput(self):
         """Clear input buffer, discarding all that is in the buffer."""
         if not self.hComPort: raise portNotOpenError
-        win32file.PurgeComm(self.hComPort, win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
+        win32.PurgeComm(self.hComPort, win32.PURGE_RXCLEAR | win32.PURGE_RXABORT)
 
     def flushOutput(self):
         """Clear output buffer, aborting the current output and
         discarding all that is in the buffer."""
         if not self.hComPort: raise portNotOpenError
-        win32file.PurgeComm(self.hComPort, win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT)
+        win32.PurgeComm(self.hComPort, win32.PURGE_TXCLEAR | win32.PURGE_TXABORT)
 
     def sendBreak(self, duration=0.25):
         """Send break condition. Timed, returns to idle state after given duration."""
         if not self.hComPort: raise portNotOpenError
         import time
-        win32file.SetCommBreak(self.hComPort)
+        win32.SetCommBreak(self.hComPort)
         time.sleep(duration)
-        win32file.ClearCommBreak(self.hComPort)
+        win32.ClearCommBreak(self.hComPort)
 
     def setBreak(self, level=1):
         """Set break: Controls TXD. When active, to transmitting is possible."""
         if not self.hComPort: raise portNotOpenError
         if level:
-            win32file.SetCommBreak(self.hComPort)
+            win32.SetCommBreak(self.hComPort)
         else:
-            win32file.ClearCommBreak(self.hComPort)
+            win32.ClearCommBreak(self.hComPort)
 
     def setRTS(self, level=1):
         """Set terminal status line: Request To Send"""
         if not self.hComPort: raise portNotOpenError
         if level:
             self._rtsState = win32file.RTS_CONTROL_ENABLE
-            win32file.EscapeCommFunction(self.hComPort, win32file.SETRTS)
+            win32.EscapeCommFunction(self.hComPort, win32.SETRTS)
         else:
             self._rtsState = win32file.RTS_CONTROL_DISABLE
-            win32file.EscapeCommFunction(self.hComPort, win32file.CLRRTS)
+            win32.EscapeCommFunction(self.hComPort, win32.CLRRTS)
 
     def setDTR(self, level=1):
         """Set terminal status line: Data Terminal Ready"""
         if not self.hComPort: raise portNotOpenError
         if level:
             self._dtrState = win32file.DTR_CONTROL_ENABLE
-            win32file.EscapeCommFunction(self.hComPort, win32file.SETDTR)
+            win32.EscapeCommFunction(self.hComPort, win32.SETDTR)
         else:
             self._dtrState = win32file.DTR_CONTROL_DISABLE
-            win32file.EscapeCommFunction(self.hComPort, win32file.CLRDTR)
+            win32.EscapeCommFunction(self.hComPort, win32.CLRDTR)
+
+    def _GetCommModemStatus(self):
+        stat = win32.DWORD()
+        win32.GetCommModemStatus(self.hComPort, ctypes.byref(stat))
+        return stat.value
 
     def getCTS(self):
         """Read terminal status line: Clear To Send"""
         if not self.hComPort: raise portNotOpenError
-        return MS_CTS_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+        return win32.MS_CTS_ON & self._GetCommModemStatus() != 0
 
     def getDSR(self):
         """Read terminal status line: Data Set Ready"""
         if not self.hComPort: raise portNotOpenError
-        return MS_DSR_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+        return win32.MS_DSR_ON & self._GetCommModemStatus() != 0
 
     def getRI(self):
         """Read terminal status line: Ring Indicator"""
         if not self.hComPort: raise portNotOpenError
-        return MS_RING_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+        return win32.MS_RING_ON & self._GetCommModemStatus() != 0
 
     def getCD(self):
         """Read terminal status line: Carrier Detect"""
         if not self.hComPort: raise portNotOpenError
-        return MS_RLSD_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+        return win32.MS_RLSD_ON & self._GetCommModemStatus() != 0
 
     # - - platform specific - - - -
 
@@ -315,13 +329,16 @@
         """Platform specific - set flow state."""
         if not self.hComPort: raise portNotOpenError
         if level:
-            win32file.EscapeCommFunction(self.hComPort, win32file.SETXON)
+            win32.EscapeCommFunction(self.hComPort, win32.SETXON)
         else:
-            win32file.EscapeCommFunction(self.hComPort, win32file.SETXOFF)
+            win32.EscapeCommFunction(self.hComPort, win32.SETXOFF)
 
     def outWaiting(self):
         """return how many characters the in the outgoing buffer"""
-        flags, comstat = win32file.ClearCommError(self.hComPort)
+        flags = win32.DWORD()
+        comstat = win32.COMSTAT()
+        if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)):
+            raise SerialException('call to ClearCommError failed')
         return comstat.cbOutQue
 
 
diff --git a/pyserial/serial/win32.py b/pyserial/serial/win32.py
new file mode 100644
index 0000000..55dec16
--- /dev/null
+++ b/pyserial/serial/win32.py
@@ -0,0 +1,273 @@
+from ctypes import *
+from ctypes.wintypes import HANDLE
+from ctypes.wintypes import BOOL
+from ctypes.wintypes import LPCWSTR
+_stdcall_libraries = {}
+_stdcall_libraries['kernel32'] = WinDLL('kernel32')
+from ctypes.wintypes import DWORD
+from ctypes.wintypes import WORD
+from ctypes.wintypes import BYTE
+
+
+class _SECURITY_ATTRIBUTES(Structure):
+    pass
+LPSECURITY_ATTRIBUTES = POINTER(_SECURITY_ATTRIBUTES)
+
+CreateEventW = _stdcall_libraries['kernel32'].CreateEventW
+CreateEventW.restype = HANDLE
+CreateEventW.argtypes = [LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR]
+CreateEvent = CreateEventW # alias
+CreateFileW = _stdcall_libraries['kernel32'].CreateFileW
+CreateFileW.restype = HANDLE
+CreateFileW.argtypes = [LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE]
+CreateFile = CreateFileW # alias
+
+class _OVERLAPPED(Structure):
+    pass
+OVERLAPPED = _OVERLAPPED
+
+class _COMSTAT(Structure):
+    pass
+COMSTAT = _COMSTAT
+
+class _DCB(Structure):
+    pass
+DCB = _DCB
+
+class _COMMTIMEOUTS(Structure):
+    pass
+COMMTIMEOUTS = _COMMTIMEOUTS
+
+GetLastError = _stdcall_libraries['kernel32'].GetLastError
+GetLastError.restype = DWORD
+GetLastError.argtypes = []
+
+LPOVERLAPPED = POINTER(_OVERLAPPED)
+LPDWORD = POINTER(DWORD)
+
+GetOverlappedResult = _stdcall_libraries['kernel32'].GetOverlappedResult
+GetOverlappedResult.restype = BOOL
+GetOverlappedResult.argtypes = [HANDLE, LPOVERLAPPED, LPDWORD, BOOL]
+
+ResetEvent = _stdcall_libraries['kernel32'].ResetEvent
+ResetEvent.restype = BOOL
+ResetEvent.argtypes = [HANDLE]
+
+LPCVOID = c_void_p
+
+WriteFile = _stdcall_libraries['kernel32'].WriteFile
+WriteFile.restype = BOOL
+WriteFile.argtypes = [HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED]
+
+LPVOID = c_void_p
+
+ReadFile = _stdcall_libraries['kernel32'].ReadFile
+ReadFile.restype = BOOL
+ReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED]
+
+CloseHandle = _stdcall_libraries['kernel32'].CloseHandle
+CloseHandle.restype = BOOL
+CloseHandle.argtypes = [HANDLE]
+
+ClearCommBreak = _stdcall_libraries['kernel32'].ClearCommBreak
+ClearCommBreak.restype = BOOL
+ClearCommBreak.argtypes = [HANDLE]
+
+LPCOMSTAT = POINTER(_COMSTAT)
+
+ClearCommError = _stdcall_libraries['kernel32'].ClearCommError
+ClearCommError.restype = BOOL
+ClearCommError.argtypes = [HANDLE, LPDWORD, LPCOMSTAT]
+
+SetupComm = _stdcall_libraries['kernel32'].SetupComm
+SetupComm.restype = BOOL
+SetupComm.argtypes = [HANDLE, DWORD, DWORD]
+
+EscapeCommFunction = _stdcall_libraries['kernel32'].EscapeCommFunction
+EscapeCommFunction.restype = BOOL
+EscapeCommFunction.argtypes = [HANDLE, DWORD]
+
+GetCommModemStatus = _stdcall_libraries['kernel32'].GetCommModemStatus
+GetCommModemStatus.restype = BOOL
+GetCommModemStatus.argtypes = [HANDLE, LPDWORD]
+
+LPDCB = POINTER(_DCB)
+
+GetCommState = _stdcall_libraries['kernel32'].GetCommState
+GetCommState.restype = BOOL
+GetCommState.argtypes = [HANDLE, LPDCB]
+
+LPCOMMTIMEOUTS = POINTER(_COMMTIMEOUTS)
+
+GetCommTimeouts = _stdcall_libraries['kernel32'].GetCommTimeouts
+GetCommTimeouts.restype = BOOL
+GetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS]
+
+PurgeComm = _stdcall_libraries['kernel32'].PurgeComm
+PurgeComm.restype = BOOL
+PurgeComm.argtypes = [HANDLE, DWORD]
+
+SetCommBreak = _stdcall_libraries['kernel32'].SetCommBreak
+SetCommBreak.restype = BOOL
+SetCommBreak.argtypes = [HANDLE]
+
+SetCommMask = _stdcall_libraries['kernel32'].SetCommMask
+SetCommMask.restype = BOOL
+SetCommMask.argtypes = [HANDLE, DWORD]
+
+SetCommState = _stdcall_libraries['kernel32'].SetCommState
+SetCommState.restype = BOOL
+SetCommState.argtypes = [HANDLE, LPDCB]
+
+SetCommTimeouts = _stdcall_libraries['kernel32'].SetCommTimeouts
+SetCommTimeouts.restype = BOOL
+SetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS]
+
+ONESTOPBIT = 0 # Variable c_int
+TWOSTOPBITS = 2 # Variable c_int
+ONE5STOPBITS = 1
+
+NOPARITY = 0 # Variable c_int
+ODDPARITY = 1 # Variable c_int
+EVENPARITY = 2 # Variable c_int
+MARKPARITY = 3
+SPACEPARITY = 4
+
+MS_DSR_ON = 32 # Variable c_ulong
+EV_RING = 256 # Variable c_int
+EV_PERR = 512 # Variable c_int
+EV_ERR = 128 # Variable c_int
+SETXOFF = 1 # Variable c_int
+EV_RXCHAR = 1 # Variable c_int
+GENERIC_WRITE = 1073741824 # Variable c_long
+PURGE_TXCLEAR = 4 # Variable c_int
+FILE_FLAG_OVERLAPPED = 1073741824 # Variable c_int
+EV_DSR = 16 # Variable c_int
+MAXDWORD = 4294967295L # Variable c_uint
+EV_RLSD = 32 # Variable c_int
+ERROR_IO_PENDING = 997 # Variable c_long
+MS_CTS_ON = 16 # Variable c_ulong
+EV_EVENT1 = 2048 # Variable c_int
+RTS_CONTROL_HANDSHAKE = 2 # Variable c_int
+EV_RX80FULL = 1024 # Variable c_int
+PURGE_RXABORT = 2 # Variable c_int
+FILE_ATTRIBUTE_NORMAL = 128 # Variable c_int
+PURGE_TXABORT = 1 # Variable c_int
+SETXON = 2 # Variable c_int
+OPEN_EXISTING = 3 # Variable c_int
+RTS_CONTROL_ENABLE = 1 # Variable c_int
+MS_RING_ON = 64 # Variable c_ulong
+EV_TXEMPTY = 4 # Variable c_int
+EV_RXFLAG = 2 # Variable c_int
+DTR_CONTROL_HANDSHAKE = 2 # Variable c_int
+DTR_CONTROL_ENABLE = 1 # Variable c_int
+MS_RLSD_ON = 128 # Variable c_ulong
+GENERIC_READ = 2147483648L # Variable c_ulong
+EV_EVENT2 = 4096 # Variable c_int
+EV_CTS = 8 # Variable c_int
+EV_BREAK = 64 # Variable c_int
+PURGE_RXCLEAR = 8 # Variable c_int
+ULONG_PTR = c_ulong
+
+class N11_OVERLAPPED4DOLLAR_48E(Union):
+    pass
+class N11_OVERLAPPED4DOLLAR_484DOLLAR_49E(Structure):
+    pass
+N11_OVERLAPPED4DOLLAR_484DOLLAR_49E._fields_ = [
+    ('Offset', DWORD),
+    ('OffsetHigh', DWORD),
+]
+
+PVOID = c_void_p
+
+N11_OVERLAPPED4DOLLAR_48E._anonymous_ = ['_0']
+N11_OVERLAPPED4DOLLAR_48E._fields_ = [
+    ('_0', N11_OVERLAPPED4DOLLAR_484DOLLAR_49E),
+    ('Pointer', PVOID),
+]
+_OVERLAPPED._anonymous_ = ['_0']
+_OVERLAPPED._fields_ = [
+    ('Internal', ULONG_PTR),
+    ('InternalHigh', ULONG_PTR),
+    ('_0', N11_OVERLAPPED4DOLLAR_48E),
+    ('hEvent', HANDLE),
+]
+_SECURITY_ATTRIBUTES._fields_ = [
+    ('nLength', DWORD),
+    ('lpSecurityDescriptor', LPVOID),
+    ('bInheritHandle', BOOL),
+]
+_COMSTAT._fields_ = [
+    ('fCtsHold', DWORD, 1),
+    ('fDsrHold', DWORD, 1),
+    ('fRlsdHold', DWORD, 1),
+    ('fXoffHold', DWORD, 1),
+    ('fXoffSent', DWORD, 1),
+    ('fEof', DWORD, 1),
+    ('fTxim', DWORD, 1),
+    ('fReserved', DWORD, 25),
+    ('cbInQue', DWORD),
+    ('cbOutQue', DWORD),
+]
+_DCB._fields_ = [
+    ('DCBlength', DWORD),
+    ('BaudRate', DWORD),
+    ('fBinary', DWORD, 1),
+    ('fParity', DWORD, 1),
+    ('fOutxCtsFlow', DWORD, 1),
+    ('fOutxDsrFlow', DWORD, 1),
+    ('fDtrControl', DWORD, 2),
+    ('fDsrSensitivity', DWORD, 1),
+    ('fTXContinueOnXoff', DWORD, 1),
+    ('fOutX', DWORD, 1),
+    ('fInX', DWORD, 1),
+    ('fErrorChar', DWORD, 1),
+    ('fNull', DWORD, 1),
+    ('fRtsControl', DWORD, 2),
+    ('fAbortOnError', DWORD, 1),
+    ('fDummy2', DWORD, 17),
+    ('wReserved', WORD),
+    ('XonLim', WORD),
+    ('XoffLim', WORD),
+    ('ByteSize', BYTE),
+    ('Parity', BYTE),
+    ('StopBits', BYTE),
+    ('XonChar', c_char),
+    ('XoffChar', c_char),
+    ('ErrorChar', c_char),
+    ('EofChar', c_char),
+    ('EvtChar', c_char),
+    ('wReserved1', WORD),
+]
+_COMMTIMEOUTS._fields_ = [
+    ('ReadIntervalTimeout', DWORD),
+    ('ReadTotalTimeoutMultiplier', DWORD),
+    ('ReadTotalTimeoutConstant', DWORD),
+    ('WriteTotalTimeoutMultiplier', DWORD),
+    ('WriteTotalTimeoutConstant', DWORD),
+]
+__all__ = ['GetLastError', 'MS_CTS_ON', 'FILE_ATTRIBUTE_NORMAL',
+           'DTR_CONTROL_ENABLE', '_COMSTAT', 'MS_RLSD_ON',
+           'GetOverlappedResult', 'SETXON', 'PURGE_TXABORT',
+           'PurgeComm', 'N11_OVERLAPPED4DOLLAR_48E', 'EV_RING',
+           'ONESTOPBIT', 'SETXOFF', 'PURGE_RXABORT', 'GetCommState',
+           'RTS_CONTROL_ENABLE', '_DCB', 'CreateEvent',
+           '_COMMTIMEOUTS', '_SECURITY_ATTRIBUTES', 'EV_DSR',
+           'EV_PERR', 'EV_RXFLAG', 'OPEN_EXISTING', 'DCB',
+           'FILE_FLAG_OVERLAPPED', 'EV_CTS', 'SetupComm',
+           'LPOVERLAPPED', 'EV_TXEMPTY', 'ClearCommBreak',
+           'LPSECURITY_ATTRIBUTES', 'SetCommBreak', 'SetCommTimeouts',
+           'COMMTIMEOUTS', 'ODDPARITY', 'EV_RLSD',
+           'GetCommModemStatus', 'EV_EVENT2', 'PURGE_TXCLEAR',
+           'EV_BREAK', 'EVENPARITY', 'LPCVOID', 'COMSTAT', 'ReadFile',
+           'PVOID', '_OVERLAPPED', 'WriteFile', 'GetCommTimeouts',
+           'ResetEvent', 'EV_RXCHAR', 'LPCOMSTAT', 'ClearCommError',
+           'ERROR_IO_PENDING', 'EscapeCommFunction', 'GENERIC_READ',
+           'RTS_CONTROL_HANDSHAKE', 'OVERLAPPED',
+           'DTR_CONTROL_HANDSHAKE', 'PURGE_RXCLEAR', 'GENERIC_WRITE',
+           'LPDCB', 'CreateEventW', 'SetCommMask', 'EV_EVENT1',
+           'SetCommState', 'LPVOID', 'CreateFileW', 'LPDWORD',
+           'EV_RX80FULL', 'TWOSTOPBITS', 'LPCOMMTIMEOUTS', 'MAXDWORD',
+           'MS_DSR_ON', 'MS_RING_ON',
+           'N11_OVERLAPPED4DOLLAR_484DOLLAR_49E', 'EV_ERR',
+           'ULONG_PTR', 'CreateFile', 'NOPARITY', 'CloseHandle']