diff --git a/CHANGES.md b/CHANGES.md
index c38195d2ff..26dd51b148 100755
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -7,6 +7,7 @@ Next Release (4.2.1)
Features
--------
+* [#510](https://github.com/java-native-access/jna/pull/510): Added `GetCommState`, `GetCommTimeouts` `SetCommState` and `SetCommTimeouts` to `com.sun.jna.platform.win32.Kernel32`. Added `DCB` structure to `com.sun.jna.platform.win32.WinBase` - [@MBollig](https://github.com/MBollig)
Bug Fixes
---------
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
index 106a654e0c..87af3296d5 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
@@ -14,6 +14,7 @@
import com.sun.jna.Native;
import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.W32APIOptions;
@@ -2729,4 +2730,87 @@ boolean GetVolumePathNamesForVolumeName(String lpszVolumeName,
* @see FindVolumeClose
*/
boolean FindVolumeClose(HANDLE hFindVolume);
+
+ /**
+ * Retrieves the current control settings for a specified communications
+ * device.
+ *
+ * @param hFile
+ * [in] A handle to the communications device.
+ * The
+ * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)}
+ * function returns this {@link HANDLE}.
+ * @param lpDCB
+ * [in, out] A pointer to a {@link WinBase.DCB} structure that
+ * receives the control settings information.
+ *
+ * @return If the function succeeds, the return value is nonzero.
+ * If the function fails, the return value is zero. To get extended
+ * error information, call {@link Kernel32#GetLastError()}.
+ *
+ */
+ boolean GetCommState(HANDLE hFile, WinBase.DCB lpDCB);
+
+ /**
+ *
+ * Retrieves the time-out parameters for all read and write operations on a
+ * specified communications device.
+ *
+ * For more information about time-out values for communications devices,
+ * see the {@link Kernel32#SetCommTimeouts} function.
+ *
+ * @param hFile
+ * [in] A handle to the communications device. The
+ * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)}
+ * function returns this handle.
+ *
+ * @param lpCommTimeouts
+ * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure in
+ * which the time-out information is returned.
+ * @return If the function succeeds, the return value is nonzero.
+ *
+ * If the function fails, the return value is zero. To get extended
+ * error information, call {@link Kernel32#GetLastError()}.
+ *
+ *
+ *
+ */
+ boolean GetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts);
+
+ /**
+ * Configures a communications device according to the specifications in a
+ * device-control block (a {@link WinBase.DCB} structure). The function
+ * reinitializes all hardware and control settings, but it does not empty
+ * output or input queues.
+ *
+ * @param hFile
+ * [in] A handle to the communications device. The
+ * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)}
+ * function returns this handle.
+ * @param lpDCB
+ * [in] A pointer to a {@link WinBase.DCB} structure that
+ * contains the configuration information for the specified
+ * communications device.
+ * @return If the function succeeds, the return value is nonzero. If the
+ * function fails, the return value is zero. To get extended error
+ * information, call {@link Kernel32#GetLastError()}.
+ */
+ boolean SetCommState(HANDLE hFile, WinBase.DCB lpDCB);
+
+ /**
+ * Sets the time-out parameters for all read and write operations on a
+ * specified communications device.
+ *
+ * @param hFile
+ * [in] A handle to the communications device. The
+ * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)}
+ * function returns this handle.
+ * @param LPCOMMTIMEOUTS
+ * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure
+ * that contains the new time-out values.
+ * @return If the function succeeds, the return value is nonzero.
+ * If the function fails, the return value is zero. To get extended
+ * error information, call {@link Kernel32#GetLastError()}.
+ */
+ boolean SetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts);
}
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java
index 2a47213bc8..545ddacbb4 100755
--- a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java
@@ -1057,4 +1057,650 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext,
int NMPWAIT_USE_DEFAULT_WAIT=0x00000000;
int NMPWAIT_NOWAIT=0x00000001;
int NMPWAIT_WAIT_FOREVER=0xffffffff;
+
+
+
+ /**
+ *
+ * Contains the time-out parameters for a communications device. The
+ * parameters determine the behavior of
+ * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)}
+ * , {@link Kernel32#WriteFile(com.sun.jna.platform.win32.WinNT.HANDLE,
+ * byte[], int, com.sun.jna.ptr.IntByReference,
+ * com.sun.jna.platform.win32.WinBase.OVERLAPPED))}, ReadFileEx, and
+ * WriteFileEx operations on the device.
+ *
+ *
+ * Remarks
+ * If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier
+ * to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than
+ * zero and less than MAXDWORD, one of the following occurs when the
+ * ReadFile function is called:
+ *
If there are any bytes in the input buffer, ReadFile returns
+ * immediately with the bytes in the buffer.
+ * If there are no bytes in the input buffer, ReadFile waits until a
+ * byte arrives and then returns immediately.
+ * If no bytes arrive within the time specified by
+ * ReadTotalTimeoutConstant, ReadFile times out.
+ *
+ * @author Markus
+ *
+ */
+ public static class COMMTIMEOUTS extends Structure {
+ /**
+ *
+ * The maximum time allowed to elapse before the arrival of the next
+ * byte on the communications line, in milliseconds. If the interval
+ * between the arrival of any two bytes exceeds this amount, the
+ * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)}
+ * operation is completed and any buffered data is returned. A value of
+ * zero indicates that interval time-outs are not used.
+ *
+ * A value of MAXDWORD, combined with zero values for both the
+ * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} and
+ * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} members, specifies
+ * that the read operation is to return immediately with the bytes that
+ * have already been received, even if no bytes have been received.
+ *
+ */
+ public DWORD ReadIntervalTimeout;
+
+ /**
+ * The multiplier used to calculate the total time-out period for read
+ * operations, in milliseconds. For each read operation, this value is
+ * multiplied by the requested number of bytes to be read.
+ */
+ public DWORD ReadTotalTimeoutMultiplier;
+
+ /**
+ * A constant used to calculate the total time-out period for read
+ * operations, in milliseconds. For each read operation, this value is
+ * added to the product of the
+ * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} member and the
+ * requested number of bytes.
+ *
+ * A value of zero for both the
+ * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} and
+ * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} members indicates that
+ * total time-outs are not used for read operations.
+ */
+ public DWORD ReadTotalTimeoutConstant;
+
+ /**
+ * The multiplier used to calculate the total time-out period for write
+ * operations, in milliseconds. For each write operation, this value is
+ * multiplied by the number of bytes to be written.
+ */
+ public DWORD WriteTotalTimeoutMultiplier;
+
+ /**
+ * A constant used to calculate the total time-out period for write
+ * operations, in milliseconds. For each write operation, this value is
+ * added to the product of the
+ * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} member and the
+ * number of bytes to be written.
+ *
+ * A value of zero for both the
+ * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} and
+ * {@link COMMTIMEOUTS#WriteTotalTimeoutConstant} members indicates that
+ * total time-outs are not used for write operations.
+ *
+ */
+ public DWORD WriteTotalTimeoutConstant;
+
+ protected List getFieldOrder() {
+ return Arrays.asList(new String[] { "ReadIntervalTimeout", "ReadTotalTimeoutMultiplier",
+ "ReadTotalTimeoutConstant", "WriteTotalTimeoutMultiplier", "WriteTotalTimeoutConstant" });
+ }
+ }
+
+
+
+ /**
+ * Defines the control setting for a serial communications device.
+ */
+ public static class DCB extends Structure {
+
+ /**
+ * Type is used to handle the bitfield of the DBC structure.
+ */
+ public static class DCBControllBits extends DWORD {
+ private static final long serialVersionUID = 8574966619718078579L;
+
+ @Override
+ public String toString() {
+ final StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append('<');
+ stringBuilder.append("fBinary:1=");
+ stringBuilder.append(getfBinary() ? '1' : '0');
+ stringBuilder.append(", fParity:1=");
+ stringBuilder.append(getfParity() ? '1' : '0');
+ stringBuilder.append(", fOutxCtsFlow:1=");
+ stringBuilder.append(getfOutxCtsFlow() ? '1' : '0');
+ stringBuilder.append(", fOutxDsrFlow:1=");
+ stringBuilder.append(getfOutxDsrFlow() ? '1' : '0');
+ stringBuilder.append(", fDtrControl:2=");
+ stringBuilder.append(getfDtrControl());
+ stringBuilder.append(", fDsrSensitivity:1=");
+ stringBuilder.append(getfDsrSensitivity() ? '1' : '0');
+ stringBuilder.append(", fTXContinueOnXoff:1=");
+ stringBuilder.append(getfTXContinueOnXoff() ? '1' : '0');
+ stringBuilder.append(", fOutX:1=");
+ stringBuilder.append(getfOutX() ? '1' : '0');
+ stringBuilder.append(", fInX:1=");
+ stringBuilder.append(getfInX() ? '1' : '0');
+ stringBuilder.append(", fErrorChar:1=");
+ stringBuilder.append(getfErrorChar() ? '1' : '0');
+ stringBuilder.append(", fNull:1=");
+ stringBuilder.append(getfNull() ? '1' : '0');
+ stringBuilder.append(", fRtsControl:2=");
+ stringBuilder.append(getfRtsControl());
+ stringBuilder.append(", fAbortOnError:1=");
+ stringBuilder.append(getfAbortOnError() ? '1' : '0');
+ stringBuilder.append(", fDummy2:17=");
+ stringBuilder.append(getfDummy2());
+ stringBuilder.append('>');
+ return stringBuilder.toString();
+ }
+
+ public boolean getfAbortOnError() {
+ return (this.intValue() & (0x01 << 14)) != 0x00;
+ }
+
+ public boolean getfBinary() {
+ return (this.intValue() & 0x01) != 0x00;
+ }
+
+ public boolean getfDsrSensitivity() {
+ return (this.intValue() & (0x01 << 6)) != 0x00;
+ }
+
+ public int getfDtrControl() {
+ return (this.intValue() >>> 4) & 0x03;
+ }
+
+ public boolean getfErrorChar() {
+ return (this.intValue() & (0x01 << 10)) != 0x00;
+ }
+
+ public boolean getfInX() {
+ return (this.intValue() & (0x01 << 9)) != 0x00;
+ }
+
+ public boolean getfNull() {
+ return (this.intValue() & (0x01 << 11)) != 0x00;
+ }
+
+ public boolean getfOutX() {
+ return (this.intValue() & (0x01 << 8)) != 0x00;
+ }
+
+ public boolean getfOutxCtsFlow() {
+ return (this.intValue() & (0x01 << 2)) != 0x00;
+ }
+
+ public boolean getfOutxDsrFlow() {
+ return (this.intValue() & (0x01 << 3)) != 0x00;
+ }
+
+ public boolean getfParity() {
+ return (this.intValue() & (0x01 << 1)) != 0x00;
+ }
+
+ public int getfRtsControl() {
+ return (this.intValue() >>> 12) & 0x03;
+ }
+
+ public int getfDummy2() {
+ return (this.intValue()>>>15) & 0x1FFFF;
+ }
+
+ public boolean getfTXContinueOnXoff() {
+ return (this.intValue() & (0x01 << 7)) != 0x00;
+ }
+
+ /**
+ * If this member is TRUE, the driver terminates all read and write
+ * operations with an error status if an error occurs.
+ * The driver will not accept any further communications operations
+ * until the application has acknowledged the error by calling the
+ * ClearCommError function.
+ *
+ * @param fAbortOnError
+ */
+ public void setfAbortOnError(boolean fAbortOnError) {
+ int tmp = leftShiftMask(fAbortOnError ? 1 : 0, (byte)14, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * If this member is TRUE, binary mode is enabled.
+ * Windows does not support nonbinary mode transfers, so this member
+ * must be TRUE.
+ *
+ * @param fBinary
+ */
+ public void setfBinary(boolean fBinary) {
+ int tmp = leftShiftMask(fBinary ? 1 : 0, (byte)0, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * If this member is TRUE, the communications driver is sensitive to the
+ * state of the DSR signal.
+ * The driver ignores any bytes received, unless the DSR modem input
+ * line is high.
+ *
+ * @param fDsrSensitivity
+ */
+ public void setfDsrSensitivity(boolean fDsrSensitivity) {
+ int tmp = leftShiftMask(fDsrSensitivity ? 1 : 0, (byte)6, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * The DTR (data-terminal-ready) flow control. This member can be one of
+ * the following values.
+ * {@link WinBase#DTR_CONTROL_DISABLE}
+ * {@link WinBase#DTR_CONTROL_ENABLE}
+ * {@link WinBase#DTR_CONTROL_HANDSHAKE}
+ *
+ * @param fOutxDsrFlow
+ * value to set
+ */
+ public void setfDtrControl(int fOutxDsrFlow) {
+ int tmp = leftShiftMask(fOutxDsrFlow, (byte)4, 0x03, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * Indicates whether bytes received with parity errors are replaced with
+ * the character specified by the ErrorChar member.
+ * If this member is TRUE and the fParity member is TRUE, replacement
+ * occurs.
+ *
+ * @param fErrorChar
+ */
+ public void setfErrorChar(boolean fErrorChar) {
+ int tmp = leftShiftMask(fErrorChar ? 1 : 0, (byte)10, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * Indicates whether XON/XOFF flow control is used during reception.
+ * If this member is TRUE, the XoffChar character is sent when the input
+ * buffer comes within XoffLim bytes of being full, and the XonChar
+ * character is sent when the input buffer comes within XonLim bytes of
+ * being empty.
+ *
+ * @param fInX
+ */
+ public void setfInX(boolean fInX) {
+ int tmp = leftShiftMask(fInX ? 1 : 0, (byte)9, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * If this member is TRUE, null bytes are discarded when received.
+ *
+ * @param fNull
+ */
+ public void setfNull(boolean fNull) {
+ int tmp = leftShiftMask(fNull ? 1 : 0, (byte)11, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * Indicates whether XON/XOFF flow control is used during transmission.
+ *
+ * If this member is TRUE, transmission stops when the XoffChar
+ * character is received and starts again when the XonChar character is
+ * received.
+ *
+ * @param fOutX
+ */
+ public void setfOutX(boolean fOutX) {
+ int tmp = leftShiftMask(fOutX ? 1 : 0, (byte)8, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * If this member is TRUE, the CTS (clear-to-send) signal is monitored
+ * for output flow control.
+ * If this member is TRUE and CTS is turned off, output is suspended
+ * until CTS is sent again.
+ *
+ * @param fOutxCtsFlow
+ */
+ public void setfOutxCtsFlow(boolean fOutxCtsFlow) {
+ int tmp = leftShiftMask(fOutxCtsFlow ? 1 : 0, (byte)2, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * If this member is TRUE, the DSR (data-set-ready) signal is monitored
+ * for output flow control.
+ * If this member is TRUE and DSR is turned off, output is suspended
+ * until DSR is sent again.
+ *
+ * @param fOutxDsrFlow
+ */
+ public void setfOutxDsrFlow(boolean fOutxDsrFlow) {
+ int tmp = leftShiftMask(fOutxDsrFlow ? 1 : 0, (byte)3, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * If this member is TRUE, parity checking is performed and errors are
+ * reported.
+ *
+ * @param fParity
+ */
+ public void setfParity(boolean fParity) {
+ int tmp = leftShiftMask(fParity ? 1 : 0, (byte)1, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ *
+ * The RTS (request-to-send) flow control. This member can be one of the
+ * following values.
+ * {@link WinBase#RTS_CONTROL_DISABLE}
+ * {@link WinBase#RTS_CONTROL_ENABLE}
+ * {@link WinBase#RTS_CONTROL_HANDSHAKE}
+ * {@link WinBase#RTS_CONTROL_TOGGLE}
+ *
+ * @param fRtsControl
+ */
+ public void setfRtsControl(int fRtsControl) {
+ int tmp = leftShiftMask(fRtsControl, (byte)12, 0x03, this.intValue());
+ this.setValue(tmp);
+ }
+
+ /**
+ * If this member is TRUE, transmission continues after the input buffer
+ * has come within XoffLim bytes of being full and the driver has
+ * transmitted the XoffChar character to stop receiving bytes.
+ * If this member is FALSE, transmission does not continue until the
+ * input buffer is within XonLim bytes of being empty and the driver has
+ * transmitted the XonChar character to resume reception.
+ *
+ * @param fTXContinueOnXoff
+ */
+ public void setfTXContinueOnXoff(boolean fTXContinueOnXoff) {
+ int tmp = leftShiftMask(fTXContinueOnXoff ? 1 : 0, (byte)7, 0x01, this.intValue());
+ this.setValue(tmp);
+ }
+
+
+ private static int leftShiftMask(int valuetoset, byte shift, int mask, int storage) {
+ int tmp = storage;
+ tmp &= ~(mask << shift);
+ tmp |= ((valuetoset & mask) << shift);
+ return tmp;
+ }
+ }
+ /**
+ * The length of the structure, in bytes. The caller must set this
+ * member to sizeof(DCB).
+ */
+ public DWORD DCBlength;
+
+ /**
+ *
+ * The baud rate at which the communications device operates. This
+ * member can be an actual baud rate value, or one of the following
+ * indexes.
+ * {@link WinBase#CBR_110}
+ * {@link WinBase#CBR_300}
+ * {@link WinBase#CBR_600}
+ * {@link WinBase#CBR_1200}
+ * {@link WinBase#CBR_2400}
+ * {@link WinBase#CBR_4800}
+ * {@link WinBase#CBR_9600}
+ * {@link WinBase#CBR_14400}
+ * {@link WinBase#CBR_19200}
+ * {@link WinBase#CBR_38400}
+ * {@link WinBase#CBR_56000}
+ * {@link WinBase#CBR_128000}
+ * {@link WinBase#CBR_256000}
+ *
+ */
+ public DWORD BaudRate;
+
+ /**
+ * Contains all the bit wise setting entries.
+ */
+ public DCBControllBits controllBits;
+
+ /**
+ * Reserved; must be zero.
+ */
+ public WORD wReserved;
+
+ /**
+ * The minimum number of bytes in use allowed in the input buffer before
+ * flow control is activated to allow transmission by the sender. This
+ * assumes that either XON/XOFF, RTS, or DTR input flow control is
+ * specified in the fInX, fRtsControl, or fDtrControl members.
+ */
+ public WORD XonLim;
+
+ /**
+ * The minimum number of free bytes allowed in the input buffer before
+ * flow control is activated to inhibit the sender. Note that the sender
+ * may transmit characters after the flow control signal has been
+ * activated, so this value should never be zero. This assumes that
+ * either XON/XOFF, RTS, or DTR input flow control is specified in the
+ * fInX, fRtsControl, or fDtrControl members. The maximum number of
+ * bytes in use allowed is calculated by subtracting this value from the
+ * size, in bytes, of the input buffer.
+ */
+ public WORD XoffLim;
+
+ /**
+ * The number of bits in the bytes transmitted and received.
+ */
+ public BYTE ByteSize;
+
+ /**
+ *
+ * The parity scheme to be used. This member can be one of the following
+ * values.
+ * {@link WinBase#EVENPARITY}
+ * {@link WinBase#ODDPARITY}
+ * {@link WinBase#NOPARITY}
+ * {@link WinBase#SPACEPARITY}
+ * {@link WinBase#MARKPARITY}
+ */
+ public BYTE Parity;
+
+ /**
+ * The number of stop bits to be used. This member can be one of the
+ * following values.
+ * {@link WinBase#ONESTOPBIT}
+ * {@link WinBase#ONE5STOPBITS}
+ * {@link WinBase#TWOSTOPBITS}
+ */
+ public BYTE StopBits;
+
+ /**
+ * The value of the XON character for both transmission and reception.
+ */
+ public char XonChar;
+
+ /**
+ * The value of the XOFF character for both transmission and reception.
+ */
+ public char XoffChar;
+
+ /**
+ * The value of the character used to replace bytes received with a
+ * parity error.
+ */
+ public char ErrorChar;
+
+ /**
+ * The value of the character used to signal the end of data.
+ */
+ public char EofChar;
+
+ /**
+ * The value of the character used to signal an event.
+ */
+ public char EvtChar;
+
+ /**
+ * Reserved; do not use.
+ */
+ public WORD wReserved1;
+
+ public DCB() {
+ DCBlength = new DWORD(size());
+ }
+
+ protected List getFieldOrder() {
+ return Arrays.asList(new String[] { "DCBlength", "BaudRate", "controllBits", "wReserved", "XonLim",
+ "XoffLim", "ByteSize", "Parity", "StopBits", "XonChar", "XoffChar", "ErrorChar", "EofChar",
+ "EvtChar", "wReserved1" });
+ }
+ }
+
+ /**
+ * No parity.
+ */
+ int NOPARITY = 0;
+
+ /**
+ * Odd parity.
+ */
+ int ODDPARITY = 1;
+
+ /**
+ * Even parity.
+ */
+ int EVENPARITY = 2;
+
+ /**
+ * Mark parity.
+ */
+ int MARKPARITY = 3;
+
+ /**
+ * Space parity.
+ */
+ int SPACEPARITY = 4;
+
+ /**
+ * 1 stop bit.
+ */
+ int ONESTOPBIT = 0;
+
+ /**
+ * 1.5 stop bits.
+ */
+ int ONE5STOPBITS = 1;
+ /**
+ * 2 stop bits.
+ */
+ int TWOSTOPBITS = 2;
+ /**
+ * 110 bps.
+ */
+ int CBR_110 = 110;
+ /**
+ * 300 bps.
+ */
+ int CBR_300 = 300;
+ /**
+ * 600 bps.
+ */
+ int CBR_600 = 600;
+ /**
+ * 1200 bps.
+ */
+ int CBR_1200 = 1200;
+ /**
+ * 2400 bps.
+ */
+ int CBR_2400 = 2400;
+ /**
+ * 4800 bps.
+ */
+ int CBR_4800 = 4800;
+ /**
+ * 9600 bps.
+ */
+ int CBR_9600 = 9600;
+ /**
+ * 14400 bps.
+ */
+ int CBR_14400 = 14400;
+ /**
+ * 19200 bps.
+ */
+ int CBR_19200 = 19200;
+ /**
+ * 38400 bps.
+ */
+ int CBR_38400 = 38400;
+ /**
+ * 56000 bps.
+ */
+ int CBR_56000 = 56000;
+
+ /**
+ * 128000 bps.
+ */
+ int CBR_128000 = 128000;
+
+ /**
+ * 256000 bps.
+ */
+ int CBR_256000 = 256000;
+
+ /**
+ * Disables the DTR line when the device is opened and leaves it disabled.
+ */
+ int DTR_CONTROL_DISABLE = 0;
+
+ /**
+ * Enables the DTR line when the device is opened and leaves it on.
+ */
+ int DTR_CONTROL_ENABLE = 1;
+
+ /**
+ * Enables DTR handshaking.
+ * If handshaking is enabled, it is an error for the application to adjust
+ * the line by using the EscapeCommFunction function.
+ */
+ int DTR_CONTROL_HANDSHAKE = 2;
+
+ /**
+ * Disables the RTS line when the device is opened and leaves it disabled.
+ */
+ int RTS_CONTROL_DISABLE = 0;
+
+ /**
+ * Enables the RTS line when the device is opened and leaves it on.
+ */
+ int RTS_CONTROL_ENABLE = 1;
+
+ /**
+ * Enables RTS handshaking.
+ * The driver raises the RTS line when the "type-ahead" (input) buffer is
+ * less than one-half full and lowers the RTS line when the buffer is more
+ * than three-quarters full.
+ * If handshaking is enabled, it is an error for the application to adjust
+ * the line by using the EscapeCommFunction function.
+ */
+ int RTS_CONTROL_HANDSHAKE = 2;
+
+ /**
+ * Specifies that the RTS line will be high if bytes are available for
+ * transmission.
+ * After all buffered bytes have been sent, the RTS line will be low.
+ */
+ int RTS_CONTROL_TOGGLE = 3;;
+
}
diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java
index 97cb7e1407..1b4e743859 100644
--- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java
+++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java
@@ -767,4 +767,167 @@ public void testVirtualQueryEx() {
SIZE_T bytesRead = Kernel32.INSTANCE.VirtualQueryEx(selfHandle, Pointer.NULL, mbi, new SIZE_T(mbi.size()));
assertTrue(bytesRead.intValue() > 0);
}
+
+ public void testGetCommState() {
+ WinBase.DCB lpDCB = new WinBase.DCB();
+ // Here we test a com port that definitely does not exist!
+ HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy",
+ WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL,
+ null);
+
+ int lastError = Kernel32.INSTANCE.GetLastError();
+ assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND);
+ //try to read the com port state using the invalid handle
+ assertFalse(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB));
+ // Check if we can open a connection to com port1
+ // If yes, we try to read the com state
+ // If no com port exists we have to skip this test
+ handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0,
+ null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null);
+ lastError = Kernel32.INSTANCE.GetLastError();
+ if (WinNT.NO_ERROR == lastError) {
+ assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort));
+ try {
+ lpDCB = new WinBase.DCB();
+ assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB));
+ switch (lpDCB.BaudRate.intValue()) {
+ case WinBase.CBR_110:
+ case WinBase.CBR_1200:
+ case WinBase.CBR_128000:
+ case WinBase.CBR_14400:
+ case WinBase.CBR_19200:
+ case WinBase.CBR_2400:
+ case WinBase.CBR_256000:
+ case WinBase.CBR_300:
+ case WinBase.CBR_38400:
+ case WinBase.CBR_4800:
+ case WinBase.CBR_56000:
+ case WinBase.CBR_600:
+ case WinBase.CBR_9600:
+ break;
+ default:
+ fail("Received value of WinBase.DCB.BaudRate is not valid");
+ }
+ } finally {
+ Kernel32.INSTANCE.CloseHandle(handleSerialPort);
+ }
+ }
+ }
+
+ public void testSetCommState() {
+ WinBase.DCB lpDCB = new WinBase.DCB();
+ // Here we test a com port that definitely does not exist!
+ HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy",
+ WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL,
+ null);
+
+ int lastError = Kernel32.INSTANCE.GetLastError();
+ assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND);
+ // try to read the com port state using the invalid handle
+ assertFalse(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB));
+ // Check if we can open a connection to com port1
+ // If yes, we try to read the com state
+ // If no com port exists we have to skip this test
+ handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0,
+ null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null);
+ lastError = Kernel32.INSTANCE.GetLastError();
+ if (WinNT.NO_ERROR == lastError) {
+ assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort));
+ try {
+ lpDCB = new WinBase.DCB();
+ assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB));
+ DWORD oldBaudRate = new DWORD(lpDCB.BaudRate.longValue());
+
+ lpDCB.BaudRate = new DWORD(WinBase.CBR_110);
+
+ assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB));
+ WinBase.DCB lpNewDCB = new WinBase.DCB();
+ assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpNewDCB));
+
+ assertEquals(WinBase.CBR_110, lpNewDCB.BaudRate.intValue());
+
+ lpDCB.BaudRate = oldBaudRate;
+ assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB));
+
+ } finally {
+ Kernel32.INSTANCE.CloseHandle(handleSerialPort);
+ }
+ }
+ }
+
+ public void testGetCommTimeouts() {
+ WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS();
+
+ // Here we test a com port that definitely does not exist!
+ HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy",
+ WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL,
+ null);
+
+ int lastError = Kernel32.INSTANCE.GetLastError();
+ assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND);
+ // try to read the com port timeouts using the invalid handle
+ assertFalse(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts));
+
+ // Check if we can open a connection to com port1
+ // If yes, we try to read the com state
+ // If no com port exists we have to skip this test
+ handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0,
+ null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null);
+ lastError = Kernel32.INSTANCE.GetLastError();
+ if (WinNT.NO_ERROR == lastError) {
+ assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort));
+ try {
+ lpCommTimeouts = new WinBase.COMMTIMEOUTS();
+ assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts));
+ } finally {
+ Kernel32.INSTANCE.CloseHandle(handleSerialPort);
+ }
+ }
+ }
+
+ public void testSetCommTimeouts() {
+ WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS();
+
+ // Here we test a com port that definitely does not exist!
+ HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy",
+ WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL,
+ null);
+
+ int lastError = Kernel32.INSTANCE.GetLastError();
+ assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND);
+ // try to store the com port timeouts using the invalid handle
+ assertFalse(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts));
+
+ // Check if we can open a connection to com port1
+ // If yes, we try to store the com timeouts
+ // If no com port exists we have to skip this test
+ handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0,
+ null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null);
+ lastError = Kernel32.INSTANCE.GetLastError();
+ if (WinNT.NO_ERROR == lastError) {
+ assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort));
+ try {
+ lpCommTimeouts = new WinBase.COMMTIMEOUTS();
+ assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts));
+
+ DWORD oldReadIntervalTimeout = new DWORD(lpCommTimeouts.ReadIntervalTimeout.longValue());
+
+ lpCommTimeouts.ReadIntervalTimeout = new DWORD(20);
+
+ assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts));
+
+ WinBase.COMMTIMEOUTS lpNewCommTimeouts = new WinBase.COMMTIMEOUTS();
+ assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpNewCommTimeouts));
+
+ assertEquals(20, lpNewCommTimeouts.ReadIntervalTimeout.intValue());
+
+ lpCommTimeouts.ReadIntervalTimeout = oldReadIntervalTimeout;
+
+ assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts));
+
+ } finally {
+ Kernel32.INSTANCE.CloseHandle(handleSerialPort);
+ }
+ }
+ }
}
diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java
new file mode 100644
index 0000000000..cecb4b3b7d
--- /dev/null
+++ b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java
@@ -0,0 +1,136 @@
+/* Copyright (c) 2015 Markus Bollig, All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ */
+package com.sun.jna.platform.win32;
+
+import com.sun.jna.platform.win32.WinBase.DCB;
+
+import junit.framework.TestCase;
+
+public class WinBaseTest extends TestCase {
+
+ /**
+ * Test the mapping of the {@link DCB} structure.
+ * Particularly the mapping of the bit field is tested.
+ */
+ public void testDCBStructureMapping() {
+ //first we test if the WinBase.DCB bitfiled mapping works as expected.
+ WinBase.DCB lpDCB = new WinBase.DCB();
+ lpDCB.controllBits.setValue(0);
+
+ lpDCB.controllBits.setfBinary(true);
+ assertEquals(1, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfBinary());
+ lpDCB.controllBits.setfBinary(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfBinary());
+
+ lpDCB.controllBits.setfParity(true);
+ assertEquals(2, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfParity());
+ lpDCB.controllBits.setfParity(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfParity());
+
+ lpDCB.controllBits.setfOutxCtsFlow(true);
+ assertEquals(4, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow());
+ lpDCB.controllBits.setfOutxCtsFlow(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow());
+
+ lpDCB.controllBits.setfOutxDsrFlow(true);
+ assertEquals(8, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow());
+ lpDCB.controllBits.setfOutxDsrFlow(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow());
+
+ lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE);
+ assertEquals(16, lpDCB.controllBits.longValue());
+ assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl());
+ lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE);
+ assertEquals(32, lpDCB.controllBits.longValue());
+ assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl());
+ lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl());
+
+ lpDCB.controllBits.setfDsrSensitivity(true);
+ assertEquals(64, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfDsrSensitivity());
+ lpDCB.controllBits.setfDsrSensitivity(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfDsrSensitivity());
+
+ lpDCB.controllBits.setfTXContinueOnXoff(true);
+ assertEquals(128, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff());
+ lpDCB.controllBits.setfTXContinueOnXoff(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff());
+
+ lpDCB.controllBits.setfOutX(true);
+ assertEquals(256, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfOutX());
+ lpDCB.controllBits.setfOutX(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfOutX());
+
+ lpDCB.controllBits.setfInX(true);
+ assertEquals(512, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfInX());
+ lpDCB.controllBits.setfInX(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfInX());
+
+ lpDCB.controllBits.setfErrorChar(true);
+ assertEquals(1024, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfErrorChar());
+ lpDCB.controllBits.setfErrorChar(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfErrorChar());
+
+ lpDCB.controllBits.setfNull(true);
+ assertEquals(2048, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfNull());
+ lpDCB.controllBits.setfNull(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfNull());
+
+
+ lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE);
+ assertEquals(4096, lpDCB.controllBits.longValue());
+ assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl());
+ lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE);
+ assertEquals(8192, lpDCB.controllBits.longValue());
+ assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl());
+ lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE);
+ assertEquals(12288, lpDCB.controllBits.longValue());
+ assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl());
+ lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl());
+
+
+ lpDCB.controllBits.setfAbortOnError(true);
+ assertEquals(16384, lpDCB.controllBits.longValue());
+ assertEquals(true, lpDCB.controllBits.getfAbortOnError());
+ lpDCB.controllBits.setfAbortOnError(false);
+ assertEquals(0, lpDCB.controllBits.longValue());
+ assertEquals(false, lpDCB.controllBits.getfAbortOnError());
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(WinBaseTest.class);
+ }
+}
diff --git a/native/libffi/autogen.sh b/native/libffi/autogen.sh
index d270b984c1..822ff97d88 100755
--- a/native/libffi/autogen.sh
+++ b/native/libffi/autogen.sh
@@ -1,2 +1,2 @@
#!/bin/sh
-exec autoreconf -v -f -i
+exec autoreconf -v -f -i
\ No newline at end of file