diff --git a/CHANGES.md b/CHANGES.md index e0620d0f58..4879a27086 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,8 +17,9 @@ Features * [#535](https://github.com/java-native-access/jna/pull/535): Added `SHEmptyRecycleBin`, `ShellExecuteEx` to `com.sun.jna.platform.win32.Shell32` - [@mlfreeman2](https://github.com/mlfreeman2). * [#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). +* [#547](https://github.com/java-native-access/jna/pull/547): Added `GetSystemTimes` to `com.sun.jna.platform.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis). +* [#548](https://github.com/java-native-access/jna/pull/548): Return 64-bit unsigned integer from `com.sun.jna.platform.win32.WinBase.FILETIME` - [@dbwiddis](https://github.com/dbwiddis). Bug Fixes --------- 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 f38e940ad9..7f569d58e9 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java @@ -23,6 +23,7 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; +import com.sun.jna.platform.win32.WinDef.DWORDLONG; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.ByteByReference; import com.sun.jna.win32.StdCallLibrary; @@ -264,13 +265,46 @@ public static long dateToFileTime(final Date date) { return ms_since_16010101 * 1000 * 10; } + /** + *
Converts this filetime into a {@link Date}
+ * @return The {@link Date} represented by this filetime. + */ public Date toDate() { return filetimeToDate(dwHighDateTime, dwLowDateTime); } + /** + *Converts this filetime into a number of milliseconds which have + * passed since January 1, 1970 (UTC).
+ * @return This filetime as a number of milliseconds which have passed + * since January 1, 1970 (UTC) + */ + public long toTime() { + return toDate().getTime(); + } + + /** + *Converts this filetime into a number of milliseconds which have + * passed since January 1, 1970 (UTC).
+ * @return This filetime as a number of milliseconds which have passed + * since January 1, 1970 (UTC) + * @deprecated Replaced by {@link #toTime()} + */ + @Deprecated public long toLong() { return toDate().getTime(); } + + /** + *Converts the two 32-bit unsigned integer parts of this filetime + * into a 64-bit unsigned integer representing the number of + * 100-nanosecond intervals since January 1, 1601 (UTC).
+ * @return This filetime as a 64-bit unsigned integer number of + * 100-nanosecond intervals since January 1, 1601 (UTC). + */ + public DWORDLONG toDWordLong() { + return new DWORDLONG((long) dwHighDateTime << 32 | dwLowDateTime & 0xffffffffL); + } @Override public String toString() { 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 c9023bc871..2a47dcad09 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -34,6 +34,7 @@ import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.BaseTSD.SIZE_T; +import com.sun.jna.platform.win32.WinBase.FILETIME; import com.sun.jna.platform.win32.WinBase.MEMORYSTATUSEX; import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO; import com.sun.jna.platform.win32.WinDef.DWORD; @@ -387,14 +388,14 @@ public void testGetSystemInfo() { public void testGetSystemTimes() { Kernel32 kernel = Kernel32.INSTANCE; - WinBase.FILETIME lpIdleTime = new WinBase.FILETIME(); - WinBase.FILETIME lpKernelTime = new WinBase.FILETIME(); - WinBase.FILETIME lpUserTime = new WinBase.FILETIME(); + FILETIME lpIdleTime = new FILETIME(); + FILETIME lpKernelTime = new FILETIME(); + FILETIME lpUserTime = new FILETIME(); boolean succ = kernel.GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime); assertTrue(succ); - long idleTime = WinBase.FILETIME.dateToFileTime(lpIdleTime.toDate()); - long kernelTime = WinBase.FILETIME.dateToFileTime(lpKernelTime.toDate()); - long userTime = WinBase.FILETIME.dateToFileTime(lpUserTime.toDate()); + long idleTime = lpIdleTime.toDWordLong().longValue(); + long kernelTime = lpKernelTime.toDWordLong().longValue(); + long userTime = lpUserTime.toDWordLong().longValue(); // All should be >= 0. kernel includes idle. assertTrue(idleTime >= 0); assertTrue(kernelTime >= idleTime); 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 2e03b14c46..9224a716f4 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java @@ -13,8 +13,10 @@ package com.sun.jna.platform.win32; import java.util.Calendar; +import java.util.Date; import com.sun.jna.platform.win32.WinBase.DCB; +import com.sun.jna.platform.win32.WinBase.FILETIME; import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import junit.framework.TestCase; @@ -28,6 +30,16 @@ public WinBaseTest(String name) { super(name); } + public void testFiletime() { + // subtract to convert ms after 1/1/1970 to ms after 1/1/1601 + long epochDiff = 11644473600000L; + // Construct filetimes for ms after 1/1/1601, check for 100-ns after + assertEquals("Mismatched filetime for 2ms", (new FILETIME(new Date(2L - epochDiff))).toDWordLong().longValue(), 2L * 10000); + assertEquals("Mismatched filetime for 2^16ms", (new FILETIME(new Date((1L << 16) - epochDiff))).toDWordLong().longValue(), (1L << 16) * 10000); + assertEquals("Mismatched filetime for 2^32ms", (new FILETIME(new Date((1L << 32) - epochDiff))).toDWordLong().longValue(), (1L << 32) * 10000); + assertEquals("Mismatched filetime for 2^49ms", (new FILETIME(new Date((1L << 49) - epochDiff))).toDWordLong().longValue(), (1L << 49) * 10000); + } + public void testCalendarToSystemTimeConversion() { Calendar expected = Calendar.getInstance(); SYSTEMTIME sysTime = new SYSTEMTIME();