jtermios.windows.WinAPI Maven / Gradle / Ivy
Show all versions of filo-firmata Show documentation
/*
* Copyright (c) 2011, Kustaa Nyholm / SpareTimeLabs
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
package jtermios.windows;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.*;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
import static jtermios.JTermios.JTermiosLogging.*;
/**
* This WinAPI class implements a simple wrapper API to access the Windows COM
* ports from Java.
*
* The purpose is to follow reasonably closely the WIN32 API so that COM port
* related C-code can be ported to Java almost as-is with little changes when
* this class is statically imported.
*
* This is a pure lightweight wrapper around WIN32 API calls with no added
* syntactic sugar, functionality or niceties.
*
* Here is a rude example:
*
*
*
* import static jtermios.windows.WinAPI.*;
* ...
* byte[] buffer = "Hello World".getBytes();
* HANDLE hcomm = CreateFileA( "COM5:", GENERIC_READ |GENERIC_WRITE, 0, null, 0, 0, null );
* int[] wrtn = {0};
* WriteFile(hcomm, buffer, buffer.length, wrtn);
* CloseHandle(hcomm);
*
*
*
* Can't get much closer to C-code, what!
*
* In addition to the basic open/close/read/write and setup operations this
* class also makes available enough of the WIN32 Event API to make it possible
* to use overlapped (asynchronous) I/O on COM ports.
*
*
* Note that overlapped IO API is full of fine print. Especially worth
* mentioning is that the OVERLAPPED structure cannot use autosync as it is
* modified (by Windows) outside the function calls that use it. OVERLAPPED
* takes care of not autosyncing but it is best to us the writeField() methods
* to set fields of OVERLAPPED.
*
*
*
* OVERLAPPED ovl = new OVERLAPPED();
* ovl.writeField("hEvent",CreateEvent(null, true, false, null));
* ...
* WriteFile(hComm, txm, txb.length, txn, ovl);
* ...
* GetOverlappedResult(hComm, ovl, txn, true);
*
*
*
* @author Kustaa Nyholm
*
*/
public class WinAPI {
private static Windows_kernel32_lib m_K32lib;
private static Windows_kernel32_lib_Direct m_K32libDM;
private static WaitMultiple m_K32libWM;
static {
// Moved to static per JNA recommendations
Native.setPreserveLastError(true); // For older JNA to hopefully preserve last error although we don't use it with Windows
// This had to be separated out for Direct Mapping (no non-primative arrays)
m_K32libWM = (WaitMultiple) Native.loadLibrary("kernel32", WaitMultiple.class, com.sun.jna.win32.W32APIOptions.ASCII_OPTIONS);
// Added com.sun.jna.win32.W32APIOptions.ASCII_OPTIONS so we don't mix/match WString and String
Native.register(Windows_kernel32_lib_Direct.class, NativeLibrary.getInstance("kernel32", com.sun.jna.win32.W32APIOptions.ASCII_OPTIONS));
m_K32libDM = new Windows_kernel32_lib_Direct();
m_K32lib = m_K32libDM;
// m_K32lib = (Windows_kernel32_lib) Native.loadLibrary("kernel32", Windows_kernel32_lib.class, com.sun.jna.win32.W32APIOptions.ASCII_OPTIONS);
}
// The following is to fix JNA's non-thread-local getLastError implementation
private static final ThreadLocal LastError = new ThreadLocal() {
@Override
protected int[] initialValue() {
return new int[1]; // Arrays are always initialized to zero values
}
};
public static class HANDLE extends PointerType {
private boolean immutable;
public HANDLE() {
}
public HANDLE(Pointer p) {
setPointer(p);
immutable = true;
}
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
if (NULL.equals(o))
return NULL;
if (INVALID_HANDLE_VALUE.equals(o))
return INVALID_HANDLE_VALUE;
return o;
}
public void setPointer(Pointer p) {
if (immutable) {
throw new UnsupportedOperationException("immutable");
}
super.setPointer(p);
}
}
public static HANDLE INVALID_HANDLE_VALUE = new HANDLE(Pointer.createConstant(Pointer.SIZE == 8 ? -1 : 0xFFFFFFFFL));
public static HANDLE NULL = new HANDLE(Pointer.createConstant(0));
public static class Windows_kernel32_lib_Direct implements Windows_kernel32_lib {
native public HANDLE CreateFile(String name, int access, int mode, SECURITY_ATTRIBUTES security, int create, int atteribs, Pointer template) throws LastErrorException;
native public boolean WriteFile(HANDLE hFile, byte[] buf, int wrn, int[] nwrtn, Pointer lpOverlapped) throws LastErrorException;
native public boolean WriteFile(HANDLE hFile, Pointer buf, int wrn, int[] nwrtn, OVERLAPPED lpOverlapped) throws LastErrorException;
native public boolean ReadFile(HANDLE hFile, byte[] buf, int rdn, int[] nrd, Pointer lpOverlapped) throws LastErrorException;
native public boolean ReadFile(HANDLE hFile, Pointer lpBuffer, int rdn, int[] nrd, OVERLAPPED lpOverlapped) throws LastErrorException;
native public boolean FlushFileBuffers(HANDLE hFile) throws LastErrorException;
native public boolean PurgeComm(HANDLE hFile, int qmask) throws LastErrorException;
native public boolean CancelIo(HANDLE hFile) throws LastErrorException;
native public boolean CloseHandle(HANDLE hFile) throws LastErrorException;
native public boolean ClearCommError(HANDLE hFile, int[] n, COMSTAT s) throws LastErrorException;
native public boolean SetCommMask(HANDLE hFile, int dwEvtMask) throws LastErrorException;
native public boolean GetCommMask(HANDLE hFile, int[] dwEvtMask) throws LastErrorException;
native public boolean GetCommState(HANDLE hFile, DCB dcb) throws LastErrorException;
native public boolean SetCommState(HANDLE hFile, DCB dcb) throws LastErrorException;
native public boolean SetCommTimeouts(HANDLE hFile, COMMTIMEOUTS tout) throws LastErrorException;
native public boolean SetupComm(HANDLE hFile, int dwInQueue, int dwOutQueue) throws LastErrorException;
native public boolean SetCommBreak(HANDLE hFile) throws LastErrorException;
native public boolean ClearCommBreak(HANDLE hFile) throws LastErrorException;
native public boolean GetCommModemStatus(HANDLE hFile, int[] stat) throws LastErrorException;
native public boolean EscapeCommFunction(HANDLE hFile, int func) throws LastErrorException;
native public HANDLE CreateEvent(SECURITY_ATTRIBUTES lpEventAttributes, boolean bManualReset, boolean bInitialState, String lpName) throws LastErrorException;
native public boolean ResetEvent(HANDLE hEvent) throws LastErrorException;
native public boolean SetEvent(HANDLE hEvent) throws LastErrorException;
native public boolean WaitCommEvent(HANDLE hFile, IntByReference lpEvtMask, OVERLAPPED lpOverlapped) throws LastErrorException;
native public int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);
native public boolean GetOverlappedResult(HANDLE hFile, OVERLAPPED lpOverlapped, int[] lpNumberOfBytesTransferred, boolean bWait) throws LastErrorException;
native public int FormatMessageW(int flags, Pointer src, int msgId, int langId, Pointer dst, int sze, Pointer va_list);
native public int QueryDosDevice(String name, byte[] buffer, int bsize) throws LastErrorException;
}
public interface WaitMultiple extends StdCallLibrary {
public int WaitForMultipleObjects(int nCount, HANDLE[] lpHandles, boolean bWaitAll, int dwMilliseconds);
}
public interface Windows_kernel32_lib extends StdCallLibrary {
public HANDLE CreateFile(String name, int access, int mode, SECURITY_ATTRIBUTES security, int create, int atteribs, Pointer template);
public boolean WriteFile(HANDLE hFile, byte[] buf, int wrn, int[] nwrtn, Pointer lpOverlapped);
public boolean WriteFile(HANDLE hFile, Pointer buf, int wrn, int[] nwrtn, OVERLAPPED lpOverlapped);
public boolean ReadFile(HANDLE hFile, byte[] buf, int rdn, int[] nrd, Pointer lpOverlapped);
public boolean ReadFile(HANDLE hFile, Pointer lpBuffer, int rdn, int[] nrd, OVERLAPPED lpOverlapped);
public boolean FlushFileBuffers(HANDLE hFile);
public boolean PurgeComm(HANDLE hFile, int qmask);
public boolean CancelIo(HANDLE hFile);
public boolean CloseHandle(HANDLE hFile);
public boolean ClearCommError(HANDLE hFile, int[] n, COMSTAT s);
public boolean SetCommMask(HANDLE hFile, int dwEvtMask);
public boolean GetCommMask(HANDLE hFile, int[] dwEvtMask);
public boolean GetCommState(HANDLE hFile, DCB dcb);
public boolean SetCommState(HANDLE hFile, DCB dcb);
public boolean SetCommTimeouts(HANDLE hFile, COMMTIMEOUTS tout);
public boolean SetupComm(HANDLE hFile, int dwInQueue, int dwOutQueue);
public boolean SetCommBreak(HANDLE hFile);
public boolean ClearCommBreak(HANDLE hFile);
public boolean GetCommModemStatus(HANDLE hFile, int[] stat);
public boolean EscapeCommFunction(HANDLE hFile, int func);
public HANDLE CreateEvent(SECURITY_ATTRIBUTES lpEventAttributes, boolean bManualReset, boolean bInitialState, String lpName);
public boolean ResetEvent(HANDLE hEvent);
public boolean SetEvent(HANDLE hEvent);
public boolean WaitCommEvent(HANDLE hFile, IntByReference lpEvtMask, OVERLAPPED lpOverlapped);
public int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);
public boolean GetOverlappedResult(HANDLE hFile, OVERLAPPED lpOverlapped, int[] lpNumberOfBytesTransferred, boolean bWait);
public int FormatMessageW(int flags, Pointer src, int msgId, int langId, Pointer dst, int sze, Pointer va_list);
public int QueryDosDevice(String name, byte[] buffer, int bsize) ;
}
// There seems to be very little rhyme or reason from which header file
// these come from in C, so I did not bother to keep track of the
// origin of these constants
public static final int ERROR_INSUFFICIENT_BUFFER = 122;
public static final int MAXDWORD = 0xFFFFFFFF;
public static final int STATUS_WAIT_0 = 0x00000000;
public static final int STATUS_ABANDONED_WAIT_0 = 0x00000080;
public static final int WAIT_ABANDONED = (STATUS_ABANDONED_WAIT_0) + 0;
public static final int WAIT_ABANDONED_0 = (STATUS_ABANDONED_WAIT_0) + 0;
public static final int WAIT_OBJECT_0 = ((STATUS_WAIT_0) + 0);
public static final int WAIT_FAILED = 0xFFFFFFFF;
public static final int INFINITE = 0xFFFFFFFF;
public static final int WAIT_TIMEOUT = 258; //
public static final int GENERIC_READ = 0x80000000;
public static final int GENERIC_WRITE = 0x40000000;
public static final int GENERIC_EXECUTE = 0x20000000;
public static final int GENERIC_ALL = 0x10000000;
public static final int CREATE_NEW = 1;
public static final int CREATE_ALWAYS = 2;
public static final int OPEN_EXISTING = 3;
public static final int OPEN_ALWAYS = 4;
public static final int TRUNCATE_EXISTING = 5;
public static final int PURGE_TXABORT = 0x0001;
public static final int PURGE_RXABORT = 0x0002;
public static final int PURGE_TXCLEAR = 0x0004;
public static final int PURGE_RXCLEAR = 0x0008;
public static final int MS_CTS_ON = 0x0010;
public static final int MS_DSR_ON = 0x0020;
public static final int MS_RING_ON = 0x0040;
public static final int MS_RLSD_ON = 0x0080;
public static final int SETXOFF = 1;
public static final int SETXON = 2;
public static final int SETRTS = 3;
public static final int CLRRTS = 4;
public static final int SETDTR = 5;
public static final int CLRDTR = 6;
public static final int RESETDEV = 7;
public static final int SETBREAK = 8;
public static final int CLRBREAK = 9;
public static final int FILE_FLAG_WRITE_THROUGH = 0x80000000;
public static final int FILE_FLAG_OVERLAPPED = 0x40000000;
public static final int FILE_FLAG_NO_BUFFERING = 0x20000000;
public static final int FILE_FLAG_RANDOM_ACCESS = 0x10000000;
public static final int FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
public static final int FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
public static final int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
public static final int FILE_FLAG_POSIX_SEMANTICS = 0x01000000;
public static final int FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000;
public static final int FILE_FLAG_OPEN_NO_RECALL = 0x00100000;
public static final int FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;
public static final int ERROR_OPERATION_ABORTED = 995;
public static final int ERROR_IO_INCOMPLETE = 996;
public static final int ERROR_IO_PENDING = 997;
public static final int ERROR_BROKEN_PIPE = 109;
public static final int ERROR_MORE_DATA = 234;
public static final int ERROR_FILE_NOT_FOUND = 2;
public static final byte NOPARITY = 0;
public static final byte ODDPARITY = 1;
public static final byte EVENPARITY = 2;
public static final byte MARKPARITY = 3;
public static final byte SPACEPARITY = 4;
public static final byte ONESTOPBIT = 0;
public static final byte ONE5STOPBITS = 1;
public static final byte TWOSTOPBITS = 2;
public static final int CBR_110 = 110;
public static final int CBR_300 = 300;
public static final int CBR_600 = 600;
public static final int CBR_1200 = 1200;
public static final int CBR_2400 = 2400;
public static final int CBR_4800 = 4800;
public static final int CBR_9600 = 9600;
public static final int CBR_14400 = 14400;
public static final int CBR_19200 = 19200;
public static final int CBR_38400 = 38400;
public static final int CBR_56000 = 56000;
public static final int CBR_57600 = 57600;
public static final int CBR_115200 = 115200;
public static final int CBR_128000 = 128000;
public static final int CBR_256000 = 256000;
public static final int CE_RXOVER = 0x0001;
public static final int CE_OVERRUN = 0x0002;
public static final int CE_RXPARITY = 0x0004;
public static final int CE_FRAME = 0x0008;
public static final int CE_BREAK = 0x0010;
public static final int CE_TXFULL = 0x0100;
public static final int CE_PTO = 0x0200;
public static final int CE_IOE = 0x0400;
public static final int CE_DNS = 0x0800;
public static final int CE_OOP = 0x1000;
public static final int CE_MODE = 0x8000;
public static final int IE_BADID = -1;
public static final int IE_OPEN = -2;
public static final int IE_NOPEN = -3;
public static final int IE_MEMORY = -4;
public static final int IE_DEFAULT = -5;
public static final int IE_HARDWARE = -10;
public static final int IE_BYTESIZE = -11;
public static final int IE_BAUDRATE = -12;
public static final int EV_RXCHAR = 0x0001;
public static final int EV_RXFLAG = 0x0002;
public static final int EV_TXEMPTY = 0x0004;
public static final int EV_CTS = 0x0008;
public static final int EV_DSR = 0x0010;
public static final int EV_RLSD = 0x0020;
public static final int EV_BREAK = 0x0040;
public static final int EV_ERR = 0x0080;
public static final int EV_RING = 0x0100;
public static final int EV_PERR = 0x0200;
public static final int EV_RX80FULL = 0x0400;
public static final int EV_EVENT1 = 0x0800;
public static final int EV_EVENT2 = 0x1000;
public static final int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
public static final int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
public static final int FORMAT_MESSAGE_FROM_STRING = 0x00000400;
public static final int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
public static final int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
public static final int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
public static final int FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF;
public static final int LANG_NEUTRAL = 0x00;
public static final int SUBLANG_DEFAULT = 0x01;
public static int MAKELANGID(int p, int s) {
return (s << 10) | p;
}
public static class ULONG_PTR extends IntegerType {
public ULONG_PTR() {
this(0);
}
public ULONG_PTR(long value) {
super(Pointer.SIZE, value);
}
}
/**
* Represent the Windows API struct OVERLAPPED. The constructor of this
* class does 'this.setAutoSynch(false)' because instances of this class
* should not be auto synchronized nor written as a whole, because Windows
* stores pointers to the actual memory representing this this struct and
* modifies it outside the function calls and copying (writing) the Java
* class fields to the actual memory will destroy those structures.
*
*
* To set the fields it recommend to use the 'writeField(String,Object)'. It
* is ok to read those fields of OVERLAPPED using Java dot-notatio. that
* have been written by Java code, but those field that Windows modifies
* should be accessed using 'readField(String)' or by invoking 'read()' on
* the object before accessing the fields with the java dot-notation.
*
* For example this is acceptable usage for doing overlapped I/O (except
* this code does no error checking!):
*
*
*
* OVERLAPPED ovl = new OVERLAPPED();
* ovl.writeField("hEvent", CreateEvent(null, true, false, null));
* ResetEvent(osReader.hEvent);
* ReadFile(hComm, buffer, reqN, recN, ovl);
*
*
*
* @author nyholku
*
*/
public static class OVERLAPPED extends Structure {
public ULONG_PTR Internal;
public ULONG_PTR InternalHigh;
public int Offset;
public int OffsetHigh;
public HANDLE hEvent;
@Override
protected List getFieldOrder() {
return Arrays.asList("Internal",//
"InternalHigh",//
"Offset",//
"OffsetHigh",//
"hEvent"//
);
}
public OVERLAPPED() {
setAutoSynch(false);
}
public String toString() {
return String.format(//
"[Offset %d OffsetHigh %d hEvent %s]",//
Offset, OffsetHigh, hEvent.toString());
}
}
public static class SECURITY_ATTRIBUTES extends Structure {
public int nLength;
public Pointer lpSecurityDescriptor;
public boolean bInheritHandle;
@Override
protected List getFieldOrder() {
return Arrays.asList("nLength",//
"lpSecurityDescriptor",//
"bInheritHandle"//
);
}
}
public static class DCB extends Structure {
public int DCBlength;
public int BaudRate;
public int fFlags; // No bit field mapping in JNA so define a flags field and masks for fFlags
public static final int fBinary = 0x00000001;
public static final int fParity = 0x00000002;
public static final int fOutxCtsFlow = 0x00000004;
public static final int fOutxDsrFlow = 0x00000008;
public static final int fDtrControl = 0x00000030;
public static final int fDsrSensitivity = 0x00000040;
public static final int fTXContinueOnXoff = 0x00000080;
public static final int fOutX = 0x00000100;
public static final int fInX = 0x00000200;
public static final int fErrorChar = 0x00000400;
public static final int fNull = 0x00000800;
public static final int fRtsControl = 0x00003000;
public static final int fAbortOnError = 0x00004000;
public static final int fDummy2 = 0xFFFF8000;
public short wReserved;
public short XonLim;
public short XoffLim;
public byte ByteSize;
public byte Parity;
public byte StopBits;
public byte XonChar;
public byte XoffChar;
public byte ErrorChar;
public byte EofChar;
public byte EvtChar;
public short wReserved1;
@Override
protected List getFieldOrder() {
return Arrays.asList("DCBlength",//
"BaudRate",//
"fFlags",//
"wReserved",//
"XonLim",//
"XoffLim",//
"ByteSize",//
"Parity",//
"StopBits",//
"XonChar",//
"XoffChar",//
"ErrorChar",//
"EofChar",//
"EvtChar",//
"wReserved1"//
);
}
public String toString() {
return String.format(//
"[BaudRate %d fFlags %04X wReserved %d XonLim %d XoffLim %d ByteSize %d Parity %d StopBits %d XonChar %02X XoffChar %02X ErrorChar %02X EofChar %02X EvtChar %02X wReserved1 %d]", //
BaudRate, fFlags, wReserved, XonLim, XoffLim, ByteSize, Parity, StopBits, XonChar, XoffChar, ErrorChar, EofChar, EvtChar, wReserved1);
}
};
public static class COMMTIMEOUTS extends Structure {
public int ReadIntervalTimeout;
public int ReadTotalTimeoutMultiplier;
public int ReadTotalTimeoutConstant;
public int WriteTotalTimeoutMultiplier;
public int WriteTotalTimeoutConstant;
@Override
protected List getFieldOrder() {
return Arrays.asList("ReadIntervalTimeout",//
"ReadTotalTimeoutMultiplier",//
"ReadTotalTimeoutConstant",//
"WriteTotalTimeoutMultiplier",//
"WriteTotalTimeoutConstant"//
);
}
public String toString() {
return String.format(//
"[ReadIntervalTimeout %d ReadTotalTimeoutMultiplier %d ReadTotalTimeoutConstant %d WriteTotalTimeoutMultiplier %d WriteTotalTimeoutConstant %d]", //
ReadIntervalTimeout, ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant, WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant);
}
};
public static class COMSTAT extends Structure {
public int fFlags;
public static final int fCtsHold = 0x00000001;
public static final int fDsrHold = 0x00000002;
public static final int fRlsdHold = 0x00000004;
public static final int fXoffHold = 0x00000008;
public static final int fXoffSent = 0x00000010;
public static final int fEof = 0x00000020;
public static final int fTxim = 0x00000040;
public static final int fReserved = 0xFFFFFF80;
public int cbInQue;
public int cbOutQue;
@Override
protected List getFieldOrder() {
return Arrays.asList("fFlags",//
"cbInQue",//
"cbOutQue"//
);
}
public String toString() {
return String.format("[fFlags %04X cbInQue %d cbInQue %d]", fFlags, cbInQue, cbOutQue);
}
};
static public HANDLE CreateFile(String name, int access, int sharing, SECURITY_ATTRIBUTES security, int create, int attribs, Pointer template) {
log = log && log(5, "> CreateFileA(%s, 0x%08X, 0x%08X, %s, 0x%08X, 0x%08X,%s)\n", name, access, sharing, security, create, attribs, template);
HANDLE h;
try {
h = m_K32lib.CreateFile(name, access, sharing, security, create, attribs, template);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
h = INVALID_HANDLE_VALUE;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< CreateFileA(%s, 0x%08X, 0x%08X, %s, 0x%08X, 0x%08X,%s) => %s\n", name, access, sharing, security, create, attribs, template, h);
return h;
}
// This is for synchronous writes only
static public boolean WriteFile(HANDLE hFile, byte[] buf, int wrn, int[] nwrtn) {
log = log && log(5, "> WriteFile(%s, %s, %d, [%d])\n", hFile, log(buf, wrn), wrn, nwrtn[0]);
boolean res;
try {
res = m_K32lib.WriteFile(hFile, buf, wrn, nwrtn, null);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< WriteFile(%s, %s, %d, [%d]) => %s\n", hFile, log(buf, wrn), wrn, nwrtn[0], res);
return res;
}
// This can be used with synchronous as well as overlapped writes
static public boolean WriteFile(HANDLE hFile, Pointer buf, int wrn, int[] nwrtn, OVERLAPPED ovrlp) {
log = log && log(5, "> WriteFile(%s, %s, %d, [%d], %s)\n", hFile, log(buf.getByteArray(0, wrn), 5), wrn, nwrtn[0], ref(ovrlp));
boolean res;
try {
res = m_K32lib.WriteFile(hFile, buf, wrn, nwrtn, ovrlp);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< WriteFile(%s, %s, %d, [%d], %s) => %s\n", hFile, log(buf.getByteArray(0, wrn), 5), wrn, nwrtn[0], ref(ovrlp), res);
return res;
}
// This is for synchronous reads only
static public boolean ReadFile(HANDLE hFile, byte[] buf, int rdn, int[] nrd) {
log = log && log(5, "> ReadFile(%s, %s, %d, [%d])\n", hFile, log(buf, rdn), rdn, nrd[0]);
boolean res;
try {
res = m_K32lib.ReadFile(hFile, buf, rdn, nrd, null);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< ReadFile(%s, %s, %d, [%d]) => %s\n", hFile, log(buf, rdn), rdn, nrd[0], res);
return res;
}
// This can be used with synchronous as well as overlapped reads
static public boolean ReadFile(HANDLE hFile, Pointer buf, int rdn, int[] nrd, OVERLAPPED ovrlp) {
log = log && log(5, "> ReadFile(%s, %s, %d, [%d], %s)\n", hFile, log(buf.getByteArray(0, rdn), 5), rdn, nrd[0], ref(ovrlp));
boolean res;
try {
res = m_K32lib.ReadFile(hFile, buf, rdn, nrd, ovrlp);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< ReadFile(%s, %s, %d, [%d], %s) => %s\n", hFile, log(buf.getByteArray(0, rdn), 5), rdn, nrd[0], ref(ovrlp), res);
return res;
}
static public boolean FlushFileBuffers(HANDLE hFile) {
log = log && log(5, "> FlushFileBuffers(%s)\n", hFile);
boolean res;
try {
res = m_K32lib.FlushFileBuffers(hFile);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< FlushFileBuffers(%s) => %s\n", hFile, res);
return res;
}
static public boolean PurgeComm(HANDLE hFile, int qmask) {
log = log && log(5, "> PurgeComm(%s,0x%08X)\n", hFile, qmask);
boolean res;
try {
res = m_K32lib.PurgeComm(hFile, qmask);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< PurgeComm(%s,0x%08X) => %s\n", hFile, qmask, res);
return res;
}
static public boolean CancelIo(HANDLE hFile) {
log = log && log(5, "> CancelIo(%s)\n", hFile);
boolean res;
try {
res = m_K32lib.CancelIo(hFile);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< CancelIo(%s) => %s\n", hFile, res);
return res;
}
static public boolean CloseHandle(HANDLE hFile) {
log = log && log(5, "> CloseHandle(%s)\n", hFile);
boolean res;
try {
res = m_K32lib.CloseHandle(hFile);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< CloseHandle(%s) => %s\n", hFile, res);
return res;
}
static public boolean ClearCommError(HANDLE hFile, int[] n, COMSTAT s) {
log = log && log(5, "> ClearCommError(%s, [%d], %s)\n", hFile, n[0], s);
boolean res;
try {
res = m_K32lib.ClearCommError(hFile, n, s);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< ClearCommError(%s, [%d], %s) => %s\n", hFile, n[0], s, res);
return res;
}
static public boolean SetCommMask(HANDLE hFile, int mask) {
log = log && log(5, "> SetCommMask(%s, 0x%08X)\n", hFile, mask);
boolean res;
try {
res = m_K32lib.SetCommMask(hFile, mask);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< SetCommMask(%s, 0x%08X) => %s\n", hFile, mask, res);
return res;
}
static public boolean GetCommMask(HANDLE hFile, int[] mask) {
log = log && log(5, "> GetCommMask(%s, [0x%08X])\n", hFile, mask[0]);
boolean res;
try {
res = m_K32lib.GetCommMask(hFile, mask);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< GetCommMask(%s, [0x%08X]) => %s\n", hFile, mask[0], res);
return res;
}
static public boolean GetCommState(HANDLE hFile, DCB dcb) {
log = log && log(5, "> GetCommState(%s, %s)\n", hFile, dcb);
boolean res;
try {
res = m_K32lib.GetCommState(hFile, dcb);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< GetCommState(%s, %s) => %s\n", hFile, dcb, res);
return res;
}
static public boolean SetCommState(HANDLE hFile, DCB dcb) {
log = log && log(5, "> SetCommState(%s, %s)\n", hFile, dcb);
boolean res;
try {
res = m_K32lib.SetCommState(hFile, dcb);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< SetCommState(%s, %s) => %s\n", hFile, dcb, res);
return res;
}
static public boolean SetCommTimeouts(HANDLE hFile, COMMTIMEOUTS touts) {
log = log && log(5, "> SetCommTimeouts(%s, %s)\n", hFile, touts);
boolean res;
try {
res = m_K32lib.SetCommTimeouts(hFile, touts);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< SetCommTimeouts(%s, %s) => %s\n", hFile, touts, res);
return res;
}
static public boolean SetupComm(HANDLE hFile, int inQueueSz, int outQueueSz) {
log = log && log(5, "> SetCommTimeouts(%s, %d, %d)\n", hFile, inQueueSz, outQueueSz);
boolean res;
try {
res = m_K32lib.SetupComm(hFile, inQueueSz, outQueueSz);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< SetCommTimeouts(%s, %d, %d) => %s\n", hFile, inQueueSz, outQueueSz, res);
return res;
}
static public boolean SetCommBreak(HANDLE hFile) {
log = log && log(5, "> SetCommBreak(%s)\n", hFile);
boolean res;
try {
res = m_K32lib.SetCommBreak(hFile);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< SetCommBreak(%s) => %s\n", hFile, res);
return res;
}
static public boolean ClearCommBreak(HANDLE hFile) {
log = log && log(5, "> ClearCommBreak(%s)\n", hFile);
boolean res;
try {
res = m_K32lib.ClearCommBreak(hFile);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< ClearCommBreak(%s) => %s\n", hFile, res);
return res;
}
static public boolean GetCommModemStatus(HANDLE hFile, int[] stat) {
log = log && log(5, "> GetCommModemStatus(%s,0x%08X)\n", hFile, stat[0]);
boolean res;
try {
res = m_K32lib.GetCommModemStatus(hFile, stat);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< GetCommModemStatus(%s,0x%08X) => %s\n", hFile, stat[0], res);
return res;
}
static public boolean EscapeCommFunction(HANDLE hFile, int func) {
log = log && log(5, "> EscapeCommFunction(%s,0x%08X)\n", hFile, func);
boolean res;
try {
res = m_K32lib.EscapeCommFunction(hFile, func);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< EscapeCommFunction(%s,0x%08X) => %s\n", hFile, func, res);
return res;
}
static public HANDLE CreateEvent(SECURITY_ATTRIBUTES security, boolean manual, boolean initial, String name) {
log = log && log(5, "> CreateEventA(%s, %s, %s, %s)\n", ref(security), manual, initial, name);
HANDLE h;
try {
h = m_K32lib.CreateEvent(security, manual, initial, name);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
h = INVALID_HANDLE_VALUE;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< CreateEventA(%s, %s, %s, %s) => %s\n", ref(security), manual, initial, name, h);
return h;
}
static public boolean SetEvent(HANDLE hEvent) {
log = log && log(5, "> SetEvent(%s)\n", hEvent);
boolean res;
try {
res = m_K32lib.SetEvent(hEvent);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< SetEvent(%s) => %s\n", hEvent, res);
return res;
}
static public boolean ResetEvent(HANDLE hEvent) {
log = log && log(5, "> ResetEvent(%s)\n", hEvent);
boolean res;
try {
res = m_K32lib.ResetEvent(hEvent);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< ResetEvent(%s) => %s\n", hEvent, res);
return res;
}
static public boolean WaitCommEvent(HANDLE hFile, IntByReference lpEvtMask, OVERLAPPED ovl) {
log = log && log(5, "> WaitCommEvent(%s, [%d], %s)\n", hFile, lpEvtMask.getValue(), ref(ovl));
boolean res;
try {
res = m_K32lib.WaitCommEvent(hFile, lpEvtMask, ovl);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< WaitCommEvent(%s, [%d], %s) => %s\n", hFile, lpEvtMask.getValue(), ref(ovl), res);
return res;
}
static public boolean WaitCommEvent(HANDLE hFile, int[] lpEvtMask) {
log = log && log(5, "> WaitCommEvent(%s, [%d], %s) => %s\n", hFile, lpEvtMask[0], null);
IntByReference brlpEvtMask = new IntByReference(lpEvtMask[0]);
boolean res;
try {
res = m_K32lib.WaitCommEvent(hFile, brlpEvtMask, null);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
lpEvtMask[0] = brlpEvtMask.getValue();
log = log && log(4, "< WaitCommEvent(%s, [%d], %s) => %s\n", hFile, lpEvtMask[0], null, res);
return res;
}
static public int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds) {
log = log && log(5, "> WaitForSingleObject(%s, %d)\n", hHandle, dwMilliseconds);
int res = m_K32lib.WaitForSingleObject(hHandle, dwMilliseconds);
log = log && log(4, "< WaitForSingleObject(%s, %d) => %s\n", hHandle, dwMilliseconds, res);
return res;
}
static public int WaitForMultipleObjects(int nCount, HANDLE[] lpHandles, boolean bWaitAll, int dwMilliseconds) {
log = log && log(5, "> WaitForMultipleObjects(%d, %s, %s, %d)\n", nCount, log(lpHandles, 3), bWaitAll, dwMilliseconds);
int res = m_K32libWM.WaitForMultipleObjects(nCount, lpHandles, bWaitAll, dwMilliseconds);
log = log && log(4, "< WaitForMultipleObjects(%d, %s, %s, %d) => %s\n", nCount, log(lpHandles, 3), bWaitAll, dwMilliseconds, res);
return res;
}
static public boolean GetOverlappedResult(HANDLE hFile, OVERLAPPED ovl, int[] ntfrd, boolean wait) {
log = log && log(5, "> GetOverlappedResult(%s, %s, [%d], %s)\n", hFile, ref(ovl), ntfrd[0], wait);
boolean res;
try {
res = m_K32lib.GetOverlappedResult(hFile, ovl, ntfrd, wait);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = false;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< GetOverlappedResult(%s, %s, [%d], %s) => %s\n", hFile, ref(ovl), ntfrd[0], wait, res);
return res;
}
static public int GetLastError() {
log = log && log(5, "> GetLastError()\n");
int res = LastError.get()[0]; // This prevents multiple retrying to create this function per JNA rules
log = log && log(4, "< GetLastError() => %d\n", res);
return res;
}
static public int FormatMessageW(int flags, Pointer src, int msgId, int langId, Pointer dst, int sze, Pointer va_list) {
log = log && log(5, "> FormatMessageW(%08x, %08x, %d, %d, %s, %d, %s)\n", flags, src, msgId, langId, dst, sze, va_list);
int res = m_K32lib.FormatMessageW(flags, src, msgId, langId, dst, sze, va_list);
log = log && log(4, "< FormatMessageW(%08x, %08x, %d, %d, %s, %d, %s) => %d\n", flags, src, msgId, langId, dst, sze, va_list, res);
return res;
}
static public int QueryDosDevice(String name, byte[] buffer, int bsize) {
log = log && log(5, "> QueryDosDeviceA(%s, %s, %d)\n", name, buffer, bsize);
int res;
try {
res = m_K32lib.QueryDosDevice(name, buffer, bsize);
LastError.get()[0] = 0;
} catch (LastErrorException le) {
res = 0;
LastError.get()[0] = le.getErrorCode();
}
log = log && log(4, "< QueryDosDeviceA(%s, %s, %d) => %d\n", name, buffer, bsize, res);
return res;
}
}