Skip to content

Commit 77c2075

Browse files
Bind part of Windows Application Recovery and Restart API
- c.s.j.p.w.Kernel32#RegisterApplicationRestart - c.s.j.p.w.Kernel32#UnregisterApplicationRestart - c.s.j.p.w.Kernel32#GetApplicationRestartSettings
1 parent 771ca73 commit 77c2075

File tree

3 files changed

+163
-1
lines changed

3 files changed

+163
-1
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
---------

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)