def read(self, size=1):
     """Read size bytes from the serial port. If a timeout is set it may
        return less characters as requested. With no timeout it will block
        until the requested number of bytes is read."""
     if not self.hComPort: raise portNotOpenError
     if size > 0:
         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:
                 buf = ctypes.create_string_buffer(n)
                 rc = win32.DWORD()
                 err = win32.ReadFile(self.hComPort, buf, n, ctypes.byref(rc), ctypes.byref(self._overlappedRead))
                 if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
                     raise SerialException("ReadFile failed (%r)" % ctypes.WinError())
                 err = win32.WaitForSingleObject(self._overlappedRead.hEvent, win32.INFINITE)
                 read = buf.raw[:rc.value]
             else:
                 read = bytes()
         else:
             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 (%r)" % ctypes.WinError())
             err = win32.GetOverlappedResult(self.hComPort, ctypes.byref(self._overlappedRead), ctypes.byref(rc), True)
             read = buf.raw[:rc.value]
     else:
         read = bytes()
     return bytes(read)
Пример #2
0
 def write(self, data):
     """Output the given byte string over the serial port."""
     if not self.is_open:
         raise portNotOpenError
     #~ if not isinstance(data, (bytes, bytearray)):
     #~ raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))
     # convert data (needed in case of memoryview instance: Py 3.1 io lib), ctypes doesn't like memoryview
     data = to_bytes(data)
     if data:
         #~ win32event.ResetEvent(self._overlapped_write.hEvent)
         n = win32.DWORD()
         err = win32.WriteFile(self._port_handle, data, len(data),
                               ctypes.byref(n), self._overlapped_write)
         if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
             raise SerialException("WriteFile failed ({!r})".format(
                 ctypes.WinError()))
         if self._write_timeout != 0:  # if blocking (None) or w/ write timeout (>0)
             # Wait for the write to complete.
             #~ win32.WaitForSingleObject(self._overlapped_write.hEvent, win32.INFINITE)
             err = win32.GetOverlappedResult(self._port_handle,
                                             self._overlapped_write,
                                             ctypes.byref(n), True)
             if win32.GetLastError() == win32.ERROR_OPERATION_ABORTED:
                 return n.value  # canceled IO is no error
             if n.value != len(data):
                 raise writeTimeoutError
         return n.value
     else:
         return 0
Пример #3
0
 def read(self, size=1):
     """\
     Read size bytes from the serial port. If a timeout is set it may
     return less characters as requested. With no timeout it will block
     until the requested number of bytes is read.
     """
     if not self.is_open:
         raise portNotOpenError
     if size > 0:
         win32.ResetEvent(self._overlapped_read.hEvent)
         flags = win32.DWORD()
         comstat = win32.COMSTAT()
         if not win32.ClearCommError(self._port_handle, ctypes.byref(flags),
                                     ctypes.byref(comstat)):
             raise SerialException('call to ClearCommError failed')
         n = min(comstat.cbInQue, size) if self.timeout == 0 else size
         if n > 0:
             buf = ctypes.create_string_buffer(n)
             rc = win32.DWORD()
             read_ok = win32.ReadFile(self._port_handle, buf, n,
                                      ctypes.byref(rc),
                                      ctypes.byref(self._overlapped_read))
             if not read_ok and win32.GetLastError() not in (
                     win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING):
                 raise SerialException("ReadFile failed ({!r})".format(
                     ctypes.WinError()))
             win32.GetOverlappedResult(self._port_handle,
                                       ctypes.byref(self._overlapped_read),
                                       ctypes.byref(rc), True)
             read = buf.raw[:rc.value]
         else:
             read = bytes()
     else:
         read = bytes()
     return bytes(read)
Пример #4
0
    def write(self, data):
        """Output the given byte string over the serial port."""
        if not self.is_open:
            raise PortNotOpenError()
        #~ if not isinstance(data, (bytes, bytearray)):
        #~ raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))
        # convert data (needed in case of memoryview instance: Py 3.1 io lib), ctypes doesn't like memoryview
        data = to_bytes(data)
        if data:
            #~ win32event.ResetEvent(self._overlapped_write.hEvent)
            n = win32.DWORD()
            success = win32.WriteFile(self._port_handle, data, len(data),
                                      ctypes.byref(n), self._overlapped_write)
            if self._write_timeout != 0:  # if blocking (None) or w/ write timeout (>0)
                if not success and win32.GetLastError() not in (
                        win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING):
                    raise SerialException("WriteFile failed ({!r})".format(
                        ctypes.WinError()))

                # Wait for the write to complete.
                #~ win32.WaitForSingleObject(self._overlapped_write.hEvent, win32.INFINITE)
                win32.GetOverlappedResult(self._port_handle,
                                          self._overlapped_write,
                                          ctypes.byref(n), True)
                if win32.GetLastError() == win32.ERROR_OPERATION_ABORTED:
                    return n.value  # canceled IO is no error
                if n.value != len(data):
                    raise SerialTimeoutException('Write timeout')
                return n.value
            else:
                errorcode = win32.ERROR_SUCCESS if success else win32.GetLastError(
                )
                if errorcode in (win32.ERROR_INVALID_USER_BUFFER,
                                 win32.ERROR_NOT_ENOUGH_MEMORY,
                                 win32.ERROR_OPERATION_ABORTED):
                    return 0
                elif errorcode in (win32.ERROR_SUCCESS,
                                   win32.ERROR_IO_PENDING):
                    # no info on true length provided by OS function in async mode
                    return len(data)
                else:
                    raise SerialException("WriteFile failed ({!r})".format(
                        ctypes.WinError()))
        else:
            return 0
Пример #5
0
    def _scsi_operation(self, pbuf, size, read, timeout=10):
        sptdwb = SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER()
        ctypes.memset(ctypes.addressof(sptdwb), 0, ctypes.sizeof(sptdwb))

        sptdwb.sptd.Length = ctypes.sizeof(SCSI_PASS_THROUGH_DIRECT)
        sptdwb.sptd.PathId = 0
        sptdwb.sptd.TargetId = 1
        sptdwb.sptd.Lun = 0
        sptdwb.sptd.CdbLength = CDB10GENERIC_LENGTH
        sptdwb.sptd.SenseInfoLength = 0
        sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN if read else SCSI_IOCTL_DATA_OUT
        sptdwb.sptd.DataTransferLength = size
        sptdwb.sptd.TimeOutValue = timeout
        sptdwb.sptd.DataBuffer = pbuf
        sptdwb.sptd.SenseInfoOffset = (
            SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER.ucSenseBuf.offset
        )
        sptdwb.sptd.Cdb[0] = 0xEF
        sptdwb.sptd.Cdb[1] = 0xFF if read else 0xFE

        length = DWORD(ctypes.sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER))
        returned = DWORD(0)

        result_ok = DeviceIoControl(
            self._port_handle,
            IOCTL_SCSI_PASS_THROUGH_DIRECT,
            ctypes.pointer(sptdwb),
            length,
            ctypes.pointer(sptdwb),
            length,
            ctypes.byref(returned),
            None,
        )

        if not result_ok and win32.GetLastError() not in (
            win32.ERROR_SUCCESS,
            win32.ERROR_IO_PENDING,
        ):
            raise WindowsSCSIInterfaceException(
                "DeviceIoControl failed ({!r})".format(ctypes.WinError())
            )

        if returned.value < (
            SCSI_PASS_THROUGH_DIRECT.ScsiStatus.offset
            + SCSI_PASS_THROUGH_DIRECT.ScsiStatus.size
        ):
            raise WindowsSCSIInterfaceException(
                "Not enough SCSI information returned to determine error"
            )

        if sptdwb.sptd.ScsiStatus != 0:
            raise WindowsSCSIInterfaceException(
                "SCSI Operation returned %d" % (sptdwb.sptd.ScsiStatus,)
            )

        return sptdwb.sptd.DataTransferLength
Пример #6
0
 def read(self, size=1):
     if not self.is_open:
         print("ERROR: Port is not opened")
         exit(1)
     if size > 0:
         win32.ResetEvent(self._overlapped_read.hEvent)
         flags = win32.DWORD()
         comstat = win32.COMSTAT()
         if not win32.ClearCommError(self._port_handle, ctypes.byref(flags),
                                     ctypes.byref(comstat)):
             print("ERROR: ClearCommError failed ({!r})".format(
                 ctypes.WinError()))
             exit(1)
         n = min(comstat.cbInQue, size) if self.timeout == 0 else size
         if n > 0:
             buf = ctypes.create_string_buffer(n)
             rc = win32.DWORD()
             read_ok = win32.ReadFile(self._port_handle, buf, n,
                                      ctypes.byref(rc),
                                      ctypes.byref(self._overlapped_read))
             if not read_ok and win32.GetLastError() not in (
                     win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING):
                 print("ERROR: ReadFile failed ({!r})".format(
                     ctypes.WinError()))
                 exit(1)
             if not read_ok:
                 print("ERROR: Something bad")
                 return buf.value
             result_ok = win32.GetOverlappedResult(
                 self._port_handle, ctypes.byref(self._overlapped_read),
                 ctypes.byref(rc), True)
             if not result_ok:
                 if win32.GetLastError() != win32.ERROR_OPERATION_ABORTED:
                     raise SerialException(
                         "GetOverlappedResult failed ({!r})".format(
                             ctypes.WinError()))
             read = buf.raw[:rc.value]
         else:
             read = bytes()
     else:
         read = bytes()
     return bytes(read)
Пример #7
0
 def _cancel_overlapped_io(self, overlapped):
     """Cancel a blocking read operation, may be called from other thread"""
     # check if read operation is pending
     rc = win32.DWORD()
     err = win32.GetOverlappedResult(self._port_handle,
                                     ctypes.byref(overlapped),
                                     ctypes.byref(rc), False)
     if not err and win32.GetLastError() in (win32.ERROR_IO_PENDING,
                                             win32.ERROR_IO_INCOMPLETE):
         # cancel, ignoring any errors (e.g. it may just have finished on its own)
         win32.CancelIoEx(self._port_handle, overlapped)
Пример #8
0
 def write(self, data):
     if not self.is_open:
         print("Port is not opened")
         exit(1)
     data = to_bytes(data)
     if data:
         n = win32.DWORD()
         success = win32.WriteFile(self._port_handle, data, len(data),
                                   ctypes.byref(n), self._overlapped_write)
         if self._write_timeout != 0:
             if not success and win32.GetLastError() not in (
                     win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING):
                 print("WriteFile failed ({!r})".format(ctypes.WinError()))
                 exit(1)
             win32.GetOverlappedResult(self._port_handle,
                                       self._overlapped_write,
                                       ctypes.byref(n), True)
             if win32.GetLastError() == win32.ERROR_OPERATION_ABORTED:
                 return n.value
             if n.value != len(data):
                 print("Write timeout")
                 exit(1)
             return n.value
         else:
             errorcode = win32.ERROR_SUCCESS if success else win32.GetLastError(
             )
             if errorcode in (win32.ERROR_INVALID_USER_BUFFER,
                              win32.ERROR_NOT_ENOUGH_MEMORY,
                              win32.ERROR_OPERATION_ABORTED):
                 return 0
             elif errorcode in (win32.ERROR_SUCCESS,
                                win32.ERROR_IO_PENDING):
                 # no info on true length provided by OS function in async mode
                 return len(data)
             else:
                 print("WriteFile failed ({!r})".format(ctypes.WinError()))
                 exit(1)
     else:
         return 0