Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why is there no 'SetSystemTime/SetLocalTime' declaration in Windows Kernel 32 wrapper ? #345

Closed
lgoldstein opened this issue Jul 3, 2014 · 10 comments

Comments

@lgoldstein
Copy link
Contributor

I was wondering why the SetSystemTime API is not exposed in the Kernel32 wrapper - it seems to use the already existing SYSTEMTIME definition that is used for GetSystemTime. It does not seem to require any de-allocation of memory or such, so I was wondering if there is some special reason why this API was left out. It seems that all one has to is to add "boolean SetSystemTime/SetLocalTime(WinBase.SYSTEMTIME lpSystemTime)" definitions to the Kernel32 interface.

@dblock
Copy link
Member

dblock commented Jul 3, 2014

It has not been left out, nobody has contributed it. Please do. Don't forget tests.

@dblock dblock closed this as completed Jul 3, 2014
@lgoldstein
Copy link
Contributor Author

Here is a 'patch' file one can use in order to add the missing function - including unit test (sorry, don't have time for fork-modify-pullrequest-delete...)

From 0c10d71dab4115da244eb513ea4bc3f284b2ff00 Mon Sep 17 00:00:00 2001
From: Lyor Goldstein <[email protected]>
Date: Thu, 7 Aug 2014 09:46:06 +0300
Subject: [PATCH] Added Kernel32#SetSystemTime

---
 .../src/com/sun/jna/platform/win32/Kernel32.java   | 14 +++++++++
 .../com/sun/jna/platform/win32/Kernel32Test.java   | 34 ++++++++++++++++++++++
 2 files changed, 48 insertions(+)

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 b3b1604..06a6680 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
@@ -160,6 +160,20 @@ public interface Kernel32 extends WinNT {
     void GetSystemTime(WinBase.SYSTEMTIME lpSystemTime);

     /**
+     * The SetSystemTime function modifies the current system date and time.
+     * The system time is expressed in Coordinated Universal Time (UTC).
+     * 
+     * @param lpSystemTime
+     *            Pointer to a SYSTEMTIME structure holding the new
+     *            system date and time. <B>Note:</B> The {@code wDayOfWeek}
+     *            member of the SYSTEMTIME structure is ignored.
+     * @return {@code true} if the function succeeds, {@code false} otherwise.
+     *         If the function fails, call GetLastError to get extended error
+     *         information.
+     */
+    boolean SetSystemTime(WinBase.SYSTEMTIME lpSystemTime);
+
+    /**
      * Retrieves the current local date and time.
      * 
      * @param lpSystemTime
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 699795c..840f970 100644
--- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java
+++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java
@@ -78,6 +78,40 @@ public class Kernel32Test extends TestCase {
                      cal.get(Calendar.YEAR), time.wYear);
     }

+    public void testSetSystemTime() {
+        Kernel32 kernel = Kernel32.INSTANCE;
+        WinBase.SYSTEMTIME time = new WinBase.SYSTEMTIME();
+        kernel.GetSystemTime(time);
+        try {
+            WinBase.SYSTEMTIME expected = new WinBase.SYSTEMTIME();
+            expected.wYear = time.wYear;
+            expected.wMonth = time.wMonth;
+            expected.wDay = time.wDay;
+            expected.wHour = time.wHour;
+            expected.wMinute = time.wMinute;
+            expected.wSecond = time.wSecond;
+            expected.wMilliseconds = time.wMilliseconds;
+
+            if (expected.wHour > 0) {
+                expected.wHour--;
+            } else {
+                expected.wHour++;
+            }
+
+            if (!kernel.SetSystemTime(expected)) {
+                fail("Failed to modify time: error=" + kernel.GetLastError());
+            }
+            
+            WinBase.SYSTEMTIME actual = new WinBase.SYSTEMTIME();
+            kernel.GetSystemTime(actual);
+            assertEquals("Mismatched hour value", expected.wHour, actual.wHour);
+        } finally {
+            if (!kernel.SetSystemTime(time)) {
+                fail("Failed to restore original time: error=" + kernel.GetLastError());
+            }
+        }
+    }
+
     public void testGetLastError() {
         Kernel32 kernel = Kernel32.INSTANCE;
         int ERRCODE  = 8;
-- 
1.9.0.msysgit.0

@dblock
Copy link
Member

dblock commented Aug 7, 2014

Someone needs to turn this into a PR, thx.

@dblock dblock reopened this Aug 7, 2014
@lgoldstein
Copy link
Contributor Author

@dblock If you save it as .patch or .diff file, you can easily apply it via git or even the Linux patch command (or similar)

@dblock
Copy link
Member

dblock commented Aug 7, 2014

Should I send the bill for my time at my usual rate to VMWare? ;)

@lgoldstein
Copy link
Contributor Author

@dblock I am merely trying to contribute something within the time constraints I have. Perhaps some other good samaritan can do the merging...

@thomasjoulin
Copy link

Here you go #357

Thanks @lgoldstein and @dblock :)

@twall
Copy link
Contributor

twall commented Aug 7, 2014

thanks Thomas!

On Aug 7, 2014, at 7:27 AM, Thomas Joulin [email protected] wrote:

Here you go #357

Thanks @lgoldstein and @dblock :)


Reply to this email directly or view it on GitHub.

@dblock
Copy link
Member

dblock commented Aug 8, 2014

Thanks for jumping in @thomasjoulin, much appreciated. Merged via ef71874.

@dblock dblock closed this as completed Aug 8, 2014
@lgoldstein
Copy link
Contributor Author

Thanks @thomasjoulin and @dblock - looking forward to next release that will include it...

mstyura pushed a commit to mstyura/jna that referenced this issue Sep 9, 2024
Motivation:

We didnt correctly guard against reentrancy in forceClose() which could result in a NPE like:

```
2021-10-12T13:00:38.3081885Z io.netty.channel.ChannelPipelineException: io.netty.incubator.codec.quic.QuicheQuicServerCodec.handlerRemoved() has thrown an exception.
2021-10-12T13:00:38.3084756Z 	at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved0(DefaultChannelPipeline.java:640)
2021-10-12T13:00:38.3087125Z 	at io.netty.channel.DefaultChannelPipeline.destroyDown(DefaultChannelPipeline.java:876)
2021-10-12T13:00:38.3089017Z 	at io.netty.channel.DefaultChannelPipeline.destroyUp(DefaultChannelPipeline.java:844)
2021-10-12T13:00:38.3090840Z 	at io.netty.channel.DefaultChannelPipeline.destroy(DefaultChannelPipeline.java:836)
2021-10-12T13:00:38.3092598Z 	at io.netty.channel.DefaultChannelPipeline.access$700(DefaultChannelPipeline.java:46)
2021-10-12T13:00:38.3094465Z 	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelUnregistered(DefaultChannelPipeline.java:1392)
2021-10-12T13:00:38.3097085Z 	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelUnregistered(AbstractChannelHandlerContext.java:198)
2021-10-12T13:00:38.3100292Z 	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelUnregistered(AbstractChannelHandlerContext.java:184)
2021-10-12T13:00:38.3103291Z 	at io.netty.channel.DefaultChannelPipeline.fireChannelUnregistered(DefaultChannelPipeline.java:821)
2021-10-12T13:00:38.3105176Z 	at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:839)
2021-10-12T13:00:38.3106880Z 	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
2021-10-12T13:00:38.3109237Z 	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
2021-10-12T13:00:38.3111163Z 	at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:384)
2021-10-12T13:00:38.3112918Z 	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
2021-10-12T13:00:38.3114604Z 	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
2021-10-12T13:00:38.3116270Z 	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
2021-10-12T13:00:38.3117634Z 	at java.lang.Thread.run(Thread.java:748)
2021-10-12T13:00:38.3118372Z Caused by: java.lang.NullPointerException: null
2021-10-12T13:00:38.3119836Z 	at io.netty.incubator.codec.quic.QuicheQuicChannel.forceClose(QuicheQuicChannel.java:358)
2021-10-12T13:00:38.3121948Z 	at io.netty.incubator.codec.quic.QuicheQuicCodec.handlerRemoved(QuicheQuicCodec.java:98)
2021-10-12T13:00:38.3124291Z 	at io.netty.incubator.codec.quic.QuicheQuicServerCodec.handlerRemoved(QuicheQuicServerCodec.java:86)
2021-10-12T13:00:38.3127010Z 	at io.netty.channel.AbstractChannelHandlerContext.callHandlerRemoved(AbstractChannelHandlerContext.java:946)
2021-10-12T13:00:38.3129590Z 	at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved0(DefaultChannelPipeline.java:637)
2021-10-12T13:00:38.3130965Z 	... 16 common frames omitted
```

Modifications:

Move the assignment of connection to null to the top of the method

Result:

No more NPE due reentrancy possible
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants