diff --git a/CHANGES.md b/CHANGES.md index b29988d4af..bea0090634 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,16 @@ NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and ASL (see LICENSE). NOTE: JNI native support is typically incompatible between minor versions, and almost always incompatible between major versions. +Next release +============ + +Features +-------- +* [#526](https://github.com/java-native-access/jna/pull/526): Added initialization and conversion between Windows SYSTEMTIME and Java Calendar [@lgoldstein](https://github.com/lgoldstein) + +Bug Fixes +--------- + Release 4.2.1 ============= 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 545ddacbb4..8623cfe39a 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java @@ -1,18 +1,20 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; +import java.text.DateFormat; import java.util.Arrays; +import java.util.Calendar; import java.util.Date; import java.util.List; @@ -41,29 +43,29 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { int WAIT_OBJECT_0 = ((NTStatus.STATUS_WAIT_0 ) + 0 ); int WAIT_ABANDONED = ((NTStatus.STATUS_ABANDONED_WAIT_0 ) + 0 ); int WAIT_ABANDONED_0 = ((NTStatus.STATUS_ABANDONED_WAIT_0 ) + 0 ); - + /** * Maximum computer name length. * The value is 15 on Mac, 31 on everything else. */ int MAX_COMPUTERNAME_LENGTH = Platform.isMac() ? 15 : 31; - + /** - * This logon type is intended for users who will be interactively using the computer, such - * as a user being logged on by a terminal server, remote shell, or similar process. This - * logon type has the additional expense of caching logon information for disconnected operations; - * therefore, it is inappropriate for some client/server applications, such as a mail server. + * This logon type is intended for users who will be interactively using the computer, such + * as a user being logged on by a terminal server, remote shell, or similar process. This + * logon type has the additional expense of caching logon information for disconnected operations; + * therefore, it is inappropriate for some client/server applications, such as a mail server. */ int LOGON32_LOGON_INTERACTIVE = 2; /** - * This logon type is intended for high performance servers to authenticate plaintext passwords. + * This logon type is intended for high performance servers to authenticate plaintext passwords. * The LogonUser function does not cache credentials for this logon type. */ int LOGON32_LOGON_NETWORK = 3; /** - * This logon type is intended for batch servers, where processes may be executing on behalf - * of a user without their direct intervention. This type is also for higher performance servers - * that process many plaintext authentication attempts at a time, such as mail or Web servers. + * This logon type is intended for batch servers, where processes may be executing on behalf + * of a user without their direct intervention. This type is also for higher performance servers + * that process many plaintext authentication attempts at a time, such as mail or Web servers. * The LogonUser function does not cache credentials for this logon type. */ int LOGON32_LOGON_BATCH = 4; @@ -72,32 +74,32 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { */ int LOGON32_LOGON_SERVICE = 5; /** - * This logon type is for GINA DLLs that log on users who will be interactively using the computer. + * This logon type is for GINA DLLs that log on users who will be interactively using the computer. * This logon type can generate a unique audit record that shows when the workstation was unlocked. */ int LOGON32_LOGON_UNLOCK = 7; /** - * This logon type preserves the name and password in the authentication package, which allows the - * server to make connections to other network servers while impersonating the client. A server can - * accept plaintext credentials from a client, call LogonUser, verify that the user can access the + * This logon type preserves the name and password in the authentication package, which allows the + * server to make connections to other network servers while impersonating the client. A server can + * accept plaintext credentials from a client, call LogonUser, verify that the user can access the * system across the network, and still communicate with other servers. */ int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; /** - * This logon type allows the caller to clone its current token and specify new credentials for - * outbound connections. The new logon session has the same local identifier but uses different - * credentials for other network connections. This logon type is supported only by the + * This logon type allows the caller to clone its current token and specify new credentials for + * outbound connections. The new logon session has the same local identifier but uses different + * credentials for other network connections. This logon type is supported only by the * LOGON32_PROVIDER_WINNT50 logon provider. */ int LOGON32_LOGON_NEW_CREDENTIALS = 9; /** - * Use the standard logon provider for the system. The default security provider is negotiate, - * unless you pass NULL for the domain name and the user name is not in UPN format. In this case, - * the default provider is NTLM. + * Use the standard logon provider for the system. The default security provider is negotiate, + * unless you pass NULL for the domain name and the user name is not in UPN format. In this case, + * the default provider is NTLM. */ int LOGON32_PROVIDER_DEFAULT = 0; - + /** * Use the Windows NT 3.5 logon provider. */ @@ -109,14 +111,14 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { /** * Use the negotiate logon provider. */ - int LOGON32_PROVIDER_WINNT50 = 3; - + int LOGON32_PROVIDER_WINNT50 = 3; + /** * If this flag is set, a child process created with the bInheritHandles parameter of * CreateProcess set to TRUE will inherit the object handle. */ int HANDLE_FLAG_INHERIT = 1; - + /** * If this flag is set, calling the {@link Kernel32#CloseHandle} function will not * close the object handle. @@ -133,7 +135,7 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { int STARTF_FORCEONFEEDBACK = 0x040; int STARTF_FORCEOFFFEEDBACK = 0x080; int STARTF_USESTDHANDLES = 0x100; - + // Process Creation flags int DEBUG_PROCESS = 0x00000001; int DEBUG_ONLY_THIS_PROCESS = 0x00000002; @@ -164,24 +166,24 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { int FILE_USER_DISALLOWED = 7; int FILE_READ_ONLY = 8; int FILE_DIR_DISALOWED = 9; - + /* Open encrypted files raw flags */ int CREATE_FOR_IMPORT = 1; int CREATE_FOR_DIR = 2; int OVERWRITE_HIDDEN = 4; - + /* Invalid return values */ int INVALID_FILE_SIZE = 0xFFFFFFFF; int INVALID_SET_FILE_POINTER = 0xFFFFFFFF; int INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF; - + /** * Return code for a process still active. */ int STILL_ACTIVE = WinNT.STATUS_PENDING; /** - * The FILETIME structure is a 64-bit value representing the number of + * The FILETIME structure is a 64-bit value representing the number of * 100-nanosecond intervals since January 1, 1601 (UTC). * Conversion code in this class Copyright 2002-2004 Apache Software Foundation. * @author Rainer Klute (klute@rainer-klute.de) for the Apache Software Foundation (org.apache.poi.hpsf) @@ -189,8 +191,9 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { public static class FILETIME extends Structure { public int dwLowDateTime; public int dwHighDateTime; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwLowDateTime", "dwHighDateTime" }); } @@ -226,7 +229,7 @@ public FILETIME(Pointer memory) { * operating system is the modern one? :-))

*/ private static final long EPOCH_DIFF = 11644473600000L; - + /** *

Converts a Windows FILETIME into a {@link Date}. The Windows * FILETIME structure holds a date and time associated with a @@ -245,7 +248,7 @@ public static Date filetimeToDate(final int high, final int low) { final long ms_since_19700101 = ms_since_16010101 - EPOCH_DIFF; return new Date(ms_since_19700101); } - + /** *

Converts a {@link Date} into a filetime.

* @@ -259,20 +262,21 @@ public static long dateToFileTime(final Date date) { final long ms_since_16010101 = ms_since_19700101 + EPOCH_DIFF; return ms_since_16010101 * 1000 * 10; } - + public Date toDate() { return filetimeToDate(dwHighDateTime, dwLowDateTime); } - + public long toLong() { return toDate().getTime(); } - + + @Override public String toString() { return super.toString() + ": " + toDate().toString(); //$NON-NLS-1$ } } - + /* Local Memory Flags */ int LMEM_FIXED = 0x0000; int LMEM_MOVEABLE = 0x0002; @@ -289,14 +293,14 @@ public String toString() { /* Flags returned by LocalFlags (in addition to LMEM_DISCARDABLE) */ int LMEM_DISCARDED = 0x4000; - int LMEM_LOCKCOUNT = 0x00FF; - + int LMEM_LOCKCOUNT = 0x00FF; + /** - * Specifies a date and time, using individual members for the month, - * day, year, weekday, hour, minute, second, and millisecond. The time - * is either in coordinated universal time (UTC) or local time, depending + * Specifies a date and time, using individual members for the month, + * day, year, weekday, hour, minute, second, and millisecond. The time + * is either in coordinated universal time (UTC) or local time, depending * on the function that is being called. - * http://msdn.microsoft.com/en-us/library/ms724950(VS.85).aspx + * @see SYSTEMTIME structure */ public static class SYSTEMTIME extends Structure { // The year. The valid values for this member are 1601 through 30827. @@ -315,12 +319,68 @@ public static class SYSTEMTIME extends Structure { public short wSecond; // The millisecond. The valid values for this member are 0 through 999. public short wMilliseconds; - - protected List getFieldOrder() { + + public SYSTEMTIME() { + super(); + } + + public SYSTEMTIME(Date date) { + this(date.getTime()); + } + + public SYSTEMTIME(long timestamp) { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(timestamp); + fromCalendar(cal); + } + + public SYSTEMTIME(Calendar cal) { + fromCalendar(cal); + } + + public void fromCalendar(Calendar cal) { + wYear = (short) cal.get(Calendar.YEAR); + wMonth = (short) (1 + cal.get(Calendar.MONTH) - Calendar.JANUARY); // 1 = January + wDay = (short) cal.get(Calendar.DAY_OF_MONTH); + wHour = (short) cal.get(Calendar.HOUR_OF_DAY); + wMinute = (short) cal.get(Calendar.MINUTE); + wSecond = (short) cal.get(Calendar.SECOND); + wMilliseconds = (short) cal.get(Calendar.MILLISECOND); + wDayOfWeek = (short) (cal.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY); // 0 = Sunday + } + + public Calendar toCalendar() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, wYear); + cal.set(Calendar.MONTH, Calendar.JANUARY + (wMonth - 1)); + cal.set(Calendar.DAY_OF_MONTH, wDay); + cal.set(Calendar.HOUR_OF_DAY, wHour); + cal.set(Calendar.MINUTE, wMinute); + cal.set(Calendar.SECOND, wSecond); + cal.set(Calendar.MILLISECOND, wMilliseconds); + return cal; + } + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "wYear", "wMonth", "wDayOfWeek", "wDay", "wHour", "wMinute", "wSecond", "wMilliseconds" }); } + + @Override + public String toString() { + // if not initialized, return the default representation + if ((wYear == 0) && (wMonth == 0) && (wDay == 0) + && (wHour == 0) && (wMinute == 0) && (wSecond == 0) + && (wMilliseconds == 0)) { + return super.toString(); + } + + DateFormat dtf = DateFormat.getDateTimeInstance(); + Calendar cal = toCalendar(); + return dtf.format(cal.getTime()); + } } - + /** * Specifies settings for a time zone. * http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx @@ -333,54 +393,55 @@ public static class TIME_ZONE_INFORMATION extends Structure { public String DaylightName; public SYSTEMTIME DaylightDate; public LONG DaylightBias; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "Bias", "StandardName", "StandardDate", "StandardBias", "DaylightName", "DaylightDate", "DaylightBias" }); } - } - + } + /** - * The lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize - * parameter specifies the minimum number of TCHARs to allocate for an output - * message buffer. The function allocates a buffer large enough to hold the - * formatted message, and places a pointer to the allocated buffer at the address - * specified by lpBuffer. The caller should use the LocalFree function to free + * The lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize + * parameter specifies the minimum number of TCHARs to allocate for an output + * message buffer. The function allocates a buffer large enough to hold the + * formatted message, and places a pointer to the allocated buffer at the address + * specified by lpBuffer. The caller should use the LocalFree function to free * the buffer when it is no longer needed. */ int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; /** * Insert sequences in the message definition are to be ignored and passed through - * to the output buffer unchanged. This flag is useful for fetching a message for + * to the output buffer unchanged. This flag is useful for fetching a message for * later formatting. If this flag is set, the Arguments parameter is ignored. */ int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; /** * The lpSource parameter is a pointer to a null-terminated message definition. - * The message definition may contain insert sequences, just as the message text + * The message definition may contain insert sequences, just as the message text * in a message table resource may. Cannot be used with FORMAT_MESSAGE_FROM_HMODULE * or FORMAT_MESSAGE_FROM_SYSTEM. */ int FORMAT_MESSAGE_FROM_STRING = 0x00000400; /** - * The lpSource parameter is a module handle containing the message-table + * The lpSource parameter is a module handle containing the message-table * resource(s) to search. If this lpSource handle is NULL, the current process's - * application image file will be searched. Cannot be used with + * application image file will be searched. Cannot be used with * FORMAT_MESSAGE_FROM_STRING. */ int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; /** - * The function should search the system message-table resource(s) for the + * The function should search the system message-table resource(s) for the * requested message. If this flag is specified with FORMAT_MESSAGE_FROM_HMODULE, - * the function searches the system message table if the message is not found in - * the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING. - * If this flag is specified, an application can pass the result of the + * the function searches the system message table if the message is not found in + * the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING. + * If this flag is specified, an application can pass the result of the * GetLastError function to retrieve the message text for a system-defined error. */ int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; /** * The Arguments parameter is not a va_list structure, but is a pointer to an array - * of values that represent the arguments. This flag cannot be used with 64-bit - * argument values. If you are using 64-bit values, you must use the va_list + * of values that represent the arguments. This flag cannot be used with 64-bit + * argument values. If you are using 64-bit values, you must use the va_list * structure. */ int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; @@ -394,7 +455,7 @@ protected List getFieldOrder() { */ int DRIVE_NO_ROOT_DIR = 1; /** - * The drive is a type that has removable media, for example, a floppy drive + * The drive is a type that has removable media, for example, a floppy drive * or removable hard disk. */ int DRIVE_REMOVABLE = 2; @@ -413,10 +474,10 @@ protected List getFieldOrder() { /** * The drive is a RAM disk. */ - int DRIVE_RAMDISK = 6; - + int DRIVE_RAMDISK = 6; + /** - * The OVERLAPPED structure contains information used in + * The OVERLAPPED structure contains information used in * asynchronous (or overlapped) input and output (I/O). */ public static class OVERLAPPED extends Structure { @@ -425,32 +486,33 @@ public static class OVERLAPPED extends Structure { public int Offset; public int OffsetHigh; public HANDLE hEvent; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "Internal", "InternalHigh", "Offset", "OffsetHigh", "hEvent" }); } - } - + } + int INFINITE = 0xFFFFFFFF; /** - * Contains information about the current computer system. This includes the architecture and + * Contains information about the current computer system. This includes the architecture and * type of the processor, the number of processors in the system, the page size, and other such * information. */ public static class SYSTEM_INFO extends Structure { - + /** Unnamed inner structure. */ public static class PI extends Structure { - + public static class ByReference extends PI implements Structure.ByReference { - + } /** - * System's processor architecture. + * System's processor architecture. * This value can be one of the following values: - * + * * PROCESSOR_ARCHITECTURE_UNKNOWN * PROCESSOR_ARCHITECTURE_INTEL * PROCESSOR_ARCHITECTURE_IA64 @@ -461,23 +523,24 @@ public static class ByReference extends PI implements Structure.ByReference { * Reserved for future use. */ public WORD wReserved; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "wProcessorArchitecture", "wReserved" }); - } + } } - + /** Unnamed inner union. */ public static class UNION extends Union { - + public static class ByReference extends UNION implements Structure.ByReference { - + } /** * An obsolete member that is retained for compatibility with Windows NT 3.5 and earlier. * New applications should use the wProcessorArchitecture branch of the union. - * Windows Me/98/95: The system always sets this member to zero, the value defined + * Windows Me/98/95: The system always sets this member to zero, the value defined * for PROCESSOR_ARCHITECTURE_INTEL. */ public DWORD dwOemID; @@ -486,7 +549,7 @@ public static class ByReference extends UNION implements Structure.ByReference { */ public PI pi; } - + /** * Processor architecture (unnamed union). */ @@ -496,36 +559,36 @@ public static class ByReference extends UNION implements Structure.ByReference { */ public DWORD dwPageSize; /** - * Pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs). + * Pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs). */ public Pointer lpMinimumApplicationAddress; /** - * Pointer to the highest memory address accessible to applications and DLLs. + * Pointer to the highest memory address accessible to applications and DLLs. */ public Pointer lpMaximumApplicationAddress; /** - * Mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31. + * Mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31. */ public DWORD_PTR dwActiveProcessorMask; /** - * Number of processors in the system. + * Number of processors in the system. */ public DWORD dwNumberOfProcessors; /** - * 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. + * 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 */ - public DWORD dwProcessorType; + public DWORD dwProcessorType; /** * Granularity for the starting address at which virtual memory can be allocated. */ public DWORD dwAllocationGranularity; /** - * System's architecture-dependent processor level. It should be used only for display purposes. + * System's architecture-dependent processor level. It should be used only for display purposes. * To determine the feature set of a processor, use the IsProcessorFeaturePresent function. * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_INTEL, wProcessorLevel is defined by the CPU vendor. * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_IA64, wProcessorLevel is set to 1. @@ -535,14 +598,15 @@ public static class ByReference extends UNION implements Structure.ByReference { * Architecture-dependent processor revision. */ public WORD wProcessorRevision; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "processorArchitecture", "dwPageSize", "lpMinimumApplicationAddress", "lpMaximumApplicationAddress", "dwActiveProcessorMask", "dwNumberOfProcessors", "dwProcessorType", "dwAllocationGranularity", "wProcessorLevel", "wProcessorRevision"}); } } - + /** - * Contains information about the current state of both physical and virtual memory, including + * Contains information about the current state of both physical and virtual memory, including * extended memory. The GlobalMemoryStatusEx function stores information in this structure. */ public static class MEMORYSTATUSEX extends Structure { @@ -551,7 +615,7 @@ public static class MEMORYSTATUSEX extends Structure { */ public DWORD dwLength; /** - * A number between 0 and 100 that specifies the approximate percentage of physical memory + * A number between 0 and 100 that specifies the approximate percentage of physical memory * that is in use (0 indicates no memory use and 100 indicates full memory use). */ public DWORD dwMemoryLoad; @@ -561,12 +625,12 @@ public static class MEMORYSTATUSEX extends Structure { public DWORDLONG ullTotalPhys; /** * The amount of physical memory currently available, in bytes. This is the amount of physical - * memory that can be immediately reused without having to write its contents to disk first. + * memory that can be immediately reused without having to write its contents to disk first. * It is the sum of the size of the standby, free, and zero lists. */ public DWORDLONG ullAvailPhys; /** - * The current committed memory limit for the system or the current process, whichever is smaller, in bytes. + * The current committed memory limit for the system or the current process, whichever is smaller, in bytes. */ public DWORDLONG ullTotalPageFile; /** @@ -579,7 +643,7 @@ public static class MEMORYSTATUSEX extends Structure { */ public DWORDLONG ullTotalVirtual; /** - * The amount of unreserved and uncommitted memory currently in the user-mode portion of the + * The amount of unreserved and uncommitted memory currently in the user-mode portion of the * virtual address space of the calling process, in bytes. */ public DWORDLONG ullAvailVirtual; @@ -587,16 +651,17 @@ public static class MEMORYSTATUSEX extends Structure { * Reserved. This value is always 0. */ public DWORDLONG ullAvailExtendedVirtual; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwLength", "dwMemoryLoad", "ullTotalPhys", "ullAvailPhys", "ullTotalPageFile", "ullAvailPageFile", "ullTotalVirtual", "ullAvailVirtual", "ullAvailExtendedVirtual" }); } - + public MEMORYSTATUSEX() { dwLength = new DWORD(size()); } }; - + /** * The SECURITY_ATTRIBUTES structure contains the security descriptor for an * object and specifies whether the handle retrieved by specifying this @@ -609,27 +674,28 @@ public static class SECURITY_ATTRIBUTES extends Structure { * The size of the structure, in bytes. */ public DWORD dwLength; - + /** * A pointer to a SECURITY_DESCRIPTOR structure that controls access to the object. */ public Pointer lpSecurityDescriptor; - + /** * A Boolean value that specifies whether the returned handle is inherited when * a new process is created */ public boolean bInheritHandle; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwLength", "lpSecurityDescriptor", "bInheritHandle" }); } - + public SECURITY_ATTRIBUTES() { dwLength = new DWORD(size()); } } - + /** * Specifies the window station, desktop, standard handles, and appearance of the main * window for a process at creation time. @@ -639,19 +705,19 @@ public static class STARTUPINFO extends Structure { * The size of the structure, in bytes. */ public DWORD cb; - + /** * Reserved; must be NULL. */ public String lpReserved; - + /** * The name of the desktop, or the name of both the desktop and window station for this process. * A backslash in the string indicates that the string includes both the desktop and window * station names. For more information, see Thread Connection to a Desktop. */ public String lpDesktop; - + /** * For console processes, this is the title displayed in the title bar * if a new console window is created. If NULL, the name of the @@ -660,12 +726,12 @@ public static class STARTUPINFO extends Structure { * console window. */ public String lpTitle; - + /** * If dwFlags specifies STARTF_USEPOSITION, this member is the x offset * of the upper left corner of a window if a new window is created, in * pixels. Otherwise, this member is ignored. - * + * * The offset is from the upper left corner of the screen. For GUI * processes, the specified position is used the first time the new * process calls CreateWindow to create an overlapped window if the x @@ -677,7 +743,7 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USEPOSITION, this member is the y offset * of the upper left corner of a window if a new window is created, in * pixels. Otherwise, this member is ignored. - * + * * The offset is from the upper left corner of the screen. For GUI * processes, the specified position is used the first time the new * process calls CreateWindow to create an overlapped window if the y @@ -689,18 +755,18 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USESIZE, this member is the width of the * window if a new window is created, in pixels. Otherwise, this member * is ignored. - * + * * For GUI processes, this is used only the first time the new process * calls CreateWindow to create an overlapped window if the nWidth * parameter of CreateWindow is CW_USEDEFAULT. */ public DWORD dwXSize; - + /** * If dwFlags specifies STARTF_USESIZE, this member is the height of the * window if a new window is created, in pixels. Otherwise, this member * is ignored. - * + * * For GUI processes, this is used only the first time the new process * calls CreateWindow to create an overlapped window if the nHeight * parameter of CreateWindow is CW_USEDEFAULT. @@ -725,13 +791,13 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USEFILLATTRIBUTE, this member is the * initial text and background colors if a new console window is created * in a console application. Otherwise, this member is ignored. - * + * * This value can be any combination of the following values: * FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, * FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, * BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following * combination of values produces red text on a white background: - * + * * FOREGROUND_RED| BACKGROUND_RED| BACKGROUND_GREEN| BACKGROUND_BLUE */ public DWORD dwFillAttribute; @@ -747,7 +813,7 @@ public static class STARTUPINFO extends Structure { * the values that can be specified in the nCmdShow parameter for the * ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this * member is ignored. - * + * * For GUI processes, the first time ShowWindow is called, its nCmdShow * parameter is ignored wShowWindow specifies the default value. In * subsequent calls to ShowWindow, the wShowWindow member is used if the @@ -769,14 +835,14 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USESTDHANDLES, this member is the * standard input handle for the process. If STARTF_USESTDHANDLES is not * specified, the default for standard input is the keyboard buffer. - * + * * If dwFlags specifies STARTF_USEHOTKEY, this member specifies a hotkey * value that is sent as the wParam parameter of a WM_SETHOTKEY message * to the first eligible top-level window created by the application * that owns the process. If the window is created with the WS_POPUP * window style, it is not eligible unless the WS_EX_APPWINDOW extended * window style is also set. For more information, see CreateWindowEx. - * + * * Otherwise, this member is ignored. */ public HANDLE hStdInput; @@ -796,11 +862,12 @@ public static class STARTUPINFO extends Structure { * buffer. */ public HANDLE hStdError; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "cb", "lpReserved", "lpDesktop", "lpTitle", "dwX", "dwY", "dwXSize", "dwYSize", "dwXCountChars", "dwYCountChars", "dwFillAttribute", "dwFlags", "wShowWindow", "cbReserved2", "lpReserved2", "hStdInput", "hStdOutput", "hStdError" }); } - + public STARTUPINFO() { cb = new DWORD(size()); } @@ -819,7 +886,7 @@ public static class PROCESS_INFORMATION extends Structure { * object. */ public HANDLE hProcess; - + /** * A handle to the primary thread of the newly created process. The * handle is used to specify the thread in all functions that perform @@ -842,8 +909,9 @@ public static class PROCESS_INFORMATION extends Structure { * identifier may be reused. */ public DWORD dwThreadId; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "hProcess", "hThread", "dwProcessId", "dwThreadId" }); } @@ -927,7 +995,7 @@ public PROCESS_INFORMATION(Pointer memory) { public interface THREAD_START_ROUTINE extends Callback{ public DWORD apply( LPVOID lpParameter ); } - + /** * Represents a thread entry point in another process. Can only be expressed as a pointer, as * the location has no meaning in the Java process. @@ -936,11 +1004,11 @@ public class FOREIGN_THREAD_START_ROUTINE extends Structure { LPVOID foreignLocation; @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "foreignLocation" }); } } - + /** * Specifies a type of computer name to be retrieved by the GetComputerNameEx function */ @@ -952,18 +1020,18 @@ public static interface COMPUTER_NAME_FORMAT { * "corporate-mail-server", the NetBIOS name would be "corporate-mail-"". */ int ComputerNameNetBIOS = 0; - + /** * The DNS name of the local computer or the cluster associated with the local computer. */ int ComputerNameDnsHostname = 1; - + /** * The name of the DNS domain assigned to the local computer or the cluster associated * with the local computer. */ int ComputerNameDnsDomain = 2; - + /** * The fully qualified DNS name that uniquely identifies the local computer or the cluster * associated with the local computer. This name is a combination of the DNS host name and @@ -972,32 +1040,32 @@ public static interface COMPUTER_NAME_FORMAT { * the fully qualified DNS name is "corporate-mail-server.microsoft.com". */ int ComputerNameDnsFullyQualified = 3; - + /** * The NetBIOS name of the local computer. On a cluster, this is the NetBIOS name of the * local node on the cluster. */ int ComputerNamePhysicalNetBIOS = 4; - + /** * The DNS host name of the local computer. On a cluster, this is the DNS host name of the * local node on the cluster. */ int ComputerNamePhysicalDnsHostname = 5; - + /** * The name of the DNS domain assigned to the local computer. On a cluster, this is the DNS * domain of the local node on the cluster. */ int ComputerNamePhysicalDnsDomain = 6; - + /** * The fully qualified DNS name that uniquely identifies the computer. On a cluster, this is * the fully qualified DNS name of the local node on the cluster. The fully qualified DNS name * is a combination of the DNS host name and the DNS domain name, using the form HostName.DomainName. */ int ComputerNamePhysicalDnsFullyQualified = 7; - + /** * Note used - serves as an upper limit in case one wants to go through all the values */ @@ -1027,7 +1095,7 @@ public interface FE_IMPORT_FUNC extends Callback { public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, ULONGByReference ulLength); } - + int PIPE_CLIENT_END=0x00000000; int PIPE_SERVER_END=0x00000001; @@ -1035,33 +1103,33 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, int PIPE_ACCESS_DUPLEX=0x00000003; int PIPE_ACCESS_INBOUND=0x00000001; int PIPE_ACCESS_OUTBOUND=0x00000002; - + /* Pipe type values */ int PIPE_TYPE_BYTE=0x00000000; int PIPE_TYPE_MESSAGE=0x00000004; - + /* Pipe read modes */ int PIPE_READMODE_BYTE=0x00000000; int PIPE_READMODE_MESSAGE=0x00000002; - + /* Pipe wait modes */ int PIPE_WAIT=0x00000000; int PIPE_NOWAIT=0x00000001; - + int PIPE_ACCEPT_REMOTE_CLIENTS=0x00000000; int PIPE_REJECT_REMOTE_CLIENTS=0x00000008; - + int PIPE_UNLIMITED_INSTANCES=255; - + /* Named pipe pre-defined timeout values */ int NMPWAIT_USE_DEFAULT_WAIT=0x00000000; int NMPWAIT_NOWAIT=0x00000001; int NMPWAIT_WAIT_FOREVER=0xffffffff; - + /** - * + * * Contains the time-out parameters for a communications device. The * parameters determine the behavior of * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} @@ -1070,7 +1138,7 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, * 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 @@ -1082,26 +1150,26 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, * 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; @@ -1118,7 +1186,7 @@ public static class COMMTIMEOUTS extends Structure { * 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 @@ -1139,16 +1207,17 @@ public static class COMMTIMEOUTS extends Structure { * added to the product of the * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} member and the * number of bytes to be written. - * + * * A value of zero for both the * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} and * {@link COMMTIMEOUTS#WriteTotalTimeoutConstant} members indicates that * total time-outs are not used for write operations. - * + * */ public DWORD WriteTotalTimeoutConstant; - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "ReadIntervalTimeout", "ReadTotalTimeoutMultiplier", "ReadTotalTimeoutConstant", "WriteTotalTimeoutMultiplier", "WriteTotalTimeoutConstant" }); } @@ -1160,7 +1229,7 @@ protected List getFieldOrder() { * 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. */ @@ -1265,10 +1334,10 @@ public boolean getfTXContinueOnXoff() { * 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) { + public void setfAbortOnError(boolean fAbortOnError) { int tmp = leftShiftMask(fAbortOnError ? 1 : 0, (byte)14, 0x01, this.intValue()); this.setValue(tmp); } @@ -1277,10 +1346,10 @@ public void setfAbortOnError(boolean fAbortOnError) { * 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) { + public void setfBinary(boolean fBinary) { int tmp = leftShiftMask(fBinary ? 1 : 0, (byte)0, 0x01, this.intValue()); this.setValue(tmp); } @@ -1290,10 +1359,10 @@ public void setfBinary(boolean fBinary) { * 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) { + public void setfDsrSensitivity(boolean fDsrSensitivity) { int tmp = leftShiftMask(fDsrSensitivity ? 1 : 0, (byte)6, 0x01, this.intValue()); this.setValue(tmp); } @@ -1304,7 +1373,7 @@ public void setfDsrSensitivity(boolean fDsrSensitivity) { *
  • {@link WinBase#DTR_CONTROL_DISABLE}
  • *
  • {@link WinBase#DTR_CONTROL_ENABLE}
  • *
  • {@link WinBase#DTR_CONTROL_HANDSHAKE}
  • - * + * * @param fOutxDsrFlow * value to set */ @@ -1318,7 +1387,7 @@ public void setfDtrControl(int fOutxDsrFlow) { * 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) { @@ -1332,20 +1401,20 @@ public void setfErrorChar(boolean fErrorChar) { * 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) { + 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) { + public void setfNull(boolean fNull) { int tmp = leftShiftMask(fNull ? 1 : 0, (byte)11, 0x01, this.intValue()); this.setValue(tmp); } @@ -1356,7 +1425,7 @@ public void setfNull(boolean fNull) { * 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) { @@ -1369,7 +1438,7 @@ public void setfOutX(boolean fOutX) { * 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) { @@ -1382,7 +1451,7 @@ public void setfOutxCtsFlow(boolean fOutxCtsFlow) { * 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) { @@ -1393,23 +1462,23 @@ public void setfOutxDsrFlow(boolean fOutxDsrFlow) { /** * If this member is TRUE, parity checking is performed and errors are * reported. - * + * * @param fParity */ - public void setfParity(boolean 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) { @@ -1424,15 +1493,15 @@ public void setfRtsControl(int fRtsControl) { * 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) { + 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); @@ -1447,7 +1516,7 @@ private static int leftShiftMask(int valuetoset, byte shift, int mask, int stor 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. @@ -1464,7 +1533,7 @@ private static int leftShiftMask(int valuetoset, byte shift, int mask, int stor *
  • {@link WinBase#CBR_56000}
  • *
  • {@link WinBase#CBR_128000}
  • *
  • {@link WinBase#CBR_256000}
  • - * + * */ public DWORD BaudRate; @@ -1504,7 +1573,7 @@ private static int leftShiftMask(int valuetoset, byte shift, int mask, int stor public BYTE ByteSize; /** - * + * * The parity scheme to be used. This member can be one of the following * values. *
  • {@link WinBase#EVENPARITY}
  • @@ -1559,7 +1628,8 @@ public DCB() { DCBlength = new DWORD(size()); } - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "DCBlength", "BaudRate", "controllBits", "wReserved", "XonLim", "XoffLim", "ByteSize", "Parity", "StopBits", "XonChar", "XoffChar", "ErrorChar", "EofChar", "EvtChar", "wReserved1" }); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java index cecb4b3b7d..2e03b14c46 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java @@ -1,133 +1,180 @@ /* Copyright (c) 2015 Markus Bollig, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; +import java.util.Calendar; + import com.sun.jna.platform.win32.WinBase.DCB; +import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import junit.framework.TestCase; public class WinBaseTest extends TestCase { + public WinBaseTest() { + super(); + } + + public WinBaseTest(String name) { + super(name); + } + + public void testCalendarToSystemTimeConversion() { + Calendar expected = Calendar.getInstance(); + SYSTEMTIME sysTime = new SYSTEMTIME(); + sysTime.fromCalendar(expected); + + assertEquals("Mismatched systime year", expected.get(Calendar.YEAR), sysTime.wYear); + assertEquals("Mismatched systime month", (1 + expected.get(Calendar.MONTH) - Calendar.JANUARY), sysTime.wMonth); + assertEquals("Mismatched systime day", expected.get(Calendar.DAY_OF_MONTH), sysTime.wDay); + assertEquals("Mismatched systime weekday", expected.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY, sysTime.wDayOfWeek); + + assertEquals("Mismatched systime hour", expected.get(Calendar.HOUR_OF_DAY), sysTime.wHour); + assertEquals("Mismatched systime minute", expected.get(Calendar.MINUTE), sysTime.wMinute); + assertEquals("Mismatched systime second", expected.get(Calendar.SECOND), sysTime.wSecond); + // NOTE: we do not check millis due to clock granularity issues - /** - * Test the mapping of the {@link DCB} structure. - * Particularly the mapping of the bit field is tested. - */ + Calendar actual = sysTime.toCalendar(); + assertEquals("Mismatched calendar year", sysTime.wYear, actual.get(Calendar.YEAR)); + assertEquals("Mismatched calendar month", Calendar.JANUARY + (sysTime.wMonth - 1), actual.get(Calendar.MONTH)); + assertEquals("Mismatched calendar day", sysTime.wDay, actual.get(Calendar.DAY_OF_MONTH)); + assertEquals("Mismatched calendar weekday", sysTime.wDayOfWeek, actual.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY); + + assertEquals("Mismatched calendar hour", sysTime.wHour, actual.get(Calendar.HOUR_OF_DAY)); + assertEquals("Mismatched calendar minute", sysTime.wMinute, actual.get(Calendar.MINUTE)); + assertEquals("Mismatched calendar second", sysTime.wSecond, actual.get(Calendar.SECOND)); + // NOTE: we do not check millis due to clock granularity issues + + assertEquals("Mismatched reconstructed year", expected.get(Calendar.YEAR), actual.get(Calendar.YEAR)); + assertEquals("Mismatched reconstructed month", expected.get(Calendar.MONTH), actual.get(Calendar.MONTH)); + assertEquals("Mismatched reconstructed day", expected.get(Calendar.DAY_OF_MONTH), actual.get(Calendar.DAY_OF_MONTH)); + assertEquals("Mismatched reconstructed weekday", expected.get(Calendar.DAY_OF_WEEK), actual.get(Calendar.DAY_OF_WEEK)); + + assertEquals("Mismatched reconstructed hour", expected.get(Calendar.HOUR_OF_DAY), actual.get(Calendar.HOUR_OF_DAY)); + assertEquals("Mismatched reconstructed minute", expected.get(Calendar.MINUTE), actual.get(Calendar.MINUTE)); + assertEquals("Mismatched reconstructed second", expected.get(Calendar.SECOND), actual.get(Calendar.SECOND)); + // NOTE: we do not check millis due to clock granularity issues + } + + /** + * Test the mapping of the {@link DCB} structure. + * Particularly the mapping of the bit field is tested. + */ public void testDCBStructureMapping() { - //first we test if the WinBase.DCB bitfiled mapping works as expected. - WinBase.DCB lpDCB = new WinBase.DCB(); - lpDCB.controllBits.setValue(0); - - lpDCB.controllBits.setfBinary(true); - assertEquals(1, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfBinary()); - lpDCB.controllBits.setfBinary(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfBinary()); - - lpDCB.controllBits.setfParity(true); - assertEquals(2, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfParity()); - lpDCB.controllBits.setfParity(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfParity()); - - lpDCB.controllBits.setfOutxCtsFlow(true); - assertEquals(4, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow()); - lpDCB.controllBits.setfOutxCtsFlow(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow()); - - lpDCB.controllBits.setfOutxDsrFlow(true); - assertEquals(8, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow()); - lpDCB.controllBits.setfOutxDsrFlow(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow()); - - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE); - assertEquals(16, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl()); - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE); - assertEquals(32, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl()); - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl()); - - lpDCB.controllBits.setfDsrSensitivity(true); - assertEquals(64, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfDsrSensitivity()); - lpDCB.controllBits.setfDsrSensitivity(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfDsrSensitivity()); - - lpDCB.controllBits.setfTXContinueOnXoff(true); - assertEquals(128, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff()); - lpDCB.controllBits.setfTXContinueOnXoff(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff()); - - lpDCB.controllBits.setfOutX(true); - assertEquals(256, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutX()); - lpDCB.controllBits.setfOutX(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutX()); - - lpDCB.controllBits.setfInX(true); - assertEquals(512, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfInX()); - lpDCB.controllBits.setfInX(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfInX()); - - lpDCB.controllBits.setfErrorChar(true); - assertEquals(1024, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfErrorChar()); - lpDCB.controllBits.setfErrorChar(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfErrorChar()); - - lpDCB.controllBits.setfNull(true); - assertEquals(2048, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfNull()); - lpDCB.controllBits.setfNull(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfNull()); - - - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE); - assertEquals(4096, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE); - assertEquals(8192, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE); - assertEquals(12288, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl()); - - - lpDCB.controllBits.setfAbortOnError(true); - assertEquals(16384, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfAbortOnError()); - lpDCB.controllBits.setfAbortOnError(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfAbortOnError()); + //first we test if the WinBase.DCB bitfiled mapping works as expected. + WinBase.DCB lpDCB = new WinBase.DCB(); + lpDCB.controllBits.setValue(0); + + lpDCB.controllBits.setfBinary(true); + assertEquals(1, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfBinary()); + lpDCB.controllBits.setfBinary(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfBinary()); + + lpDCB.controllBits.setfParity(true); + assertEquals(2, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfParity()); + lpDCB.controllBits.setfParity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfParity()); + + lpDCB.controllBits.setfOutxCtsFlow(true); + assertEquals(4, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow()); + lpDCB.controllBits.setfOutxCtsFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow()); + + lpDCB.controllBits.setfOutxDsrFlow(true); + assertEquals(8, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow()); + lpDCB.controllBits.setfOutxDsrFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow()); + + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE); + assertEquals(16, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE); + assertEquals(32, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl()); + + lpDCB.controllBits.setfDsrSensitivity(true); + assertEquals(64, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfDsrSensitivity()); + lpDCB.controllBits.setfDsrSensitivity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfDsrSensitivity()); + + lpDCB.controllBits.setfTXContinueOnXoff(true); + assertEquals(128, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff()); + lpDCB.controllBits.setfTXContinueOnXoff(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff()); + + lpDCB.controllBits.setfOutX(true); + assertEquals(256, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutX()); + lpDCB.controllBits.setfOutX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutX()); + + lpDCB.controllBits.setfInX(true); + assertEquals(512, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfInX()); + lpDCB.controllBits.setfInX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfInX()); + + lpDCB.controllBits.setfErrorChar(true); + assertEquals(1024, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfErrorChar()); + lpDCB.controllBits.setfErrorChar(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfErrorChar()); + + lpDCB.controllBits.setfNull(true); + assertEquals(2048, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfNull()); + lpDCB.controllBits.setfNull(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfNull()); + + + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE); + assertEquals(4096, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE); + assertEquals(8192, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE); + assertEquals(12288, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl()); + + + lpDCB.controllBits.setfAbortOnError(true); + assertEquals(16384, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfAbortOnError()); + lpDCB.controllBits.setfAbortOnError(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfAbortOnError()); } public static void main(String[] args) {