From b984cf64e912eb3714a24394c2bcb1133111a2de Mon Sep 17 00:00:00 2001 From: Michael Freeman Date: Sun, 29 Nov 2015 14:34:56 -0500 Subject: [PATCH] Added EnumResourceTypes and EnumResourceNames to Kernel32 --- CHANGES.md | 1 + .../com/sun/jna/platform/win32/Kernel32.java | 67 + .../sun/jna/platform/win32/Kernel32Util.java | 114 +- .../com/sun/jna/platform/win32/WinBase.java | 1410 +++++++++-------- .../sun/jna/platform/win32/Kernel32Test.java | 46 + .../jna/platform/win32/Kernel32UtilTest.java | 17 + 6 files changed, 989 insertions(+), 666 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7ea4ae7b45..e0620d0f58 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ Features * [#535](https://github.com/java-native-access/jna/pull/535): Added `GetDesktopWindow` to `com.sun.jna.platform.win32.User32` - [@mlfreeman2](https://github.com/mlfreeman2). * [#543](https://github.com/java-native-access/jna/pull/543): Added `ProcessIdToSessionId`, `LoadLibraryEx`, `FreeLibrary` and `Find/Load/Lock/SizeofResource` to `com.sun.jna.platform.win32.Kernel32` - [@mlfreeman2](https://github.com/mlfreeman2). * [#547](https://github.com/java-native-access/jna/pull/547): Added `GetSystemTimes` to `com.sun.jna.platform.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis). +* [#545](https://github.com/java-native-access/jna/pull/545): Added `EnumResourceTypes` and `EnumResourceNames` to `com.sun.jna.platform.win32.Kernel32` - [@mlfreeman2](https://github.com/mlfreeman2). 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 37e7ef1593..229c07ad1b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -3202,4 +3202,71 @@ boolean GetVolumePathNamesForVolumeName(String lpszVolumeName, * information, call the GetLastError function. */ boolean FreeLibrary(HMODULE module); + + /** + * Enumerates resource types within a binary module.
+ * Starting with Windows Vista, this is typically a language-neutral + * Portable Executable (LN file), and the enumeration also includes + * resources from one of the corresponding language-specific resource files + * (.mui files)-if one exists-that contain localizable language resources. + * It is also possible to use hModule to specify a .mui file, in which case + * only that file is searched for resource types.
+ * Alternately, applications can call EnumResourceTypesEx, which provides + * more precise control over which resource files to enumerate. + * + * @param hModule + * A handle to a module to be searched.
+ * This handle must be obtained through LoadLibrary or + * LoadLibraryEx.
+ * See Remarks for more information. If this parameter is NULL, + * that is equivalent to passing in a handle to the module used + * to create the current process. + * @param proc + * A pointer to the callback function to be called for each + * enumerated resource type.
+ * For more information, see the EnumResTypeProc function. + * @param lParam + * An application-defined value passed to the callback function. + * @return Returns TRUE if successful; otherwise, FALSE. To get extended + * error information, call GetLastError. + */ + boolean EnumResourceTypes(HMODULE hModule, WinBase.EnumResTypeProc proc, Pointer lParam); + + /** + * Enumerates resources of a specified type within a binary module.
+ * For Windows Vista and later, this is typically a language-neutral + * Portable Executable (LN file), and the enumeration will also include + * resources from the corresponding language-specific resource files (.mui + * files) that contain localizable language resources.
+ * It is also possible for hModule to specify an .mui file, in which case + * only that file is searched for resources. + * + * @param hModule + * A handle to a module to be searched.
+ * Starting with Windows Vista, if this is an LN file, then + * appropriate .mui files (if any exist) are included in the + * search.
+ * If this parameter is NULL, that is equivalent to passing in a + * handle to the module used to create the current process. + * @param type + * The type of the resource for which the name is being + * enumerated.
+ * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is an integer value representing + * a predefined resource type.
+ * For a list of predefined resource types, see Resource Types. + * For more information, see the Remarks section below. + * @param proc + * A pointer to the callback function to be called for each + * enumerated resource name or ID. For more information, see + * EnumResNameProc. + * @param lParam + * An application-defined value passed to the callback function. + * This parameter can be used in error checking. + * @return The return value is TRUE if the function succeeds or FALSE if the + * function does not find a resource of the type specified, or if + * the function fails for another reason. To get extended error + * information, call GetLastError. + */ + boolean EnumResourceNames(HMODULE hModule, Pointer type, WinBase.EnumResNameProc proc, Pointer lParam); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java index bd59b8f352..8d1b0dd389 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java @@ -15,6 +15,8 @@ import java.io.File; import java.io.FileNotFoundException; import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -702,6 +704,7 @@ public static byte[] getResource(String path, String type, String name) { Win32Exception err = null; Pointer start = null; int length = 0; + byte[] results = null; try { Pointer t = null; try { @@ -741,6 +744,8 @@ public static byte[] getResource(String path, String type, String name) { if (start == null) { throw new IllegalStateException("LockResource returned null."); } + // have to capture it into a byte array before you free the library, otherwise bad things happen. + results = start.getByteArray(0, length); } catch (Win32Exception we) { err = we; } finally { @@ -760,7 +765,114 @@ public static byte[] getResource(String path, String type, String name) { throw err; } - return start.getByteArray(0, length); + return results; } + /** + * Gets a list of all resources from the specified executable file + * + * @param path + * The path to the executable file + * @return A map of resource type name/ID => resources.
+ * A map key + a single list item + the path to the executable can + * be handed off to getResource() to actually get the resource. + */ + public static Map> getResourceNames(String path) { + HMODULE target = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE); + + if (target == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + final List types = new ArrayList(); + final Map> result = new LinkedHashMap>(); + + WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer lParam) { + // simulate IS_INTRESOURCE macro defined in WinUser.h + // basically that means that if "type" is less than or equal to 65,535 + // it assumes it's an ID. + // otherwise it assumes it's a pointer to a string + if (Pointer.nativeValue(type) <= 65535) { + types.add(Pointer.nativeValue(type) + ""); + } else { + types.add(type.getWideString(0)); + } + return true; + } + }; + + WinBase.EnumResNameProc ernp = new WinBase.EnumResNameProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam) { + String typeName = ""; + + if (Pointer.nativeValue(type) <= 65535) { + typeName = Pointer.nativeValue(type) + ""; + } else { + typeName = type.getWideString(0); + } + + if (Pointer.nativeValue(name) < 65535) { + result.get(typeName).add(Pointer.nativeValue(name) + ""); + } else { + result.get(typeName).add(name.getWideString(0)); + } + + return true; + } + }; + + + Win32Exception err = null; + try { + if (!Kernel32.INSTANCE.EnumResourceTypes(target, ertp, null)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + for (final String typeName : types) { + result.put(typeName, new ArrayList()); + + // simulate MAKEINTRESOURCE macro in WinUser.h + // basically, if the value passed in can be parsed as a number then convert it into one and run with that. + // otherwise, assume it's a string and construct a pointer to said string. + Pointer pointer = null; + try { + pointer = new Pointer(Long.parseLong(typeName)); + } catch (NumberFormatException e) { + pointer = new Memory(Native.WCHAR_SIZE * (typeName.length() + 1)); + pointer.setWideString(0, typeName); + } + + boolean callResult = Kernel32.INSTANCE.EnumResourceNames(target, pointer, ernp, null); + + if (!callResult) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + } catch (Win32Exception e) { + err = e; + } finally { + // from what I can tell on MSDN, the only thing that needs cleanup + // on this is the HMODULE from LoadLibrary + if (target != null) { + if (!Kernel32.INSTANCE.FreeLibrary(target)) { + Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError()); + if (err != null) { + we.addSuppressed(err); + } + throw we; + } + } + } + + if (err != null) { + throw err; + } + return result; + } + } 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 e54601bb2f..f38e940ad9 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java @@ -304,7 +304,7 @@ public String toString() { * @see SYSTEMTIME structure */ public static class SYSTEMTIME extends Structure { - // The year. The valid values for this member are 1601 through 30827. + // The year. The valid values for this member are 1601 through 30827. public short wYear; // The month. The valid values for this member are 1 through 12. public short wMonth; @@ -504,7 +504,7 @@ protected List getFieldOrder() { public static class SYSTEM_INFO extends Structure { /** Unnamed inner structure. */ - public static class PI extends Structure { + public static class PI extends Structure { public static class ByReference extends PI implements Structure.ByReference { @@ -514,10 +514,10 @@ public static class ByReference extends PI implements Structure.ByReference { * System's processor architecture. * This value can be one of the following values: * - * PROCESSOR_ARCHITECTURE_UNKNOWN - * PROCESSOR_ARCHITECTURE_INTEL - * PROCESSOR_ARCHITECTURE_IA64 - * PROCESSOR_ARCHITECTURE_AMD64 + * PROCESSOR_ARCHITECTURE_UNKNOWN + * PROCESSOR_ARCHITECTURE_INTEL + * PROCESSOR_ARCHITECTURE_IA64 + * PROCESSOR_ARCHITECTURE_AMD64 */ public WORD wProcessorArchitecture; /** @@ -529,7 +529,7 @@ public static class ByReference extends PI implements Structure.ByReference { protected List getFieldOrder() { return Arrays.asList(new String[] { "wProcessorArchitecture", "wReserved" }); } - } + } /** Unnamed inner union. */ public static class UNION extends Union { @@ -579,9 +579,9 @@ public static class ByReference extends UNION implements Structure.ByReference { * An obsolete member that is retained for compatibility with Windows NT 3.5 and Windows Me/98/95. * Use the wProcessorArchitecture, wProcessorLevel, and wProcessorRevision members to determine * the type of processor. - * PROCESSOR_INTEL_386 - * PROCESSOR_INTEL_486 - * PROCESSOR_INTEL_PENTIUM + * PROCESSOR_INTEL_386 + * PROCESSOR_INTEL_486 + * PROCESSOR_INTEL_PENTIUM */ public DWORD dwProcessorType; /** @@ -611,9 +611,9 @@ protected List getFieldOrder() { * extended memory. The GlobalMemoryStatusEx function stores information in this structure. */ public static class MEMORYSTATUSEX extends Structure { - /** - * The size of the structure, in bytes. - */ + /** + * The size of the structure, in bytes. + */ public DWORD dwLength; /** * A number between 0 and 100 that specifies the approximate percentage of physical memory @@ -671,9 +671,9 @@ public MEMORYSTATUSEX() { * {@link Kernel32#CreatePipe}, or {@link Advapi32#RegCreateKeyEx}. */ public static class SECURITY_ATTRIBUTES extends Structure { - /** - * The size of the structure, in bytes. - */ + /** + * The size of the structure, in bytes. + */ public DWORD dwLength; /** @@ -705,11 +705,11 @@ public static class STARTUPINFO extends Structure { /** * The size of the structure, in bytes. */ - public DWORD cb; + public DWORD cb; - /** - * Reserved; must be NULL. - */ + /** + * Reserved; must be NULL. + */ public String lpReserved; /** @@ -881,7 +881,7 @@ public STARTUPINFO() { */ public static class PROCESS_INFORMATION extends Structure { - /** + /** * A handle to the newly created process. The handle is used to specify * the process in all functions that perform operations on the process * object. @@ -994,7 +994,7 @@ public PROCESS_INFORMATION(Pointer memory) { * Represents a thread entry point local to this process, as a Callback. */ public interface THREAD_START_ROUTINE extends StdCallCallback{ - public DWORD apply( LPVOID lpParameter ); + public DWORD apply( LPVOID lpParameter ); } /** @@ -1002,12 +1002,12 @@ public interface THREAD_START_ROUTINE extends StdCallCallback{ * the location has no meaning in the Java process. */ public class FOREIGN_THREAD_START_ROUTINE extends Structure { - LPVOID foreignLocation; + LPVOID foreignLocation; - @Override - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "foreignLocation" }); - } + } } /** @@ -1129,646 +1129,726 @@ public DWORD callback(Pointer pbData, Pointer pvCallbackContext, - /** - * - * Contains the time-out parameters for a communications device. The - * parameters determine the behavior of - * {@link Kernel32#ReadFile}, {@link Kernel32#WriteFile}, 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} - * 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; - - @Override + /** + * + * 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; + + @Override 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()); - } - - @Override + 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()); + } + + @Override 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;; + 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;; + + /** + * An application-defined callback function used with the EnumResourceTypes + * and EnumResourceTypesEx functions.
    + * It receives resource types.
    + * The ENUMRESTYPEPROC type defines a pointer to this callback function. + *
    + * EnumResTypeProc is a placeholder for the application-defined function + * name. + */ + interface EnumResTypeProc extends Callback { + /** + * @param module + * A handle to the module whose executable file contains the + * resources for which the types are to be enumerated.
    + * If this parameter is NULL, the function enumerates the + * resource types in the module used to create the current + * process. + * @param type + * The type of resource for which the type is being + * enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer identifier of + * the given resource type.
    + * For standard resource types, see Resource Types.
    + * For more information, see the Remarks section below. + * @param lParam + * An application-defined parameter passed to the + * EnumResourceTypes or EnumResourceTypesEx function.
    + * This parameter can be used in error checking. + * @return Returns TRUE to continue enumeration or FALSE to stop + * enumeration. + */ + boolean invoke(HMODULE module, Pointer type, Pointer lParam); + } + /** + * An application-defined callback function used with the EnumResourceNames + * and EnumResourceNamesEx functions.
    + * It receives the type and name of a resource.
    + * The ENUMRESNAMEPROC type defines a pointer to this callback function. + *
    + * EnumResNameProc is a placeholder for the application-defined function + * name. + */ + interface EnumResNameProc extends Callback { + /** + * @param module + * A handle to the module whose executable file contains the + * resources that are being enumerated.
    + * If this parameter is NULL, the function enumerates the + * resource names in the module used to create the current + * process. + * @param type + * The type of resource for which the name is being + * enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is an integer + * value representing a predefined resource type.
    + * For standard resource types, see + * Resource Types.
    + * For more information, see the Remarks section below. + * @param name + * The name of a resource of the type being enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer + * identifier of the resource.
    + * For more information, see the Remarks section below. + * @param lParam + * An application-defined parameter passed to the + * EnumResourceNames or EnumResourceNamesEx function.
    + * This parameter can be used in error checking. + * @return Returns TRUE to continue enumeration or FALSE to stop + * enumeration. + */ + boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam); + } } 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 436a1050b5..c9023bc871 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.TimeZone; +import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.NativeMappedConverter; import com.sun.jna.Platform; @@ -985,4 +986,49 @@ public void testLoadLibraryEx() { } } + public void testEnumResourceNames() { + // "14" is the type name of the My Computer icon in explorer.exe + Pointer pointer = new Memory(Native.WCHAR_SIZE * 3); + pointer.setWideString(0, "14"); + WinBase.EnumResNameProc ernp = new WinBase.EnumResNameProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam) { + + return true; + } + }; + // null HMODULE means use this process / its EXE + // there are no type "14" resources in it. + boolean result = Kernel32.INSTANCE.EnumResourceNames(null, pointer, ernp, null); + assertFalse("EnumResourceNames should have failed.", result); + assertEquals("GetLastError should be set to 1813", WinError.ERROR_RESOURCE_TYPE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); + } + + + public void testEnumResourceTypes() { + final List types = new ArrayList(); + WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer lParam) { + // simulate IS_INTRESOURCE macro defined in WinUser.h + // basically that means that if "type" is less than or equal to 65,535 + // it assumes it's an ID. + // otherwise it assumes it's a pointer to a string + if (Pointer.nativeValue(type) <= 65535) { + types.add(Pointer.nativeValue(type) + ""); + } else { + types.add(type.getWideString(0)); + } + return true; + } + }; + // null HMODULE means use this process / its EXE + // there are no type "14" resources in it. + boolean result = Kernel32.INSTANCE.EnumResourceTypes(null, ertp, null); + assertTrue("EnumResourceTypes should not have failed.", result); + assertEquals("GetLastError should be set to 0", WinError.ERROR_SUCCESS, Kernel32.INSTANCE.GetLastError()); + assertTrue("EnumResourceTypes should return some resource type names", types.size() > 0); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java index 49b95cb8c4..525b77a86f 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java @@ -20,6 +20,8 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; +import java.util.List; +import java.util.Map; import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER; @@ -266,4 +268,19 @@ public void testGetResource() { assertNotNull("The 'ICO_MYCOMPUTER' resource in explorer.exe should have some content.", results); assertTrue("The 'ICO_MYCOMPUTER' resource in explorer.exe should have some content.", results.length > 0); } + + public void testGetResourceNames() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + // On Windows 7, "14" is the type assigned to the "My Computer" icon + // (which is named "ICO_MYCOMPUTER") + Map> names = Kernel32Util.getResourceNames(new File(winDir, "explorer.exe").getAbsolutePath()); + + assertNotNull("explorer.exe should contain some resources in it.", names); + assertTrue("explorer.exe should contain some resource types in it.", names.size() > 0); + assertTrue("explorer.exe should contain a resource of type '14' in it.", names.containsKey("14")); + assertTrue("resource type 14 should have a name named ICO_MYCOMPUTER associated with it.", names.get("14").contains("ICO_MYCOMPUTER")); + } }