Skip to content

Commit ed11ac5

Browse files
Merge pull request #1294 from matthiasblaesing/application-restart
Implement ApplicationRestart functions
2 parents 1de0448 + 77c2075 commit ed11ac5

File tree

5 files changed

+189
-4
lines changed

5 files changed

+189
-4
lines changed

CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Next Release (5.7.0)
88
Features
99
--------
1010
* [#1264](https://github.com/java-native-access/jna/pull/1264): Update libffi to v3.3; Add Windows `aarch64` target. - [@tresf](https://github.com/tresf).
11+
* [#1293](https://github.com/java-native-access/jna/issues/1293): Bind part of Windows Application Recovery and Restart API: `RegisterApplicationRestart`, `UnregisterApplicationRestart` and `GetApplicationRestartSettings` in `c.s.j.p.w.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing).
1112
* [#1217](https://github.com/java-native-access/jna/pull/1217): Add mappings for AIX `Perfstat` library to `c.s.j.p.unix.aix` - [@dbwiddis](https://github.com/dbwiddis).
1213
* [#1231](https://github.com/java-native-access/jna/pull/1231): The test suite can now be executed on Windows using either ANSI or UNICODE win32 API by passing `-Dw32.ascii=true/false` to ant. Previously, UNICODE was always used. - [@T-Svensson](https://github.com/T-Svensson/)
1314
* [#1237](https://github.com/java-native-access/jna/pull/1237): *Experimental:* Add artifacts that make jna and jna-platform named modules (provide `module-info.class`). The new artifacts are named `jna-jpms.jar` and `jna-platform-jpms.jar` - [@matthiasblaesing](https://github.com/matthiasblaesing).
@@ -16,7 +17,7 @@ Features
1617
* [#1246](https://github.com/java-native-access/jna/pull/1246): Improve performance of `c.s.j.Structure#read` and `c.s.j.Structure#write` - [@joerg1985](https://github.com/joerg1985).
1718
* [#1260](https://github.com/java-native-access/jna/pull/1260): Add mapping for X11 generic events - [@lafoletc](https://github.com/lafoletc).
1819
* [#1265](https://github.com/java-native-access/jna/pull/1265): Add mapping for XQueryExtension - [@lafoletc](https://github.com/lafoletc).
19-
* [#1263](https://github.com/java-native-access/jna/pull/1263): Add LowLevelMouseProc - [@nordiakt](https://github.com/nordiakt)
20+
* [#1263](https://github.com/java-native-access/jna/pull/1263): Add LowLevelMouseProc - [@nordiakt](https://github.com/nordiakt).
2021

2122
Bug Fixes
2223
---------

build.xml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,7 @@ cd ..
14531453
</subant>
14541454
</target>
14551455

1456-
<target name="install" depends="dist" description="Install jna and jna-platform artifacts into local maven repository">
1456+
<target name="install" depends="dist,-bootstrap-maven" description="Install jna and jna-platform artifacts into local maven repository">
14571457
<artifact:mvn failonerror="true">
14581458
<arg value="org.apache.maven.plugins:maven-install-plugin:2.5:install-file"/>
14591459
<arg value="-DpomFile=${pom}"/>
@@ -1495,7 +1495,7 @@ cd ..
14951495
</target>
14961496

14971497
<!-- NOTE: The 'deploy' target works only if the version (jna.version in build.xml) ends in '-SNAPSHOT'. -->
1498-
<target name="deploy" depends="dist" description="deploy snapshot version to Maven snapshot repository">
1498+
<target name="deploy" depends="dist,-bootstrap-maven" description="deploy snapshot version to Maven snapshot repository">
14991499
<artifact:mvn failonerror="true">
15001500
<arg value="org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy-file"/>
15011501
<arg value="-Durl=${maven-snapshots-repository-url}"/>
@@ -1522,7 +1522,7 @@ cd ..
15221522

15231523
<property name="version-maven-gpg-plugin" value="1.4"/>
15241524

1525-
<target name="stage" depends="dist" description="deploy release version to Maven staging repository">
1525+
<target name="stage" depends="dist,-bootstrap-maven" description="deploy release version to Maven staging repository">
15261526
<!-- sign and deploy the jna, artifact -->
15271527
<artifact:mvn failonerror="true">
15281528
<arg value="org.apache.maven.plugins:maven-gpg-plugin:${version-maven-gpg-plugin}:sign-and-deploy-file"/>
@@ -1550,6 +1550,28 @@ cd ..
15501550
</artifact:mvn>
15511551
</target>
15521552

1553+
<target name="-bootstrap-maven">
1554+
<artifact:remoteRepository id="remote.mavenCentral" url="https://repo1.maven.org/maven2/" />
1555+
<artifact:dependencies pathId="dependency.dummy">
1556+
<remoteRepository refid="remote.mavenCentral" />
1557+
<dependency groupId="org.apache.maven.plugins" artifactId="maven-gpg-plugin" version="1.4" type="maven-plugin"/>
1558+
<dependency groupId="org.apache.maven.plugins" artifactId="maven-deploy-plugin" version="2.7" type="maven-plugin"/>
1559+
<dependency groupId="org.apache.maven.plugins" artifactId="maven-install-plugin" version="2.5" type="maven-plugin"/>
1560+
<dependency groupId="org.apache.maven" artifactId="apache-maven" version="2.0.10" />
1561+
<dependency groupId="org.apache.maven" artifactId="maven-model" version="2.0.10" />
1562+
<dependency groupId="org.apache.maven" artifactId="maven-artifact" version="2.0.10" />
1563+
<dependency groupId="org.apache.maven" artifactId="maven-project" version="2.0.10" />
1564+
<dependency groupId="org.apache.maven" artifactId="maven-artifact-manager" version="2.0.10" />
1565+
<dependency groupId="org.apache.maven" artifactId="maven-plugin-registry" version="2.0.10" />
1566+
<dependency groupId="org.apache.maven" artifactId="maven-plugin-api" version="2.0.10" />
1567+
<dependency groupId="org.codehaus.plexus" artifactId="plexus-utils" version="3.0.15" />
1568+
</artifact:dependencies>
1569+
<artifact:dependencies pathId="dependency.dummy2">
1570+
<remoteRepository refid="remote.mavenCentral" />
1571+
<dependency groupId="org.codehaus.plexus" artifactId="plexus-utils" version="1.5.5" />
1572+
</artifact:dependencies>
1573+
</target>
1574+
15531575
<target name="checkstyle">
15541576
<taskdef resource="com/puppycrawl/tools/checkstyle/ant/checkstyle-ant-task.properties"
15551577
classpath="lib/checkstyle-8.17-all.jar"/>

contrib/platform/nbproject/build-impl.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,7 @@ is divided into following sections:
13361336
</target>
13371337
<target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
13381338
<target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
1339+
<target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-single-method"/>
13391340
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
13401341
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
13411342
</target>

contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4178,4 +4178,114 @@ Pointer VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize,
41784178
* error information, call GetLastError.</p>
41794179
*/
41804180
boolean VirtualFreeEx( HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, int dwFreeType);
4181+
4182+
/**
4183+
* Registers the active instance of an application for restart.
4184+
*
4185+
* <p><strong>Usage Note</strong></p>
4186+
*
4187+
* <p>The registered callback is only invoked if the default error handling
4188+
* of the JVM does not intercept first. It was tested with OpenJDK and
4189+
* it was found, that the error handling of the JVM had to be disabled by
4190+
* running the process with "-XX:+UseOSErrorReporting".</p>
4191+
*
4192+
* @param pwzCommandline A pointer to a Unicode string that specifies the
4193+
* command-line arguments for the application when it
4194+
* is restarted. The maximum size of the command line
4195+
* that you can specify is RESTART_MAX_CMD_LINE
4196+
* characters. Do not include the name of the
4197+
* executable in the command line; this function adds
4198+
* it for you.
4199+
*
4200+
* <p>If this parameter is NULL or an empty string, the previously registered
4201+
* command line is removed. If the argument contains spaces, use quotes
4202+
* around the argument.</p>
4203+
*
4204+
* @param dwFlags This parameter can be 0 or one or more of the
4205+
* following values.
4206+
*
4207+
* <table>
4208+
* <tr>
4209+
* <th>Value</th><th>Meaning</th>
4210+
* </tr>
4211+
* <tr><td>RESTART_NO_CRASH (1)</td><td>Do not restart the process if it terminates due to an unhandled exception.</td></tr>
4212+
* <tr><td>RESTART_NO_HANG (2)</td><td>Do not restart the process if it terminates due to the application not responding.</td></tr>
4213+
* <tr><td>RESTART_NO_PATCH (4)</td><td>Do not restart the process if it terminates due to the installation of an update.</td></tr>
4214+
* <tr><td>RESTART_NO_REBOOT (8)</td><td>Do not restart the process if the computer is restarted as the result of an update. </td></tr>
4215+
* </table>
4216+
*
4217+
* @return This function returns S_OK on success or one of the following
4218+
* error codes.
4219+
* <table>
4220+
* <tr><th>Return code</th><th>Description</th></tr>
4221+
* <tr><td>E_FAIL</td><td>Internal error.</td></tr>
4222+
* <tr><td>E_INVALIDARG</td><td>The specified command line is too
4223+
* long.</td></tr>
4224+
* </table>
4225+
*
4226+
* @see <A HREF="https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-registerapplicationrestart">MSDN Entry</A>
4227+
*/
4228+
HRESULT RegisterApplicationRestart(char[] pwzCommandline, int dwFlags);
4229+
4230+
/**
4231+
* Removes the active instance of an application from the restart list.
4232+
*
4233+
* @return This function returns S_OK on success or one of the following
4234+
* error codes.
4235+
* <table>
4236+
* <tr><th>Return code</th><th>Description</th></tr>
4237+
* <tr><td>E_FAIL</td><td>Internal error.</td></tr>
4238+
* </table>
4239+
*
4240+
* @see <A HREF="https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-unregisterapplicationrestart">MSDN Entry</A>
4241+
*/
4242+
HRESULT UnregisterApplicationRestart();
4243+
4244+
/**
4245+
* Retrieves the restart information registered for the specified process.
4246+
*
4247+
* @param hProcess A handle to the process. This handle must have the
4248+
* PROCESS_VM_READ access right.
4249+
* @param pwzCommandline A pointer to a buffer that receives the restart
4250+
* command line specified by the application when it
4251+
* called the RegisterApplicationRestart function. The
4252+
* maximum size of the command line, in characters, is
4253+
* RESTART_MAX_CMD_LINE. Can be NULL if pcchSize is
4254+
* zero.
4255+
* @param pcchSize On input, specifies the size of the pwzCommandLine
4256+
* buffer, in characters.
4257+
*
4258+
* <p>
4259+
* If the buffer is not large enough to receive the command line, the
4260+
* function fails with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) and
4261+
* sets this parameter to the required buffer size, in characters.</p>
4262+
* <p>
4263+
* On output, specifies the size of the buffer that was used.</p>
4264+
* <p>
4265+
* To determine the required buffer size, set pwzCommandLine to NULL and
4266+
* this parameter to zero. The size includes one for the null-terminator
4267+
* character. Note that the function returns S_OK, not
4268+
* HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) in this case.</p>
4269+
*
4270+
* @param pdwFlags A pointer to a variable that receives the flags
4271+
* specified by the application when it called the
4272+
* RegisterApplicationRestart function.
4273+
*
4274+
* @return This function returns S_OK on success or one of the following
4275+
* error codes.
4276+
* <table>
4277+
* <tr><th>Return code</th><th>Description</th></tr>
4278+
* <tr><td>E_INVALIDARG</th><th>One or more parameters are not
4279+
* valid.</td></tr>
4280+
* <tr><td>HRESULT_FROM_WIN32(ERROR_NOT_FOUND)</th><th>The application did
4281+
* not register for restart.</td></tr>
4282+
* <tr><td>HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)</th><th>The
4283+
* pwzCommandLine buffer is too small. The function returns the required
4284+
* buffer size in pcchSize. Use the required size to reallocate the
4285+
* buffer.</td></tr>
4286+
* </table>
4287+
*
4288+
* @see <A HREF="https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getapplicationrestartsettings">MSDN Entry</A>
4289+
*/
4290+
HRESULT GetApplicationRestartSettings(HANDLE hProcess, char[] pwzCommandline, IntByReference pcchSize, IntByReference pdwFlags);
41814291
}

contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import com.sun.jna.platform.win32.BaseTSD.SIZE_T;
6565
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
6666
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTRByReference;
67+
import com.sun.jna.platform.win32.COM.COMUtils;
6768
import com.sun.jna.platform.win32.Ntifs.REPARSE_DATA_BUFFER;
6869
import com.sun.jna.platform.win32.Ntifs.SymbolicLinkReparseBuffer;
6970
import com.sun.jna.platform.win32.WinBase.FILETIME;
@@ -84,6 +85,7 @@
8485
import com.sun.jna.platform.win32.WinDef.USHORT;
8586
import com.sun.jna.platform.win32.WinNT.HANDLE;
8687
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
88+
import com.sun.jna.platform.win32.WinNT.HRESULT;
8789
import com.sun.jna.platform.win32.WinNT.MEMORY_BASIC_INFORMATION;
8890
import com.sun.jna.platform.win32.WinNT.OSVERSIONINFO;
8991
import com.sun.jna.platform.win32.WinNT.OSVERSIONINFOEX;
@@ -1910,4 +1912,53 @@ public void run() {
19101912

19111913
assertNull(mutexHandle);
19121914
}
1915+
1916+
public void testApplicationRestart() {
1917+
try {
1918+
HRESULT insufficientBuffer = W32Errors.HRESULT_FROM_WIN32(WinError.ERROR_INSUFFICIENT_BUFFER);
1919+
HRESULT result;
1920+
String dummyCommandline = "/restart -f .\\filename.ext";
1921+
char[] dummyCommandlineArray = Native.toCharArray(dummyCommandline);
1922+
int dummyFlags = 2;
1923+
result = Kernel32.INSTANCE.RegisterApplicationRestart(dummyCommandlineArray, dummyFlags);
1924+
assertTrue(COMUtils.SUCCEEDED(result));
1925+
1926+
char[] queriedCommandlineArray = null;
1927+
IntByReference queriedSize = new IntByReference();
1928+
IntByReference queriedFlags = new IntByReference();
1929+
1930+
// Query without target buffer to determine required buffer size
1931+
result = Kernel32.INSTANCE.GetApplicationRestartSettings(Kernel32.INSTANCE.GetCurrentProcess(), queriedCommandlineArray, queriedSize, queriedFlags);
1932+
1933+
assertTrue(COMUtils.SUCCEEDED(result));
1934+
assertEquals(dummyCommandline.length() + 1, queriedSize.getValue());
1935+
1936+
// Check error reporting, use insufficient buffer size
1937+
queriedCommandlineArray = new char[1];
1938+
queriedSize.setValue(queriedCommandlineArray.length);
1939+
queriedFlags.setValue(-1);
1940+
result = Kernel32.INSTANCE.GetApplicationRestartSettings(Kernel32.INSTANCE.GetCurrentProcess(), queriedCommandlineArray, queriedSize, queriedFlags);
1941+
1942+
assertTrue(COMUtils.FAILED(result));
1943+
assertEquals(insufficientBuffer, result);
1944+
assertEquals(dummyCommandline.length() + 1, queriedSize.getValue());
1945+
1946+
// Now query with the right buffer size
1947+
queriedCommandlineArray = new char[queriedSize.getValue()];
1948+
queriedSize.setValue(queriedCommandlineArray.length);
1949+
queriedFlags.setValue(-1);
1950+
result = Kernel32.INSTANCE.GetApplicationRestartSettings(Kernel32.INSTANCE.GetCurrentProcess(), queriedCommandlineArray, queriedSize, queriedFlags);
1951+
1952+
assertTrue(COMUtils.SUCCEEDED(result));
1953+
assertEquals(dummyCommandline.length() + 1, queriedSize.getValue());
1954+
assertEquals(dummyFlags, queriedFlags.getValue());
1955+
assertEquals(dummyCommandline, Native.toString(queriedCommandlineArray));
1956+
1957+
result = Kernel32.INSTANCE.UnregisterApplicationRestart();
1958+
assertTrue(COMUtils.SUCCEEDED(result));
1959+
} finally {
1960+
// Last resort if test succeeds partially
1961+
Kernel32.INSTANCE.UnregisterApplicationRestart();
1962+
}
1963+
}
19131964
}

0 commit comments

Comments
 (0)