diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..322a2b6ea8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index db83c3d9ac..c839a7b8e5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,33 +8,43 @@ on: branches: - master +permissions: + contents: read + jobs: test: runs-on: ${{ matrix.os }} strategy: matrix: - java: [8, 11, 17, 19, 20-ea] - os: [ubuntu-latest, macos-latest] + java: [8, 11, 17, 21, 23] + # macos-13 is x86, macos-latest is aarch64 + os: [ubuntu-latest, macos-13, macos-latest] + include: + - java: 17 + os: 'ubuntu-24.04-arm' # Run all tests even if one fails fail-fast: false name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: 'zulu' - name: Linux requirements if: contains(matrix.os, 'ubuntu') - run: sudo apt-get -y install texinfo + run: | + sudo apt-get update + sudo apt-get install -yq --allow-downgrades zip unzip libtool automake libltdl-dev texinfo ant ant-optional debhelper-compat default-jdk javahelper libasm-java libffi-dev libx11-dev libxt-dev maven-repo-helper pkg-config - name: macOS requirements if: contains(matrix.os, 'macos') run: | brew update brew install automake --force brew install libtool --force + brew install texinfo --force - name: Checkstyle if: contains(matrix.os, 'ubuntu') && contains(matrix.java, '8') run: | diff --git a/.github/workflows/native-libraries-macOS.yaml b/.github/workflows/native-libraries-macOS.yaml new file mode 100644 index 0000000000..00205ec5c0 --- /dev/null +++ b/.github/workflows/native-libraries-macOS.yaml @@ -0,0 +1,43 @@ +# Build native library for mac OS +name: mac OS native libraries + +on: + workflow_dispatch: + +permissions: + contents: read + +jobs: + build-native-darwin: + runs-on: ${{ matrix.os }} + strategy: + matrix: + java: [21] + os: [macos-latest] + name: Build native libraries for mac OS / darwin + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java }} + distribution: 'zulu' + - name: macOS requirements + if: contains(matrix.os, 'macos') + run: | + brew update + brew install automake --force + brew install libtool --force + brew install texinfo --force + - name: Build native code + run: | + ant -Dos.prefix=darwin-aarch64 + ant -Dos.prefix=darwin-x86-64 + - name: Upload mac OS binaries + uses: actions/upload-artifact@v4 + with: + name: darwin-native + path: | + lib/native/darwin-aarch64.jar + lib/native/darwin-x86-64.jar \ No newline at end of file diff --git a/CHANGES.md b/CHANGES.md index ddfa7a2f1e..223eda0ade 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,9 +2,78 @@ NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and AL 2.0 (see LICENSE NOTE: JNI native support is typically incompatible between minor versions, and almost always incompatible between major versions. -Release (5.13.0) +Release (5.17.0) ================ +Features +-------- +* [#1658](https://github.com/java-native-access/jna/pull/1658): Add win32 power event constants, types, and functions - [@eranl](https://github.com/eranl). + +Bug Fixes +--------- +* [#1647](https://github.com/java-native-access/jna/issues/1647): Fix calls to jnidispatch on Android with 16KB page size (part 2) - [@BugsBeGone](https://github.com/BugsBeGone). + + +Release 5.16.0 +============== + +Features +-------- +* [#1626](https://github.com/java-native-access/jna/pull/1626): Add caching of field list and field validation in `Structure` along with more efficient reentrant read-write locking instead of synchronized() blocks - [@BrettWooldridge](https://github.com/brettwooldridge) + +Bug Fixes +--------- +* [#1618](https://github.com/java-native-access/jna/issues/1618): Fix calls to jnidispatch on Android with 16KB page size - [@Thomyrock](https://github.com/Thomyrock) + +Release 5.15.0 +============== + +Features +-------- +* [#1578](https://github.com/java-native-access/jna/pull/1578): Add support for FreeBSD aarch64 - [@alexdupre](https://github.com/alexdupre). +* [#1593](https://github.com/java-native-access/jna/pull/1593): Add support for DragonFly BSD x86-64 - [@liweitianux](https://github.com/liweitianux). +* [#1595](https://github.com/java-native-access/jna/pull/1595): Add `IsProcessorFeaturePresent` to `c.s.j.p.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis). +* [#1602](https://github.com/java-native-access/jna/pull/1602): Add `XMoveWindow`, `XResizeWindow`, `XMoveResizeWindow`, `XRaiseWindow`, `XLowerWindow` X11 calls to `c.s.j.p.unix.X11` - [@vinceh121](https://github.com/vinceh121). +* [#1613](https://github.com/java-native-access/jna/issues/1613): Added static helper method `Native#getNativeLibrary' for getting the underlying NativeLibrary instance from a Library interface instance or from a "registered" class - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1624](https://github.com/java-native-access/jna/pull/1624): Enable linker build-id for android builds - [@mstyura](https://github.com/mstyura). + +Bug Fixes +--------- +* [#1579](https://github.com/java-native-access/jna/issues/1579): Fix analysis of ELF binary on arm systems running with a java ELF binary without section table headers (java8 on armv7 NAS) - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1586](https://github.com/java-native-access/jna/issues/1586): Fix free_callback JNI weak reference leak - [@xiezhaokun](https://github.com/xiezhaokun). +* [6486c90d913a413f247eef84742ce3c474738933](https://github.com/java-native-access/jna/commit/6486c90d913a413f247eef84742ce3c474738933): Check CallbackReference#cbstruct for null when checking existing Reference - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1622](https://github.com/java-native-access/jna/issues/1622): Add "linux-riscv64" entry to OSGI Bundle-NativeCode header in MANIFEST.MF - [@matthiasblaesing](https://github.com/matthiasblaesing). + +Release 5.14.0 +============== + +Features +-------- +* [#1556](https://github.com/java-native-access/jna/pull/1556): Add `SetJob`, `SetPrinter` to `c.s.j.p.w.Winspool` - [@tresf](https://github.com/tresf). +* [#1534](https://github.com/java-native-access/jna/pull/1534): Add `GetMethod`, `Put`, `SpawnInstance` to `c.s.j.p.win32.COM.WbemCli#IWbemClassObject` and `ExecMethod` to `c.s.j.p.win32.COM.WbemCli#IWbemServices` - [@faddom](https://github.com/faddom). +* [#1544](https://github.com/java-native-access/jna/pull/1544): Add `GetPriorityClass`, `SetPriorityClass`, `GetThreadPriority`, `SetThreadPriority` and associated constants to `c.s.j.p.win32.Kernel32` - [@dEajL3kA](https://github.com/dEajL3kA). +* [#1548](https://github.com/java-native-access/jna/pull/1548): Make interface `c.s.j.p.mac.XAttr public` - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1551](https://github.com/java-native-access/jna/pull/1551): Add `c.s.j.p.bsd.ExtAttr` and `c.s.j.p.bsd.ExtAttrUtil` to wrap BSD [](https://man.freebsd.org/cgi/man.cgi?query=extattr&sektion=2) system calls. [@rednoah](https://github.com/rednoah). +* [#1517](https://github.com/java-native-access/jna/pull/1517): Add missing `O_*` (e.g. `O_APPEND`, `O_SYNC`, `O_DIRECT`, ...) to `c.s.j.p.linux.Fcntl` - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1521](https://github.com/java-native-access/jna/issues/1521): Shutdown CleanerThread once the last cleanable is removed - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1557](https://github.com/java-native-access/jna/issues/1557): Build linux-riscv64 on Ubuntu focal to improve compatibility with older glibc versions - [@matthiasblaesing](https://github.com/matthiasblaesing). + +Bug Fixes +--------- +* [#1501](https://github.com/java-native-access/jna/pull/1501): `Library.OPTION_STRING_ENCODING` is ignore for string arguments function calls - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1504](https://github.com/java-native-access/jna/pull/1504): Increase maximum supported fixed args on varargs calls from 3 to 255 - [@andrew-nowak](https://github.com/andrew-nowak). +* [#1545](https://github.com/java-native-access/jna/pull/1545): Fix Java 6 incompatibility in `c.s.j.p.win32.Kerne32Util` and `c.s.j.p.win32.DBT` - [@matthiasblaesing](https://github.com/matthiasblaesing). + +Important Changes +----------------- +* The interfaces between Java and native code have changed, so `libjnidispatch` + must be rebuilt to be compatible with this release. +* Release drops support for JDKs 6 + 7, so you'll need at least JDK 8 to + update to use this version. + +Release 5.13.0 +============== + Features -------- * [#1454](https://github.com/java-native-access/jna/pull/1454): Add `c.s.j.p.win32.Psapi.QueryWorkingSetEx` and associated Types - [@crain-32](https://github.com/Crain-32). diff --git a/LICENSE b/LICENSE index c5a025f0c3..9d95afbeb5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1 +SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later Java Native Access (JNA) is licensed under the LGPL, version 2.1 or later, or (from version 4.0 onward) the Apache License, diff --git a/README.md b/README.md index f6f230ad77..bc5c77dfaf 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Java Native Access (JNA) ======================== -The definitive JNA reference (including an overview and usage details) is in the [JavaDoc](http://java-native-access.github.io/jna/5.13.0/javadoc/). Please read the [overview](http://java-native-access.github.io/jna/5.13.0/javadoc/overview-summary.html#overview_description). Questions, comments, or exploratory conversations should begin on the [mailing list](http://groups.google.com/group/jna-users), although you may find it easier to find answers to already-solved problems on [StackOverflow](http://stackoverflow.com/questions/tagged/jna). +The definitive JNA reference (including an overview and usage details) is in the [JavaDoc](http://java-native-access.github.io/jna/5.17.0/javadoc/). Please read the [overview](http://java-native-access.github.io/jna/5.17.0/javadoc/overview-summary.html#overview_description). Questions, comments, or exploratory conversations should begin on the [mailing list](http://groups.google.com/group/jna-users), although you may find it easier to find answers to already-solved problems on [StackOverflow](http://stackoverflow.com/questions/tagged/jna). JNA provides Java programs easy access to native shared libraries without writing anything but Java code - no JNI or native code is required. This functionality is comparable to Windows' Platform/Invoke and Python's ctypes. @@ -32,7 +32,8 @@ JNA is a mature library with dozens of contributors and hundreds of commercial a - [VLCJ](https://github.com/caprica/vlcj): Java bindings for libVLC. - [SVNKit](http://svnkit.com): Pure Java Subversion client library. - [OmegaT Computer-Aided Translation](https://omegat.org/). -- [IntelliJ IDEA](https://www.jetbrains.com/) by JetBrains. +- [IntelliJ IDEA](https://www.jetbrains.com/idea) by JetBrains. +- [Jetbrains Toolbox](https://www.jetbrains.com/toolbox-app/) by JetBrains. - [Apache NetBeans IDE](https://netbeans.apache.org/) by Apache Software Foundation. - [FileBot Media Renamer](http://www.filebot.net) by Reinhard Pointner. - [USB for Java](https://launchpad.net/libusb4j) by Mario Boikov. @@ -65,12 +66,12 @@ Pre-built platform support may be found [here](https://github.com/java-native-ac Download ======== -Version 5.13.0 +Version 5.17.0 JNA --- -[![Maven Central](https://img.shields.io/maven-central/v/net.java.dev.jna/jna.svg?label=Maven%20Central)](https://search.maven.org/artifact/net.java.dev.jna/jna/5.13.0/jar) [jna-5.13.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.13.0/jna-5.13.0.jar) [jna-jpms-5.13.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna-jpms/5.13.0/jna-jpms-5.13.0.jar) +[![Maven Central](https://img.shields.io/maven-central/v/net.java.dev.jna/jna.svg?label=Maven%20Central)](https://search.maven.org/artifact/net.java.dev.jna/jna/5.17.0/jar) [jna-5.17.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.17.0/jna-5.17.0.jar) [jna-jpms-5.17.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna-jpms/5.17.0/jna-jpms-5.17.0.jar) This is the core artifact of JNA and contains only the binding library and the core helper classes. @@ -78,7 +79,7 @@ core helper classes. JNA Platform ------------ -[![Maven Central](https://img.shields.io/maven-central/v/net.java.dev.jna/jna-platform.svg?label=Maven%20Central)](https://search.maven.org/artifact/net.java.dev.jna/jna-platform/5.13.0/jar) [jna-platform-5.13.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform/5.13.0/jna-platform-5.13.0.jar) [jna-platform-jpms-5.13.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform-jpms/5.13.0/jna-platform-jpms-5.13.0.jar) +[![Maven Central](https://img.shields.io/maven-central/v/net.java.dev.jna/jna-platform.svg?label=Maven%20Central)](https://search.maven.org/artifact/net.java.dev.jna/jna-platform/5.17.0/jar) [jna-platform-5.17.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform/5.17.0/jna-platform-5.17.0.jar) [jna-platform-jpms-5.17.0.jar](https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform-jpms/5.17.0/jna-platform-jpms-5.17.0.jar) This artifact holds cross-platform mappings and mappings for a number of commonly used platform functions, including a large number of Win32 mappings as well as a set of utility classes @@ -146,12 +147,12 @@ Using the Library * [Platform Library](https://github.com/java-native-access/jna/blob/master/www/PlatformLibrary.md) * [Direct Method Mapping](https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md) (Optimization) * [Frequently Asked Questions (FAQ)](https://github.com/java-native-access/jna/blob/master/www/FrequentlyAskedQuestions.md) -* [Avoiding Crashes](http://java-native-access.github.io/jna/5.13.0/javadoc/overview-summary.html#crash-protection) +* [Avoiding Crashes](http://java-native-access.github.io/jna/5.17.0/javadoc/overview-summary.html#crash-protection) Primary Documentation (JavaDoc) =============================== -The definitive JNA reference is in the [JavaDoc](http://java-native-access.github.io/jna/5.13.0/javadoc/). +The definitive JNA reference is in the [JavaDoc](http://java-native-access.github.io/jna/5.17.0/javadoc/). Developers ========== diff --git a/appveyor.yml b/appveyor.yml index 5f062ed88b..5c9cb3b239 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -40,6 +40,7 @@ for: only: - TARGET_ARCH: x86_64 before_build: + - cmd: set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% - cmd: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64' before_test: - cmd: net start spooler @@ -52,6 +53,7 @@ for: only: - TARGET_ARCH: x86 before_build: + - cmd: set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% - cmd: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86' before_test: - cmd: net start spooler @@ -64,6 +66,7 @@ for: only: - TARGET_ARCH: aarch64 before_build: + - cmd: set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% - cmd: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64_arm64' test_script: - cmd: echo Skipping tests diff --git a/build-ant-tools.xml b/build-ant-tools.xml index bb73fc7462..8248b0bddb 100644 --- a/build-ant-tools.xml +++ b/build-ant-tools.xml @@ -1,5 +1,6 @@ + Builds and tests JNA @@ -8,6 +9,7 @@ destdir="${build}/ant-tools" includeantruntime="false" encoding="UTF-8" + release="${javac.release}" > diff --git a/build.xml b/build.xml index 827d4ac2bd..8f5733a2c6 100644 --- a/build.xml +++ b/build.xml @@ -1,7 +1,6 @@ Builds and tests JNA @@ -13,8 +12,7 @@ support it). Cross-compile by specifying -Dos.prefix={name-arch} to ant - (cross-compile currently only configured/tested on w32ce-arm and - android targets) + (cross-compile currently only configured/tested on android targets) Use ANT_OPTS=-D-native=true to build native parts, or directly invoke the native or test targets @@ -33,7 +31,7 @@ - + @@ -55,74 +53,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -170,16 +101,6 @@ - - - - - - @@ -189,19 +110,6 @@ - - - - - - - - - - - - - @@ -238,9 +146,6 @@ - - - @@ -256,68 +161,8 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -352,7 +197,7 @@ - Java version ${java.version}, compatibility: ${compatibility}, ant: ${ant.java.version} + Java version ${java.version}, compatibility: ${javac.release}, ant: ${ant.java.version} JNA version ${jna.version}, native ${jni.version}, android ${android.versionCode} ${java.vm.name} (${java.vm.vendor}, ${java.vm.version}) java.home=${java.home} @@ -406,8 +251,7 @@ replace='VERSION_NATIVE = "${jni.version}";' file="${build}/jna-src/com/sun/jna/Version.java"/> - - + + + + @@ -760,19 +625,6 @@ osname=macosx;processor=aarch64 - - - - - - - - - - - - - @@ -786,8 +638,9 @@ osname=macosx;processor=aarch64 - - + + + @@ -818,6 +671,12 @@ osname=macosx;processor=aarch64 + + + + + + + + @@ -1057,6 +920,7 @@ osname=macosx;processor=aarch64 + @@ -1183,11 +1047,10 @@ cd .. description="Compile test code which does not have additional native dependencies"> - - Checking JDK compatibility 1.6 - - - - - - - - - - - - Build is not Java 6 compatible and NOT A PRODUCTION BUILD - - - @@ -1423,12 +1269,8 @@ cd .. - - - - - - + + @@ -1463,10 +1305,8 @@ cd .. - - + + @@ -1486,7 +1326,6 @@ cd .. JNA API Documentation
${header}
${footer} - @@ -1505,6 +1344,13 @@ cd .. + + + /* Intentionally left empty */ @@ -1569,50 +1415,50 @@ cd ..
- - + + - + - + - + - + - + - + - + - + - + - - + + @@ -1621,9 +1467,9 @@ cd .. - + - + @@ -1632,9 +1478,9 @@ cd .. - + - + @@ -1643,9 +1489,9 @@ cd .. - + - + @@ -1654,15 +1500,15 @@ cd .. - + - + - + @@ -1672,10 +1518,10 @@ cd .. - + - + @@ -1685,10 +1531,10 @@ cd .. - + - + @@ -1698,10 +1544,10 @@ cd .. - + - + @@ -1711,29 +1557,7 @@ cd .. - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/common.xml b/common.xml new file mode 100644 index 0000000000..2e55640cd6 --- /dev/null +++ b/common.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/platform/build.xml b/contrib/platform/build.xml index 167d39cabf..d13e636a8e 100644 --- a/contrib/platform/build.xml +++ b/contrib/platform/build.xml @@ -2,117 +2,119 @@ Builds and tests platform-specific code. - - + + + - -init-macrodef-javac: defines macro for javac compilation - -init-macrodef-junit: defines macro for junit execution - -init-macrodef-debug: defines macro for class debugging - -init-macrodef-java: defines macro for class execution - -do-jar-with-manifest: JAR building (if you are using a manifest) - -do-jar-without-manifest: JAR building (if you are not using a manifest) - run: execution of project - -javadoc-build: Javadoc generation - test-report: JUnit report generation + + + + + - An example of overriding the target for project execution could look like this: + - - - - - + - Notice that the overridden target depends on the jar target and not only on - the compile target as the regular run target does. Again, for a list of available - properties which you can use, check the target you are overriding in the - nbproject/build-impl.xml file. + + + + - --> + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -178,21 +180,37 @@ com.sun.jna.platform.wince;version="${osgi.version}";uses:="com.s - - - - + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - + + - - - + + + - - - - - - Checking JDK compatibility 1.6 - - - - - - - - - - - - Build is not Java 6 compatible and NOT A PRODUCTION BUILD - - - - Running platform tests: ${test.src.dir} + + Running platform tests: ${test.src} + + + - - + + Saving test results in ${results.junit} - + + + + + + - + + + + + + - + + + + + + - + + + + + + + + + + @@ -284,6 +308,7 @@ com.sun.jna.platform.wince;version="${osgi.version}";uses:="com.s + tests.include=${tests.include} tests.platform.mac=${tests.platform.mac} tests.platform.windows=${tests.platform.windows} tests.platform.linux=${tests.platform.linux} @@ -291,7 +316,8 @@ com.sun.jna.platform.wince;version="${osgi.version}";uses:="com.s - + + @@ -301,13 +327,13 @@ com.sun.jna.platform.wince;version="${osgi.version}";uses:="com.s - + - + - + @@ -325,12 +351,4 @@ com.sun.jna.platform.wince;version="${osgi.version}";uses:="com.s One or more tests failed - - - - - - - - diff --git a/contrib/platform/nbproject/build-impl.xml b/contrib/platform/nbproject/build-impl.xml deleted file mode 100644 index 50e512324a..0000000000 --- a/contrib/platform/nbproject/build-impl.xml +++ /dev/null @@ -1,1420 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No tests executed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set JVM to use for profiling in profiler.info.jvm - Must set profiler agent JVM arguments in profiler.info.jvmargs.agent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - Must select one file in the IDE or set profile.class - This target only works when run from inside the NetBeans IDE. - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - - - Must select some files in the IDE or set test.includes - - - - - Must select one file in the IDE or set run.class - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - Must select some files in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - Must select one file in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/platform/nbproject/ide-file-targets.xml b/contrib/platform/nbproject/ide-file-targets.xml new file mode 100644 index 0000000000..4d439b0c36 --- /dev/null +++ b/contrib/platform/nbproject/ide-file-targets.xml @@ -0,0 +1,93 @@ + + + + Must set property 'run.class' + + + + + + + + + + + + Must set property 'debug.class' + + + + + + + + + + + + + + + + + + Must set property 'run.class' + + + + + + + + + + + + + + Must set property 'debug.class' + + + + + + + + + + + + + + + + + + + Must set property 'tests.include.fullpath' + + + + test.includes: ${tests.include} + + + + + + + + Must set property 'tests.include.fullpath' + + + + test.includes: ${tests.include} + + + + + + + + + + diff --git a/contrib/platform/nbproject/project.properties b/contrib/platform/nbproject/project.properties deleted file mode 100644 index fe6ceb7564..0000000000 --- a/contrib/platform/nbproject/project.properties +++ /dev/null @@ -1,103 +0,0 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -application.args= -application.title=jna-platform -application.vendor=JNA project -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -debug.classpath=\ - ${run.classpath} -debug.modulepath=\ - ${run.modulepath} -debug.test.classpath=\ - ${run.test.classpath} -debug.test.modulepath=\ - ${run.test.modulepath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/jna-platform.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.bcpkix-jdk15on-161.jar=../../lib/test/bcpkix-jdk15on-161.jar -file.reference.bcprov-jdk15on-161.jar=../../lib/test/bcprov-jdk15on-161.jar -file.reference.hamcrest-core-1.3.jar=../../lib/hamcrest-core-1.3.jar -file.reference.jna.jar=../../build/jna.jar -file.reference.jna-test.jar=../../build/jna-test.jar -file.reference.junit.jar=../../lib/junit.jar -includes=** -javac.external.vm=false -javac.modulepath= -javac.processormodulepath= -javac.processorpath=\ - ${javac.classpath} -javac.test.modulepath=\ - ${javac.modulepath} -javadoc.html5=false -jlink.launcher=false -jlink.launcher.name=platform -jar.compress=false -javac.classpath=\ - ${file.reference.jna.jar} -# Space-separated list of extra javac options -javac.compilerargs=-XDignore.symbol.file -javac.deprecation=false -javac.source=1.6 -javac.target=1.6 -javac.test.classpath=\ - ${javac.classpath}:\ - ${file.reference.jna-test.jar}:\ - ${build.classes.dir}:\ - ${file.reference.junit.jar}:\ - ${file.reference.hamcrest-core-1.3.jar}:\ - ${file.reference.bcpkix-jdk15on-161.jar}:\ - ${file.reference.bcprov-jdk15on-161.jar} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding= -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -main.class= -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project -# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value -# or test-sys-prop.name=value to set system properties for unit tests): -run.jvmargs= -run.modulepath=\ - ${javac.modulepath} -run.test.classpath=\ - ${javac.test.classpath}:\ - ../../lib/test/reflections-0.9.11.jar:\ - ../../lib/test/guava-27.1-jre.jar:\ - ../../lib/test/javassist-3.12.1.GA.jar:\ - ../../lib/test/slf4j-api-1.6.1.jar:\ - ../../lib/test/dom4j-1.6.1.jar:\ - ${build.test.classes.dir} -run.test.modulepath=\ - ${javac.test.modulepath} -src.dir=src -test.src.dir=test -source.encoding=UTF-8 -file.encoding=UTF-8 diff --git a/contrib/platform/nbproject/project.xml b/contrib/platform/nbproject/project.xml index 94a0dfa0be..1a14a7faae 100644 --- a/contrib/platform/nbproject/project.xml +++ b/contrib/platform/nbproject/project.xml @@ -1,16 +1,164 @@ - - - org.netbeans.modules.java.j2seproject - - - platform - 1.6.5 - - - - - - - - - + + + org.netbeans.modules.ant.freeform + + + platform + + + + platform + + + + + java + src + UTF-8 + + + + java + test + UTF-8 + + + + + compile-tests + jar + + + clean + + + test + + + clean + compile-tests + jar + + + + run-selected-file-in-src + + run.class + src + \.java$ + java-name + + + + + + + + debug-selected-file-in-src + + debug.class + src + \.java$ + java-name + + + + + + + + debug-selected-file-in-test + + debug.class + test + \.java$ + java-name + + + + + + + + run-selected-file-in-test + + run.class + test + \.java$ + java-name + + + + + + + + test-single + + tests.include.fullpath + test + \.java$ + absolute-path + + + + + + + + debug-test-single + + tests.include.fullpath + test + \.java$ + absolute-path + + + + + + + + + + + src + + + + test + + + build.xml + + + + + + + + + + + + + + + src + ../../build/jna.jar + 1.8 + + + test + + src:../../build/jna.jar:../../build/jna-test.jar:../../build/test-classes:../../lib/junit.jar:../../lib/hamcrest-core-1.3.jar:../../lib/test/bcpkix-jdk15on-161.jar:../../lib/test/bcprov-jdk15on-161.jar + 1.8 + + + + diff --git a/contrib/platform/platform.iml b/contrib/platform/platform.iml deleted file mode 100644 index c341069e19..0000000000 --- a/contrib/platform/platform.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/contrib/platform/src/com/sun/jna/platform/EnumUtils.java b/contrib/platform/src/com/sun/jna/platform/EnumUtils.java index 3c9be3b91a..2f343d32f3 100644 --- a/contrib/platform/src/com/sun/jna/platform/EnumUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/EnumUtils.java @@ -82,7 +82,7 @@ public static > E fromInteger(int idx, Class clazz) public static Set setFromInteger(int flags, Class clazz) { T[] vals = clazz.getEnumConstants(); - Set result = new HashSet(); + Set result = new HashSet<>(); for (T val : vals) { diff --git a/contrib/platform/src/com/sun/jna/platform/FileMonitor.java b/contrib/platform/src/com/sun/jna/platform/FileMonitor.java index 5f7e425b28..fff283c7c7 100644 --- a/contrib/platform/src/com/sun/jna/platform/FileMonitor.java +++ b/contrib/platform/src/com/sun/jna/platform/FileMonitor.java @@ -74,8 +74,8 @@ public String toString() { } } - private final Map watched = new HashMap(); - private List listeners = new ArrayList(); + private final Map watched = new HashMap<>(); + private List listeners = new ArrayList<>(); protected abstract void watch(File file, int mask, boolean recursive) throws IOException ; protected abstract void unwatch(File file); @@ -107,13 +107,13 @@ protected void notify(FileEvent e) { } public synchronized void addFileListener(FileListener listener) { - List list = new ArrayList(listeners); + List list = new ArrayList<>(listeners); list.add(listener); listeners = list; } public synchronized void removeFileListener(FileListener x) { - List list = new ArrayList(listeners); + List list = new ArrayList<>(listeners); list.remove(x); listeners = list; } diff --git a/contrib/platform/src/com/sun/jna/platform/FileUtils.java b/contrib/platform/src/com/sun/jna/platform/FileUtils.java index b318bf7c79..2953189bdb 100644 --- a/contrib/platform/src/com/sun/jna/platform/FileUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/FileUtils.java @@ -104,7 +104,7 @@ public void moveToTrash(File... files) throws IOException { if (!trash.exists()) { throw new IOException("No trash location found (define fileutils.trash to be the path to the trash)"); } - List failed = new ArrayList(); + List failed = new ArrayList<>(); for (int i=0;i < files.length;i++) { File src = files[i]; File target = new File(trash, src.getName()); diff --git a/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java b/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java index 5120b48545..7f1ac32e37 100644 --- a/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java @@ -128,11 +128,11 @@ public static boolean outputOccupiedRanges(Raster raster, RangesOutput out) { * @return true if the output succeeded, false otherwise */ public static boolean outputOccupiedRangesOfBinaryPixels(byte[] binaryBits, int w, int h, RangesOutput out) { - Set rects = new HashSet(); + Set rects = new HashSet<>(); Set prevLine = Collections.emptySet(); int scanlineBytes = binaryBits.length / h; for (int row = 0; row < h; row++) { - Set curLine = new TreeSet(COMPARATOR); + Set curLine = new TreeSet<>(COMPARATOR); int rowOffsetBytes = row * scanlineBytes; int startCol = -1; // Look at each batch of 8 columns in this row @@ -201,10 +201,10 @@ public static boolean outputOccupiedRangesOfBinaryPixels(byte[] binaryBits, int * @return true if the output succeeded, false otherwise */ public static boolean outputOccupiedRanges(int[] pixels, int w, int h, int occupationMask, RangesOutput out) { - Set rects = new HashSet(); + Set rects = new HashSet<>(); Set prevLine = Collections.emptySet(); for (int row = 0; row < h; row++) { - Set curLine = new TreeSet(COMPARATOR); + Set curLine = new TreeSet<>(COMPARATOR); int idxOffset = row * w; int startCol = -1; @@ -241,7 +241,7 @@ public static boolean outputOccupiedRanges(int[] pixels, int w, int h, int occup } private static Set mergeRects(Set prev, Set current) { - Set unmerged = new HashSet(prev); + Set unmerged = new HashSet<>(prev); if (!prev.isEmpty() && !current.isEmpty()) { Rectangle[] pr = prev.toArray(new Rectangle[0]); Rectangle[] cr = current.toArray(new Rectangle[0]); diff --git a/contrib/platform/src/com/sun/jna/platform/WindowUtils.java b/contrib/platform/src/com/sun/jna/platform/WindowUtils.java index 66a3819e60..78ea1fa2dd 100644 --- a/contrib/platform/src/com/sun/jna/platform/WindowUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/WindowUtils.java @@ -1043,9 +1043,9 @@ private void setMask(final Component w, final Area area) { int mode = pi.getWindingRule() == PathIterator.WIND_NON_ZERO ? WinGDI.WINDING: WinGDI.ALTERNATE; float[] coords = new float[6]; - List points = new ArrayList(); + List points = new ArrayList<>(); int size = 0; - List sizes = new ArrayList(); + List sizes = new ArrayList<>(); while (!pi.isDone()) { int type = pi.currentSegment(coords); if (type == PathIterator.SEG_MOVETO) { @@ -1239,7 +1239,7 @@ public Dimension getIconSize(final HICON hIcon) { @Override public List getAllWindows(final boolean onlyVisibleWindows) { - final List result = new LinkedList(); + final List result = new LinkedList<>(); final WNDENUMPROC lpEnumFunc = new WNDENUMPROC() { @Override @@ -1576,7 +1576,7 @@ private static Pixmap createBitmap(final Display dpy, } x11.XSetForeground(dpy, gc, new NativeLong(0)); x11.XFillRectangle(dpy, pm, gc, 0, 0, width, height); - final List rlist = new ArrayList(); + final List rlist = new ArrayList<>(); try { RasterRangesUtils.outputOccupiedRanges(raster, new RasterRangesUtils.RangesOutput() { @Override @@ -1686,7 +1686,7 @@ private synchronized long[] getAlphaVisualIDs() { IntByReference pcount = new IntByReference(); info = x11.XGetVisualInfo(dpy, mask, template, pcount); if (info != null) { - List list = new ArrayList(); + List list = new ArrayList<>(); XVisualInfo[] infos = (XVisualInfo[])info.toArray(pcount.getValue()); for (int i = 0; i < infos.length; i++) { diff --git a/contrib/platform/src/com/sun/jna/platform/bsd/ExtAttr.java b/contrib/platform/src/com/sun/jna/platform/bsd/ExtAttr.java new file mode 100644 index 0000000000..4211068ee1 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/bsd/ExtAttr.java @@ -0,0 +1,47 @@ +/* Copyright (c) 2023 Reinhard Pointner, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.bsd; + +import java.nio.ByteBuffer; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.platform.unix.LibCAPI.size_t; +import com.sun.jna.platform.unix.LibCAPI.ssize_t; + +public interface ExtAttr extends Library { + + ExtAttr INSTANCE = Native.load(null, ExtAttr.class); + + int EXTATTR_NAMESPACE_USER = 0x1; + + ssize_t extattr_get_file(String path, int attrnamespace, String attrname, ByteBuffer data, size_t nbytes); + + ssize_t extattr_set_file(String path, int attrnamespace, String attrname, ByteBuffer data, size_t nbytes); + + int extattr_delete_file(String path, int attrnamespace, String attrname); + + ssize_t extattr_list_file(String path, int attrnamespace, ByteBuffer data, size_t nbytes); + +} diff --git a/contrib/platform/src/com/sun/jna/platform/bsd/ExtAttrUtil.java b/contrib/platform/src/com/sun/jna/platform/bsd/ExtAttrUtil.java new file mode 100644 index 0000000000..f5628ccd32 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/bsd/ExtAttrUtil.java @@ -0,0 +1,115 @@ +/* Copyright (c) 2023 Reinhard Pointner, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.bsd; + +import static java.util.Collections.*; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +import com.sun.jna.Native; +import com.sun.jna.platform.unix.LibCAPI.size_t; + +public class ExtAttrUtil { + + public static List list(String path) throws IOException { + // get required buffer size + long bufferLength = ExtAttr.INSTANCE.extattr_list_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, null, new size_t(0)).longValue(); + + if (bufferLength < 0) { + throw new IOException("errno: " + Native.getLastError()); + } + + if (bufferLength == 0) { + return emptyList(); + } + + ByteBuffer buffer = ByteBuffer.allocate((int) bufferLength); + long valueLength = ExtAttr.INSTANCE.extattr_list_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, buffer, new size_t(bufferLength)).longValue(); + + if (valueLength < 0) { + throw new IOException("errno: " + Native.getLastError()); + } + + return decodeStringList(buffer); + } + + public static ByteBuffer get(String path, String name) throws IOException { + // get required buffer size + long bufferLength = ExtAttr.INSTANCE.extattr_get_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name, null, new size_t(0)).longValue(); + + if (bufferLength < 0) { + throw new IOException("errno: " + Native.getLastError()); + } + + if (bufferLength == 0) { + return ByteBuffer.allocate(0); + } + + ByteBuffer buffer = ByteBuffer.allocate((int) bufferLength); + long valueLength = ExtAttr.INSTANCE.extattr_get_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name, buffer, new size_t(bufferLength)).longValue(); + + if (valueLength < 0) { + throw new IOException("errno: " + Native.getLastError()); + } + + return buffer; + } + + public static void set(String path, String name, ByteBuffer value) throws IOException { + long r = ExtAttr.INSTANCE.extattr_set_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name, value, new size_t(value.remaining())).longValue(); + if (r < 0) { + throw new IOException("errno: " + Native.getLastError()); + } + } + + public static void delete(String path, String name) throws IOException { + int r = ExtAttr.INSTANCE.extattr_delete_file(path, ExtAttr.EXTATTR_NAMESPACE_USER, name); + if (r < 0) { + throw new IOException("errno: " + Native.getLastError()); + } + } + + private static List decodeStringList(ByteBuffer buffer) { + List list = new ArrayList<>(); + + while (buffer.hasRemaining()) { + int length = buffer.get() & 0xFF; + byte[] value = new byte[length]; + buffer.get(value); + + try { + list.add(new String(value, "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + return list; + } + +} diff --git a/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java b/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java index 88cf7a58bb..dcd31c71df 100644 --- a/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java +++ b/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java @@ -388,7 +388,7 @@ public void drop(DropTargetDropEvent e) { * @return whether any of the given flavors are supported */ protected boolean isSupported(DataFlavor[] flavors) { - Set set = new HashSet(Arrays.asList(flavors)); + Set set = new HashSet<>(Arrays.asList(flavors)); set.retainAll(acceptedFlavors); return !set.isEmpty(); } diff --git a/contrib/platform/src/com/sun/jna/platform/linux/Fcntl.java b/contrib/platform/src/com/sun/jna/platform/linux/Fcntl.java index c5afe0dd5a..d99099fe60 100644 --- a/contrib/platform/src/com/sun/jna/platform/linux/Fcntl.java +++ b/contrib/platform/src/com/sun/jna/platform/linux/Fcntl.java @@ -38,9 +38,26 @@ public interface Fcntl { * Bits OR'd into the second argument to open. Note these are defined * differently on linux than unix fcntl header */ - int O_CREAT = 0100; // Create file if it doesn't exist. - int O_EXCL = 0200; // Fail if file already exists. - int O_TRUNC = 01000; // Truncate file to zero length. + int O_CREAT = 000000100; // Create file if it doesn't exist. + int O_EXCL = 000000200; // Fail if file already exists. + int O_TRUNC = 000001000; // Truncate file to zero length. + int O_APPEND = 000002000; + int O_NONBLOCK = 000004000; + int O_DSYNC = 000010000; + int O_FASYNC = 000020000; + int O_DIRECT = 000040000; + int O_LARGEFILE = 000100000; + int O_DIRECTORY = 000200000; + int O_NOFOLLOW = 000400000; + int O_NOATIME = 001000000; + int O_CLOEXEC = 002000000; + int __O_SYNC = 004000000; + int O_PATH = 010000000; + int __O_TMPFILE = 020000000; + + int O_SYNC = (__O_SYNC | O_DSYNC); + int O_TMPFILE = (__O_TMPFILE | O_DIRECTORY); + int O_NDELAY = O_NONBLOCK; /* Protection bits. */ int S_IRUSR = 00400; // Read by owner. diff --git a/contrib/platform/src/com/sun/jna/platform/linux/LibC.java b/contrib/platform/src/com/sun/jna/platform/linux/LibC.java index ae21e0c9c5..c688f09c92 100644 --- a/contrib/platform/src/com/sun/jna/platform/linux/LibC.java +++ b/contrib/platform/src/com/sun/jna/platform/linux/LibC.java @@ -73,7 +73,7 @@ class Sysinfo extends Structure { */ @Override protected List getFieldList() { - List fields = new ArrayList(super.getFieldList()); + List fields = new ArrayList<>(super.getFieldList()); if (PADDING_SIZE == 0) { Iterator fieldIterator = fields.iterator(); while (fieldIterator.hasNext()) { @@ -88,7 +88,7 @@ protected List getFieldList() { @Override protected List getFieldOrder() { - List fieldOrder = new ArrayList(super.getFieldOrder()); + List fieldOrder = new ArrayList<>(super.getFieldOrder()); if (PADDING_SIZE == 0) { fieldOrder.remove("_f"); } @@ -122,7 +122,7 @@ class Statvfs extends Structure { */ @Override protected List getFieldList() { - List fields = new ArrayList(super.getFieldList()); + List fields = new ArrayList<>(super.getFieldList()); if (NativeLong.SIZE > 4) { Iterator fieldIterator = fields.iterator(); while (fieldIterator.hasNext()) { @@ -137,7 +137,7 @@ protected List getFieldList() { @Override protected List getFieldOrder() { - List fieldOrder = new ArrayList(super.getFieldOrder()); + List fieldOrder = new ArrayList<>(super.getFieldOrder()); if (NativeLong.SIZE > 4) { fieldOrder.remove("_f_unused"); } diff --git a/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java b/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java index 3176a4942f..1a03852042 100644 --- a/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java @@ -657,7 +657,7 @@ public static void fRemoveXAttr(int fd, String name) throws IOException { private static Collection splitBufferToStrings(byte[] valueMem, String encoding) throws IOException { final Charset charset = Charset.forName(encoding); - final Set attributesList = new LinkedHashSet(1); + final Set attributesList = new LinkedHashSet<>(1); int offset = 0; for(int i = 0; i < valueMem.length; i++) { // each entry is terminated by a single \0 byte diff --git a/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java b/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java index 29cfe7d531..5bc700ebeb 100644 --- a/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java @@ -69,7 +69,7 @@ class FSRef extends Structure { @Override public void moveToTrash(File... files) throws IOException { - List failed = new ArrayList(); + List failed = new ArrayList<>(); for (File src: files) { FileManager.FSRef fsref = new FileManager.FSRef(); int status = FileManager.INSTANCE.FSPathMakeRefWithOptions(src.getAbsolutePath(), diff --git a/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java b/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java index 1cad125a93..666324212c 100644 --- a/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java +++ b/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java @@ -31,7 +31,7 @@ * JNA wrapper for <sys/xattr.h> * */ -interface XAttr extends Library { +public interface XAttr extends Library { // load from current image XAttr INSTANCE = Native.load(null, XAttr.class); diff --git a/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java b/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java index a8ba9d2fdf..22bf4abffe 100644 --- a/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java @@ -41,7 +41,7 @@ public static List listXAttr(String path) { return null; if (bufferLength == 0) - return new ArrayList(0); + return new ArrayList<>(0); Memory valueBuffer = new Memory(bufferLength); long valueLength = XAttr.INSTANCE.listxattr(path, valueBuffer, bufferLength, 0); @@ -97,7 +97,7 @@ protected static String decodeString(ByteBuffer bb) { } protected static List decodeStringSequence(ByteBuffer bb) { - List names = new ArrayList(); + List names = new ArrayList<>(); bb.mark(); // first key starts from here while (bb.hasRemaining()) { diff --git a/contrib/platform/src/com/sun/jna/platform/unix/X11.java b/contrib/platform/src/com/sun/jna/platform/unix/X11.java index 08627b6405..ce7e8193f4 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/X11.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/X11.java @@ -900,6 +900,12 @@ int XGetGeometry(Display display, Drawable d, WindowByReference w, IntByReferenc boolean XTranslateCoordinates(Display display, Window src_w, Window dest_w, int src_x, int src_y, IntByReference dest_x_return, IntByReference dest_y_return, WindowByReference child_return); + int XMoveWindow(Display display, Window w, int x, int y); + int XResizeWindow(Display display, Window w, int width, int height); + int XMoveResizeWindow(Display display, Window w, int x, int y, int width, int height); + int XRaiseWindow(Display display, Window w); + int XLowerWindow(Display display, Window w); + /***************************************************************** * RESERVED RESOURCE AND CONSTANT DEFINITIONS *****************************************************************/ diff --git a/contrib/platform/src/com/sun/jna/platform/unix/aix/SharedObjectLoader.java b/contrib/platform/src/com/sun/jna/platform/unix/aix/SharedObjectLoader.java index 8bdac4ba4f..4734f1422b 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/aix/SharedObjectLoader.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/aix/SharedObjectLoader.java @@ -55,7 +55,7 @@ private static Map getOptions() { int RTLD_MEMBER = 0x40000; // allows "lib.a(obj.o)" syntax int RTLD_GLOBAL = 0x10000; int RTLD_LAZY = 0x4; - Map options = new HashMap(); + Map options = new HashMap<>(); options.put(Library.OPTION_OPEN_FLAGS, RTLD_MEMBER | RTLD_GLOBAL | RTLD_LAZY); return Collections.unmodifiableMap(options); } diff --git a/contrib/platform/src/com/sun/jna/platform/unix/solaris/Kstat2.java b/contrib/platform/src/com/sun/jna/platform/unix/solaris/Kstat2.java index 6861fd4940..9b6a504077 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/solaris/Kstat2.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/solaris/Kstat2.java @@ -272,10 +272,10 @@ public Kstat2NV mapGet(String name) { * {@link Kstat2Map} is returned. *

* If the value is of type {@link Kstat2#KSTAT2_NVVT_INT}, a - * {@link long} is returned. + * {@code long} is returned. *

* If the value is of type {@link Kstat2#KSTAT2_NVVT_INTS}, an array of - * {@link long} is returned. + * {@code long} is returned. *

* If the value is of type {@link Kstat2#KSTAT2_NVVT_STR}, a * {@link String} is returned. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java index 26dd22d256..a81032fc94 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java @@ -455,7 +455,7 @@ public static Account[] getTokenGroups(HANDLE hToken) { tokenInformationLength.getValue(), tokenInformationLength)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - ArrayList userGroups = new ArrayList(); + ArrayList userGroups = new ArrayList<>(); // make array of names for (SID_AND_ATTRIBUTES sidAndAttribute : groups.getGroups()) { Account group; @@ -975,7 +975,7 @@ public static String[] registryGetStringArray(HKEY hKey, String value) { * @return An array of strings corresponding to the strings in the buffer. */ static String[] regMultiSzBufferToStringArray(Memory data) { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); int offset = 0; while (offset < data.size()) { String s; @@ -1995,7 +1995,7 @@ public static String[] registryGetKeys(HKEY hKey) { if (rc != W32Errors.ERROR_SUCCESS) { throw new Win32Exception(rc); } - ArrayList keys = new ArrayList(lpcSubKeys.getValue()); + ArrayList keys = new ArrayList<>(lpcSubKeys.getValue()); char[] name = new char[lpcMaxSubKeyLen.getValue() + 1]; for (int i = 0; i < lpcSubKeys.getValue(); i++) { IntByReference lpcchValueName = new IntByReference( @@ -2129,7 +2129,7 @@ public static TreeMap registryGetValues(HKEY hKey) { if (rc != W32Errors.ERROR_SUCCESS) { throw new Win32Exception(rc); } - TreeMap keyValues = new TreeMap(); + TreeMap keyValues = new TreeMap<>(); char[] name = new char[lpcMaxValueNameLen.getValue() + 1]; // Allocate enough memory to hold largest value and two // terminating WCHARs -- the memory is zeroed so after @@ -2200,7 +2200,7 @@ public static TreeMap registryGetValues(HKEY hKey) { break; } case WinNT.REG_MULTI_SZ: { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); int offset = 0; while (offset < byteData.size()) { String s; @@ -2529,7 +2529,7 @@ public EventLogRecord(Pointer pevlr) { } // strings if (_record.NumStrings.intValue() > 0) { - ArrayList strings = new ArrayList(); + ArrayList strings = new ArrayList<>(); int count = _record.NumStrings.intValue(); long offset = _record.StringOffset.intValue(); while (count > 0) { @@ -2700,8 +2700,8 @@ public static ACE_HEADER[] getFileSecurity(String fileName, ACE_HEADER[] aceStructures = dacl.getACEs(); if (compact) { - List result = new ArrayList(); - Map aceMap = new HashMap(); + List result = new ArrayList<>(); + Map aceMap = new HashMap<>(); for (ACE_HEADER aceStructure : aceStructures) { if (aceStructure instanceof ACCESS_ACEStructure) { ACCESS_ACEStructure accessACEStructure = (ACCESS_ACEStructure) aceStructure; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java index 43ab72ce48..ec54d31d95 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java @@ -337,6 +337,8 @@ protected VARIANT invoke(String methodName, VARIANT arg1, VARIANT arg2, } /** + * @param methodName + * @param dispatch * @deprecated Use {@link #invokeNoReply(java.lang.String)} */ @Deprecated @@ -345,6 +347,8 @@ protected void invokeNoReply(String methodName, IDispatch dispatch) { } /** + * @param methodName + * @param comObject * @deprecated Use {@link #invokeNoReply(java.lang.String)} */ @Deprecated @@ -366,6 +370,9 @@ protected void invokeNoReply(String methodName, VARIANT arg) { } /** + * @param methodName + * @param dispatch + * @param arg * @deprecated Use {@link #invokeNoReply(java.lang.String, com.sun.jna.platform.win32.Variant.VARIANT)} */ @Deprecated @@ -375,6 +382,10 @@ protected void invokeNoReply(String methodName, IDispatch dispatch, } /** + * @param methodName + * @param arg2 + * @param dispatch + * @param arg1 * @deprecated Use {@link #invokeNoReply(java.lang.String, com.sun.jna.platform.win32.Variant.VARIANT[])} */ @Deprecated @@ -385,6 +396,10 @@ protected void invokeNoReply(String methodName, IDispatch dispatch, } /** + * @param methodName + * @param arg1 + * @param comObject + * @param arg2 * @deprecated Use {@link #invokeNoReply(java.lang.String, com.sun.jna.platform.win32.Variant.VARIANT[])} */ @Deprecated @@ -395,6 +410,9 @@ protected void invokeNoReply(String methodName, COMLateBindingObject comObject, } /** + * @param methodName + * @param comObject + * @param arg * @deprecated Use {@link #invokeNoReply(java.lang.String, com.sun.jna.platform.win32.Variant.VARIANT)} */ @Deprecated @@ -406,6 +424,9 @@ protected void invokeNoReply(String methodName, /** + * @param methodName + * @param dispatch + * @param args * @deprecated Use {@link #invokeNoReply(java.lang.String, com.sun.jna.platform.win32.Variant.VARIANT[])} */ @Deprecated @@ -526,6 +547,8 @@ protected void setProperty(String propertyName, Dispatch value) { } /** + * @param propertyName + * @param value * @deprecated Use {@link #setProperty(java.lang.String, com.sun.jna.platform.win32.COM.Dispatch)} */ @Deprecated @@ -587,6 +610,9 @@ protected void setProperty(String propertyName, VARIANT value) { } /** + * @param propertyName + * @param iDispatch + * @param value * @deprecated Use {@link #setProperty(java.lang.String, com.sun.jna.platform.win32.Variant.VARIANT)} */ @Deprecated @@ -597,6 +623,9 @@ protected void setProperty(String propertyName, IDispatch iDispatch, } /** + * @param propertyName + * @param comObject + * @param value * @deprecated Use {@link #setProperty(java.lang.String, com.sun.jna.platform.win32.Variant.VARIANT)} */ @Deprecated @@ -611,6 +640,7 @@ protected void setProperty(String propertyName, * * @return the variant */ + @SuppressWarnings("deprecation") public VARIANT toVariant() { return new VARIANT(this.getIDispatch()); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java index c689958e78..bf2bb315f4 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java @@ -222,7 +222,7 @@ public static ArrayList getAllCOMInfoOnSystem() { HKEYByReference phkResult = new HKEYByReference(); HKEYByReference phkResult2 = new HKEYByReference(); String subKey; - ArrayList comInfos = new ArrayList(); + ArrayList comInfos = new ArrayList<>(); try { // open root key diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/Wbemcli.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/Wbemcli.java index 4a2039ceda..696d75ee6e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/Wbemcli.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/Wbemcli.java @@ -137,6 +137,23 @@ public HRESULT Get(String wszName, int lFlags, VARIANT.ByReference pVal, IntByRe return Get(wszName == null ? null : new WString(wszName), lFlags, pVal, pType, plFlavor); } + public HRESULT GetMethod(String wszName, int lFlags, PointerByReference ppInSignature, PointerByReference ppOutSignature) { + return GetMethod(wszName == null ? null : new WString(wszName), lFlags, ppInSignature, ppOutSignature); + } + + public HRESULT GetMethod(WString wszName, int lFlags, PointerByReference ppInSignature, PointerByReference ppOutSignature) { + // 20th method in IWbemClassObjectVtbl + return (HRESULT) _invokeNativeObject(19, + new Object[]{ getPointer(), wszName, lFlags, ppInSignature, ppOutSignature}, HRESULT.class); + } + + public IWbemClassObject GetMethod(String wszName) { + PointerByReference ppInSignature = new PointerByReference(); + HRESULT res = GetMethod(wszName, 0, ppInSignature, null); + COMUtils.checkRC(res); + return new IWbemClassObject(ppInSignature.getValue()); + } + public HRESULT GetNames(String wszQualifierName, int lFlags, VARIANT.ByReference pQualifierVal, PointerByReference pNames) { return GetNames(wszQualifierName == null ? null : new WString(wszQualifierName), lFlags, pQualifierVal, pNames); } @@ -194,6 +211,42 @@ public IWbemQualifierSet GetPropertyQualifierSet(String strProperty) { IWbemQualifierSet qualifier = new IWbemQualifierSet(ppQualSet.getValue()); return qualifier; } + + public HRESULT Put(String wszName, int lFlags, Variant.VARIANT pVal, int Type) { + return Put(wszName == null ? null : new WString(wszName), lFlags, pVal, Type); + } + + public HRESULT Put(WString wszName, int lFlags, Variant.VARIANT pVal, int Type) { + // 6th method in IWbemClassObjectVtbl + return (HRESULT) _invokeNativeObject(5, + new Object[]{ getPointer(), wszName, lFlags, pVal, Type}, HRESULT.class); + } + + public void Put(String wszName, String pValue) { + Variant.VARIANT aVariant = new Variant.VARIANT(); + BSTR strValue = OleAuto.INSTANCE.SysAllocString(pValue); + try { + aVariant.setValue(Variant.VT_BSTR, strValue); + HRESULT res = Put(wszName, 0, aVariant, 0); + COMUtils.checkRC(res); + } + finally { + OleAuto.INSTANCE.VariantClear(aVariant); + } + } + + public HRESULT SpawnInstance(int lFlags, PointerByReference ppNewInstance) { + // 16th method in IWbemClassObjectVtbl + return (HRESULT) _invokeNativeObject(15, + new Object[]{ getPointer(), lFlags, ppNewInstance}, HRESULT.class); + } + + public IWbemClassObject SpawnInstance() { + PointerByReference ppNewInstance = new PointerByReference(); + HRESULT res = SpawnInstance(0, ppNewInstance); + COMUtils.checkRC(res); + return new IWbemClassObject(ppNewInstance.getValue()); + } } class IWbemQualifierSet extends Unknown { @@ -348,6 +401,31 @@ public IWbemServices(Pointer pvInstance) { super(pvInstance); } + public HRESULT ExecMethod(BSTR strObjectPath, BSTR strMethodName, int lFlags, IWbemContext pCtx, + Pointer pInParams, PointerByReference ppOutParams, PointerByReference ppCallResult) { + // ExecMethod is 25st method of IWbemServicesVtbl in WbemCli.h + return (HRESULT) _invokeNativeObject(24, + new Object[] { getPointer(), strObjectPath, strMethodName, lFlags, pCtx, pInParams, ppOutParams, ppCallResult }, HRESULT.class); + } + + public IWbemClassObject ExecMethod(String strObjectPath, String strMethodName, int lFlags, IWbemContext pCtx, + IWbemClassObject inParams) { + BSTR strObjectPathBSTR = OleAuto.INSTANCE.SysAllocString(strObjectPath); + BSTR strMethodNameBSTR = OleAuto.INSTANCE.SysAllocString(strMethodName); + try { + PointerByReference ppOutParams = new PointerByReference(); + + HRESULT res = ExecMethod(strObjectPathBSTR, strMethodNameBSTR, lFlags, pCtx, inParams.getPointer(), ppOutParams, null); + + COMUtils.checkRC(res); + + return new IWbemClassObject(ppOutParams.getValue()); + } finally { + OleAuto.INSTANCE.SysFreeString(strObjectPathBSTR); + OleAuto.INSTANCE.SysFreeString(strMethodNameBSTR); + } + } + public HRESULT ExecQuery(BSTR strQueryLanguage, BSTR strQuery, int lFlags, IWbemContext pCtx, PointerByReference ppEnum) { // ExecQuery is 21st method of IWbemServicesVtbl in WbemCli.h diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/WbemcliUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/WbemcliUtil.java index 828361b7d3..a3e08684fb 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/WbemcliUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/WbemcliUtil.java @@ -284,12 +284,12 @@ private static > IEnumWbemClassObject selectProperties(IWbemSe */ private static > WmiResult enumerateProperties(IEnumWbemClassObject enumerator, Class propertyEnum, int timeout) throws TimeoutException { - WmiResult values = INSTANCE.new WmiResult(propertyEnum); + WmiResult values = INSTANCE.new WmiResult<>(propertyEnum); // Step 7: ------------------------------------------------- // Get the data from the query in step 6 ------------------- Pointer[] pclsObj = new Pointer[1]; IntByReference uReturn = new IntByReference(0); - Map wstrMap = new HashMap(); + Map wstrMap = new HashMap<>(); HRESULT hres = null; for (T property : propertyEnum.getEnumConstants()) { wstrMap.put(property, new WString(property.name())); @@ -381,11 +381,11 @@ public class WmiResult> { * The enum associated with this map */ public WmiResult(Class propertyEnum) { - propertyMap = new EnumMap>(propertyEnum); - vtTypeMap = new EnumMap(propertyEnum); - cimTypeMap = new EnumMap(propertyEnum); + propertyMap = new EnumMap<>(propertyEnum); + vtTypeMap = new EnumMap<>(propertyEnum); + cimTypeMap = new EnumMap<>(propertyEnum); for (T prop : propertyEnum.getEnumConstants()) { - propertyMap.put(prop, new ArrayList()); + propertyMap.put(prop, new ArrayList<>()); vtTypeMap.put(prop, Variant.VT_NULL); cimTypeMap.put(prop, Wbemcli.CIM_EMPTY); } @@ -486,7 +486,7 @@ public static boolean hasNamespace(String namespace) { ns = namespace.substring(5); } // Test - WmiQuery namespaceQuery = new WmiQuery("ROOT", "__NAMESPACE", NamespaceProperty.class); + WmiQuery namespaceQuery = new WmiQuery<>("ROOT", "__NAMESPACE", NamespaceProperty.class); WmiResult namespaces = namespaceQuery.execute(); for (int i = 0; i < namespaces.getResultCount(); i++) { if (ns.equalsIgnoreCase((String) namespaces.getValue(NamespaceProperty.NAME, i))) { diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index bc05fc1bbc..58c91b77fd 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -56,6 +56,7 @@ import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; +import java.lang.reflect.InvocationTargetException; public class CallbackProxy implements IDispatchCallback { // Helper declarations, initialized to default values by jvm @@ -85,7 +86,7 @@ public CallbackProxy(ObjectFactory factory, Class comEventCallbackInterface, public DispatchListener dispatchListener; Map dsipIdMap; - REFIID createRIID(Class comEventCallbackInterface) { + private REFIID createRIID(Class comEventCallbackInterface) { ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); if (null == comInterfaceAnnotation) { throw new COMException( @@ -98,8 +99,9 @@ REFIID createRIID(Class comEventCallbackInterface) { return new REFIID(new IID(iidStr).getPointer()); } - Map createDispIdMap(Class comEventCallbackInterface) { - Map map = new HashMap(); + @SuppressWarnings("deprecation") // ComEventCallback is used here to be backwards compatible + private Map createDispIdMap(Class comEventCallbackInterface) { + Map map = new HashMap<>(); for (Method meth : comEventCallbackInterface.getMethods()) { ComEventCallback callbackAnnotation = meth.getAnnotation(ComEventCallback.class); @@ -132,7 +134,7 @@ Map createDispIdMap(Class comEventCallbackInterface) { return map; } - int fetchDispIdFromName(ComEventCallback annotation) { + private int fetchDispIdFromName(ComEventCallback annotation) { // TODO return -1; } @@ -233,7 +235,7 @@ void invokeOnThread(final DISPID dispIdMember, final REFIID riid, LCID lcid, WOR try { eventMethod.invoke(comEventCallbackListener, params); } catch (Exception e) { - List decodedClassNames = new ArrayList(params.length); + List decodedClassNames = new ArrayList<>(params.length); for (Object o : params) { if (o == null) { decodedClassNames.add("NULL"); @@ -299,10 +301,12 @@ public HRESULT QueryInterface(REFIID refid, PointerByReference ppvObject) { return new HRESULT(WinError.E_NOINTERFACE); } + @Override public int AddRef() { return 0; } + @Override public int Release() { return 0; } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java index acc650ac9f..b840ef7e69 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java @@ -37,7 +37,7 @@ import com.sun.jna.platform.win32.COM.COMUtils; public class ComThread { - private static ThreadLocal isCOMThread = new ThreadLocal(); + private static ThreadLocal isCOMThread = new ThreadLocal<>(); ExecutorService executor; Runnable firstTask; @@ -116,9 +116,7 @@ public void run() { executor.shutdown(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { + } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } catch (TimeoutException e) { executor.shutdownNow(); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java index 3884fec55b..60b696408b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java @@ -23,7 +23,6 @@ */ package com.sun.jna.platform.win32.COM.util; -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.OleAuto; import com.sun.jna.platform.win32.Variant; import java.lang.reflect.InvocationHandler; @@ -88,6 +87,7 @@ class Convert { * * @return wrapped VARIANT */ + @SuppressWarnings("deprecation") public static VARIANT toVariant(Object value) { if (value instanceof VARIANT) { return (VARIANT) value; @@ -298,10 +298,7 @@ public static T toComEnum(Class enumType, Object value) return t; } } - } catch (NoSuchMethodException e) { - } catch (IllegalAccessException e) { - } catch (IllegalArgumentException e) { - } catch (InvocationTargetException e) { + } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } return null; } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 06e7fe49e4..41d94fd48e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -170,9 +170,7 @@ public IRunningObjectTable getRunningObjectTable() { private T runInComThread(Callable callable) { try { return comThread.execute(callable); - } catch (TimeoutException ex) { - throw new RuntimeException(ex); - } catch (InterruptedException ex) { + } catch (TimeoutException | InterruptedException ex) { throw new RuntimeException(ex); } catch (ExecutionException ex) { Throwable cause = ex.getCause(); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java index 7409b499dc..938002f31f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java @@ -180,11 +180,11 @@ IDispatchCallback createDispatchCallback(Class comEventCallbackInterface, ICo // environment and can't be used anymore. registeredObjects is used // to dispose interfaces even if garbadge collection has not yet collected // the proxy objects. - private final List> registeredObjects = new LinkedList>(); + private final List> registeredObjects = new LinkedList<>(); public void register(ProxyObject proxyObject) { synchronized (this.registeredObjects) { - this.registeredObjects.add(new WeakReference(proxyObject)); + this.registeredObjects.add(new WeakReference<>(proxyObject)); } } @@ -203,7 +203,7 @@ public void unregister(ProxyObject proxyObject) { public void disposeAll() { synchronized (this.registeredObjects) { - List> s = new ArrayList>(this.registeredObjects); + List> s = new ArrayList<>(this.registeredObjects); for (WeakReference weakRef : s) { ProxyObject po = weakRef.get(); if (po != null) { diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java index 99db4083c3..767f72ff89 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java @@ -60,7 +60,7 @@ public Iterable enumRunning() { public List getActiveObjectsByInterface(Class comInterface) { assert COMUtils.comIsInitialized() : "COM not initialized"; - List result = new ArrayList(); + List result = new ArrayList<>(); for (IDispatch obj : this.enumRunning()) { try { diff --git a/contrib/platform/src/com/sun/jna/platform/win32/DBT.java b/contrib/platform/src/com/sun/jna/platform/win32/DBT.java index 182c0cbf5b..e2c8d27b03 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/DBT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/DBT.java @@ -32,7 +32,7 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinUser.HDEVNOTIFY; import com.sun.jna.win32.W32APITypeMapper; -import java.nio.charset.StandardCharsets; +import java.io.UnsupportedEncodingException; import java.util.logging.Logger; /** @@ -326,7 +326,13 @@ public String getDbcpName() { if(W32APITypeMapper.DEFAULT == W32APITypeMapper.ASCII) { return Native.toString(this.dbcp_name); } else { - return new String(this.dbcp_name, StandardCharsets.UTF_16LE); + try { + return new String(this.dbcp_name, "UTF-16LE"); + } catch (UnsupportedEncodingException ex) { + // UTF-16LE is documented to be present at least beginning + // with JDK 6 + throw new RuntimeException(ex); + } } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java index 6af8abb841..9fc499e1cc 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java @@ -1640,7 +1640,7 @@ public WinDef.PVOID ddeCallback(int wType, int wFmt, Ddeml.HCONV hConv, Ddeml.HS return new WinDef.PVOID(); }; - private final List advstartHandler = new CopyOnWriteArrayList(); + private final List advstartHandler = new CopyOnWriteArrayList<>(); public void registerAdvstartHandler(AdvstartHandler handler) { advstartHandler.add(handler); @@ -1660,7 +1660,7 @@ private boolean onAdvstart(int transactionType, int dataFormat, Ddeml.HCONV hcon return oneHandlerTrue; } - private final List advstopHandler = new CopyOnWriteArrayList(); + private final List advstopHandler = new CopyOnWriteArrayList<>(); public void registerAdvstopHandler(AdvstopHandler handler) { advstopHandler.add(handler); @@ -1676,7 +1676,7 @@ private void onAdvstop(int transactionType, int dataFormat, Ddeml.HCONV hconv, D } } - private final List connectHandler = new CopyOnWriteArrayList(); + private final List connectHandler = new CopyOnWriteArrayList<>(); public void registerConnectHandler(ConnectHandler handler) { connectHandler.add(handler); @@ -1696,7 +1696,7 @@ private boolean onConnect(int transactionType, Ddeml.HSZ topic, Ddeml.HSZ servic return oneHandlerTrue; } - private final List advReqHandler = new CopyOnWriteArrayList(); + private final List advReqHandler = new CopyOnWriteArrayList<>(); public void registerAdvReqHandler(AdvreqHandler handler) { advReqHandler.add(handler); @@ -1716,7 +1716,7 @@ private Ddeml.HDDEDATA onAdvreq(int transactionType, int dataFormat, Ddeml.HCONV return null; } - private final List requestHandler = new CopyOnWriteArrayList(); + private final List requestHandler = new CopyOnWriteArrayList<>(); public void registerRequestHandler(RequestHandler handler) { requestHandler.add(handler); @@ -1736,7 +1736,7 @@ private Ddeml.HDDEDATA onRequest(int transactionType, int dataFormat, Ddeml.HCON return null; } - private final List wildconnectHandler = new CopyOnWriteArrayList(); + private final List wildconnectHandler = new CopyOnWriteArrayList<>(); public void registerWildconnectHandler(WildconnectHandler handler) { wildconnectHandler.add(handler); @@ -1747,7 +1747,7 @@ public void unregisterWildconnectHandler(WildconnectHandler handler) { } private Ddeml.HSZPAIR[] onWildconnect(int transactionType, HSZ topic, HSZ service, CONVCONTEXT convcontext, boolean sameInstance) { - List hszpairs = new ArrayList(1); + List hszpairs = new ArrayList<>(1); for(WildconnectHandler handler: wildconnectHandler) { hszpairs.addAll(handler.onWildconnect(transactionType, topic, service, convcontext, sameInstance)); } @@ -1755,7 +1755,7 @@ private Ddeml.HSZPAIR[] onWildconnect(int transactionType, HSZ topic, HSZ servic } - private final List advdataHandler = new CopyOnWriteArrayList(); + private final List advdataHandler = new CopyOnWriteArrayList<>(); public void registerAdvdataHandler(AdvdataHandler handler) { advdataHandler.add(handler); @@ -1775,7 +1775,7 @@ private int onAdvdata(int transactionType, int dataFormat, HCONV hconv, HSZ topi return Ddeml.DDE_FNOTPROCESSED; } - private final List executeHandler = new CopyOnWriteArrayList(); + private final List executeHandler = new CopyOnWriteArrayList<>(); public void registerExecuteHandler(ExecuteHandler handler) { executeHandler.add(handler); @@ -1795,7 +1795,7 @@ private int onExecute(int transactionType, HCONV hconv, HSZ topic, HDDEDATA comm return Ddeml.DDE_FNOTPROCESSED; } - private final List pokeHandler = new CopyOnWriteArrayList(); + private final List pokeHandler = new CopyOnWriteArrayList<>(); public void registerPokeHandler(PokeHandler handler) { pokeHandler.add(handler); @@ -1815,7 +1815,7 @@ private int onPoke(int transactionType, int dataFormat, HCONV hconv, HSZ topic, return Ddeml.DDE_FNOTPROCESSED; } - private final List connectConfirmHandler = new CopyOnWriteArrayList(); + private final List connectConfirmHandler = new CopyOnWriteArrayList<>(); public void registerConnectConfirmHandler(ConnectConfirmHandler handler) { connectConfirmHandler.add(handler); @@ -1831,7 +1831,7 @@ private void onConnectConfirm(int transactionType, HCONV hconv, HSZ topic, HSZ s } } - private final List disconnectHandler = new CopyOnWriteArrayList(); + private final List disconnectHandler = new CopyOnWriteArrayList<>(); public void registerDisconnectHandler(DisconnectHandler handler) { disconnectHandler.add(handler); @@ -1847,7 +1847,7 @@ private void onDisconnect(int transactionType, Ddeml.HCONV hconv, boolean sameIn } } - private final List errorHandler = new CopyOnWriteArrayList(); + private final List errorHandler = new CopyOnWriteArrayList<>(); public void registerErrorHandler(ErrorHandler handler) { errorHandler.add(handler); @@ -1863,7 +1863,7 @@ private void onError(int transactionType, Ddeml.HCONV hconv, int errorCode) { } } - private final List registerHandler = new CopyOnWriteArrayList(); + private final List registerHandler = new CopyOnWriteArrayList<>(); public void registerRegisterHandler(RegisterHandler handler) { registerHandler.add(handler); @@ -1879,7 +1879,7 @@ private void onRegister(int transactionType, Ddeml.HSZ baseServiceName, Ddeml.HS } } - private final List xactCompleteHandler = new CopyOnWriteArrayList(); + private final List xactCompleteHandler = new CopyOnWriteArrayList<>(); public void registerXactCompleteHandler(XactCompleteHandler handler) { xactCompleteHandler.add(handler); @@ -1895,7 +1895,7 @@ private void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HS } } - private final List unregisterHandler = new CopyOnWriteArrayList(); + private final List unregisterHandler = new CopyOnWriteArrayList<>(); public void registerUnregisterHandler(UnregisterHandler handler) { unregisterHandler.add(handler); @@ -1911,7 +1911,7 @@ private void onUnregister(int transactionType, HSZ baseServiceName, HSZ instance } } - private final List monitorHandler = new CopyOnWriteArrayList(); + private final List monitorHandler = new CopyOnWriteArrayList<>(); public void registerMonitorHandler(MonitorHandler handler) { monitorHandler.add(handler); @@ -1936,15 +1936,13 @@ public static class DdemlException extends RuntimeException { private static final Map ERROR_CODE_MAP; static { - Map errorCodeMapBuilder = new HashMap(); + Map errorCodeMapBuilder = new HashMap<>(); for (Field f : Ddeml.class.getFields()) { String name = f.getName(); if (name.startsWith("DMLERR_") && (!name.equals("DMLERR_FIRST")) && (!name.equals("DMLERR_LAST"))) { try { errorCodeMapBuilder.put(f.getInt(null), name); - } catch (IllegalArgumentException ex) { - throw new RuntimeException(ex); - } catch (IllegalAccessException ex) { + } catch (IllegalArgumentException | IllegalAccessException ex) { throw new RuntimeException(ex); } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java b/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java index 229d0e9606..c5593e6acc 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java @@ -54,10 +54,10 @@ public interface Dxva2 extends StdCallLibrary, PhysicalMonitorEnumerationAPI, Hi { put(Library.OPTION_TYPE_MAPPER, new DefaultTypeMapper() { { - addTypeConverter(MC_POSITION_TYPE.class, new EnumConverter(MC_POSITION_TYPE.class)); - addTypeConverter(MC_SIZE_TYPE.class, new EnumConverter(MC_SIZE_TYPE.class)); - addTypeConverter(MC_GAIN_TYPE.class, new EnumConverter(MC_GAIN_TYPE.class)); - addTypeConverter(MC_DRIVE_TYPE.class, new EnumConverter(MC_DRIVE_TYPE.class)); + addTypeConverter(MC_POSITION_TYPE.class, new EnumConverter<>(MC_POSITION_TYPE.class)); + addTypeConverter(MC_SIZE_TYPE.class, new EnumConverter<>(MC_SIZE_TYPE.class)); + addTypeConverter(MC_GAIN_TYPE.class, new EnumConverter<>(MC_GAIN_TYPE.class)); + addTypeConverter(MC_DRIVE_TYPE.class, new EnumConverter<>(MC_DRIVE_TYPE.class)); } }); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java b/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java index a69095d706..3998927e01 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java @@ -322,7 +322,7 @@ HBITMAP CreateDIBSection(HDC hDC, BITMAPINFO pbmi, int iUsage, */ int GetDeviceCaps(HDC hdc, int nIndex); - /** The GetDIBits function retrieves the bits fo the specified compatible + /** The GetDIBits function retrieves the bits of the specified compatible * bitmap and copies them into a buffer as a DIB using the specified * format. * @param hdc A handle to the device context. 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 14a1bd772b..b1ee1acb51 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -68,6 +68,92 @@ public interface Kernel32 extends StdCallLibrary, WinNT, Wincon { */ int LOAD_LIBRARY_AS_DATAFILE = 0x2; + /** + * Process priority classes + */ + DWORD NORMAL_PRIORITY_CLASS = new DWORD(0x00000020L); + DWORD IDLE_PRIORITY_CLASS = new DWORD(0x00000040L); + DWORD HIGH_PRIORITY_CLASS = new DWORD(0x00000080L); + DWORD REALTIME_PRIORITY_CLASS = new DWORD(0x00000100L); + DWORD BELOW_NORMAL_PRIORITY_CLASS = new DWORD(0x00004000L); + DWORD ABOVE_NORMAL_PRIORITY_CLASS = new DWORD(0x00008000L); + + /** + * Process mode flags + */ + DWORD PROCESS_MODE_BACKGROUND_BEGIN = new DWORD(0x00100000L); + DWORD PROCESS_MODE_BACKGROUND_END = new DWORD(0x00200000L); + + /** + * Thread priorities + */ + int THREAD_PRIORITY_IDLE = -15; + int THREAD_PRIORITY_LOWEST = -2; + int THREAD_PRIORITY_BELOW_NORMAL = -1; + int THREAD_PRIORITY_NORMAL = 0; + int THREAD_PRIORITY_ABOVE_NORMAL = 1; + int THREAD_PRIORITY_HIGHEST = 2; + int THREAD_PRIORITY_TIME_CRITICAL = 15; + + /** + * Thread mode flags + */ + int THREAD_MODE_BACKGROUND_BEGIN = 0x10000; + int THREAD_MODE_BACKGROUND_END = 0x20000; + + /** + * Thread priority error code + */ + int THREAD_PRIORITY_ERROR_RETURN = 0x7FFFFFFF; + + /** + * Processor Feature flags + */ + int PF_FLOATING_POINT_PRECISION_ERRATA = 0; + int PF_FLOATING_POINT_EMULATED = 1; + int PF_COMPARE_EXCHANGE_DOUBLE = 2; + int PF_MMX_INSTRUCTIONS_AVAILABLE = 3; + int PF_PPC_MOVEMEM_64BIT_OK = 4; + int PF_ALPHA_BYTE_INSTRUCTIONS = 5; + int PF_XMMI_INSTRUCTIONS_AVAILABLE = 6; + int PF_3DNOW_INSTRUCTIONS_AVAILABLE = 7; + int PF_RDTSC_INSTRUCTION_AVAILABLE = 8; + int PF_PAE_ENABLED = 9; + int PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10; + int PF_SSE_DAZ_MODE_AVAILABLE = 11; + int PF_NX_ENABLED = 12; + int PF_SSE3_INSTRUCTIONS_AVAILABLE = 13; + int PF_COMPARE_EXCHANGE128 = 14; + int PF_COMPARE64_EXCHANGE128 = 15; + int PF_CHANNELS_ENABLED = 16; + int PF_XSAVE_ENABLED = 17; + int PF_ARM_VFP_32_REGISTERS_AVAILABLE = 18; + int PF_ARM_NEON_INSTRUCTIONS_AVAILABLE = 19; + int PF_SECOND_LEVEL_ADDRESS_TRANSLATION = 20; + int PF_VIRT_FIRMWARE_ENABLED = 21; + int PF_RDWRFSGSBASE_AVAILABLE = 22; + int PF_FASTFAIL_AVAILABLE = 23; + int PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE = 24; + int PF_ARM_64BIT_LOADSTORE_ATOMIC = 25; + int PF_ARM_EXTERNAL_CACHE_AVAILABLE = 26; + int PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE = 27; + int PF_RDRAND_INSTRUCTION_AVAILABLE = 28; + int PF_ARM_V8_INSTRUCTIONS_AVAILABLE = 29; + int PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE = 30; + int PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE = 31; + int PF_RDTSCP_INSTRUCTION_AVAILABLE = 32; + int PF_RDPID_INSTRUCTION_AVAILABLE = 33; + int PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE = 34; + int PF_SSSE3_INSTRUCTIONS_AVAILABLE = 36; + int PF_SSE4_1_INSTRUCTIONS_AVAILABLE = 37; + int PF_SSE4_2_INSTRUCTIONS_AVAILABLE = 38; + int PF_AVX_INSTRUCTIONS_AVAILABLE = 39; + int PF_AVX2_INSTRUCTIONS_AVAILABLE = 40; + int PF_AVX512F_INSTRUCTIONS_AVAILABLE = 41; + int PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE = 43; + int PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE = 44; + int PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE = 45; + /** * Reads data from the specified file or input/output (I/O) device. Reads * occur at the position specified by the file pointer if supported by the @@ -4152,6 +4238,45 @@ Pointer VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, */ boolean GetExitCodeThread(HANDLE hThread, IntByReference exitCode); + /** + * Gets the priority class of the specified process. + * + * @param hProcess A handle to the process. + * @return If the function succeeds, the return value is the priority class of + * the specified process. + *

If the function fails, the return value is zero.

+ */ + DWORD GetPriorityClass(HANDLE hProcess); + + /** + * Sets the priority class for the specified process. + * + * @param hProcess A handle to the process. + * @param dwPriorityClass The priority class for the process. + * @return If the function succeeds, the return value is nonzero. + */ + boolean SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass); + + /** + * Gets the priority value of the specified thread. + * + * @param hProcess A handle to the process. + * @return If the function succeeds, the return value is the priority class of + * the specified thread. + *

If the function fails, the return value is + * THREAD_PRIORITY_ERROR_RETURN.

+ */ + int GetThreadPriority(HANDLE hProcess); + + /** + * Sets the priority value for the specified thread. + * + * @param hThread A handle to the thread whose priority value is to be set. + * @param nPriority The priority value for the thread. + * @return If the function succeeds, the return value is nonzero. + */ + boolean SetThreadPriority(HANDLE hThread, int nPriority); + /** * Releases, decommits, or releases and decommits a region of memory within * the virtual address space of a specified process. @@ -4387,4 +4512,14 @@ Pointer VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, *

*/ boolean VirtualUnlock(Pointer lpAddress, SIZE_T dwSize); + + /** + * Determines whether the specified processor feature is supported by the current computer. + * + * @param ProcessorFeature The processor feature to be tested. + * @return If the feature is supported, the return value is true. If the feature is not supported, the return value + * is false. If the HAL does not support detection of the feature, whether or not the hardware supports the + * feature, the return value is also false. + */ + boolean IsProcessorFeaturePresent(int ProcessorFeature); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java index db9373a361..1d9bea6723 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java @@ -392,23 +392,10 @@ public static int getFileType(String fileName) throws FileNotFoundException { default: return type; } - } catch(Win32Exception e) { - err = e; - throw err; // re-throw so finally block executed + } catch(final Win32Exception e) { + throw err = e; // re-throw to avoid return value! } finally { - try { - closeHandle(hFile); - } catch(Win32Exception e) { - if (err == null) { - err = e; - } else { - err.addSuppressedReflected(e); - } - } - - if (err != null) { - throw err; - } + cleanUp(hFile, err); } } @@ -484,7 +471,7 @@ public static Map getEnvironmentVariables(Pointer lpszEnvironment return null; } - Map vars=new TreeMap(); + Map vars=new TreeMap<>(); boolean asWideChars=isWideCharEnvironmentStringBlock(lpszEnvironmentBlock, offset); long stepFactor=asWideChars ? 2L : 1L; for (long curOffset=offset; ; ) { @@ -768,7 +755,7 @@ public static final SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX[] getLogicalProcesso } } // Array elements have variable size; iterate to populate array - List procInfoList = new ArrayList(); + List procInfoList = new ArrayList<>(); int offset = 0; while (offset < bufferSize.getValue().intValue()) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX information = SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX @@ -944,22 +931,10 @@ public static final String QueryFullProcessImageName(int pid, int dwFlags) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } return QueryFullProcessImageName(hProcess, dwFlags); - } catch (Win32Exception e) { - we = e; - throw we; // re-throw to invoke finally block + } catch (final Win32Exception e) { + throw we = e; // re-throw to avoid return value! } finally { - try { - closeHandle(hProcess); - } catch (Win32Exception e) { - if (we == null) { - we = e; - } else { - we.addSuppressed(e); - } - } - if (we != null) { - throw we; - } + cleanUp(hProcess, we); } } @@ -1093,8 +1068,8 @@ public static Map> getResourceNames(String path) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - final List types = new ArrayList(); - final Map> result = new LinkedHashMap>(); + final List types = new ArrayList<>(); + final Map> result = new LinkedHashMap<>(); WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { @@ -1205,7 +1180,7 @@ public static List getModules(int processID) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - List modules = new ArrayList(); + List modules = new ArrayList<>(); modules.add(first); Tlhelp32.MODULEENTRY32W next = new Tlhelp32.MODULEENTRY32W(); @@ -1223,23 +1198,10 @@ public static List getModules(int processID) { } return modules; - } catch (Win32Exception e) { - we = e; - throw we; // re-throw so finally block is executed + } catch (final Win32Exception e) { + throw we = e; // re-throw to avoid return value! } finally { - try { - closeHandle(snapshot); - } catch(Win32Exception e) { - if (we == null) { - we = e; - } else { - we.addSuppressedReflected(e); - } - } - - if (we != null) { - throw we; - } + cleanUp(snapshot, we); } } @@ -1295,4 +1257,253 @@ public static String expandEnvironmentStrings(String input) { return resultMemory.getString(0); } } + + /** + * Gets the priority class of the current process. + * + * @return The priority class of the current process. + * @throws Win32Exception if an error occurs. + */ + public static DWORD getCurrentProcessPriority() { + final DWORD dwPriorityClass = Kernel32.INSTANCE.GetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess()); + if (!isValidPriorityClass(dwPriorityClass)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return dwPriorityClass; + } + + /** + * Sets the priority class for the current process. + * + * @param dwPriorityClass The priority class for the process. + * @throws Win32Exception if an error occurs. + */ + public static void setCurrentProcessPriority(final DWORD dwPriorityClass) { + if (!isValidPriorityClass(dwPriorityClass)) { + throw new IllegalArgumentException("The given priority value is invalid!"); + } + if (!Kernel32.INSTANCE.SetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess(), dwPriorityClass)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Enables or disables "background" processing mode for the current process + * + * @param enable If true, enables "background" processing mode, otherwise disables it. + * @throws Win32Exception if an error occurs. + */ + public static void setCurrentProcessBackgroundMode(final boolean enable) { + // Note: PROCESS_MODE_BACKGROUN_{BEGIN,END} only works with the "current" process handle! + final DWORD dwPriorityClass = enable ? Kernel32.PROCESS_MODE_BACKGROUND_BEGIN : Kernel32.PROCESS_MODE_BACKGROUND_END; + if (!Kernel32.INSTANCE.SetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess(), dwPriorityClass)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Gets the priority value of the current thread. + * + * @return The priority value of the current thread. + * @throws Win32Exception if an error occurs. + */ + public static int getCurrentThreadPriority() { + final int nPriority = Kernel32.INSTANCE.GetThreadPriority(Kernel32.INSTANCE.GetCurrentThread()); + if (!isValidThreadPriority(nPriority)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return nPriority; + } + + /** + * Sets the priority value for the current thread. + * + * @param nPriority The priority value for the thread. + * @throws Win32Exception if an error occurs. + */ + public static void setCurrentThreadPriority(final int nPriority) { + if (!isValidThreadPriority(nPriority)) { + throw new IllegalArgumentException("The given priority value is invalid!"); + } + if (!Kernel32.INSTANCE.SetThreadPriority(Kernel32.INSTANCE.GetCurrentThread(), nPriority)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Enables or disables "background" processing mode for the current thread + * + * @param enable If true, enables "background" processing mode, otherwise disables it. + * @throws Win32Exception if an error occurs. + */ + public static void setCurrentThreadBackgroundMode(final boolean enable) { + // Note: THREAD_MODE_BACKGROUND_{BEGIN,END} only works with the "current" thread handle! + final int nPriority = enable ? Kernel32.THREAD_MODE_BACKGROUND_BEGIN : Kernel32.THREAD_MODE_BACKGROUND_END; + if (!Kernel32.INSTANCE.SetThreadPriority(Kernel32.INSTANCE.GetCurrentThread(), nPriority)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Gets the priority class of the specified process. + * + * @param pid Identifier for the running process. + * @throws Win32Exception if an error occurs. + */ + public static DWORD getProcessPriority(final int pid) { + final HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION , false, pid); + if (hProcess == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + final DWORD dwPriorityClass = Kernel32.INSTANCE.GetPriorityClass(hProcess); + if (!isValidPriorityClass(dwPriorityClass)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return dwPriorityClass; + } catch (final Win32Exception e) { + throw we = e; // re-throw to avoid return value! + } finally { + cleanUp(hProcess, we); + } + } + + /** + * Sets the priority class for the specified process. + * + * @param pid Identifier for the running process. + * @param dwPriorityClass The priority class for the process. + * @throws Win32Exception if an error occurs. + */ + public static void setProcessPriority(final int pid, final DWORD dwPriorityClass) { + if (!isValidPriorityClass(dwPriorityClass)) { + throw new IllegalArgumentException("The given priority value is invalid!"); + } + + final HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_SET_INFORMATION, false, pid); + if (hProcess == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + if (!Kernel32.INSTANCE.SetPriorityClass(hProcess, dwPriorityClass)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } catch (final Win32Exception e) { + we = e; + } finally { + cleanUp(hProcess, we); + } + } + + /** + * Gets the priority value of the specified thread. + * + * @param tid Identifier for the running thread. + * @throws Win32Exception if an error occurs. + */ + public static int getThreadPriority(final int tid) { + final HANDLE hThread = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_QUERY_INFORMATION, false, tid); + if (hThread == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + final int nPriority = Kernel32.INSTANCE.GetThreadPriority(hThread); + if (!isValidThreadPriority(nPriority)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return nPriority; + } catch (final Win32Exception e) { + throw we = e; // re-throw to avoid return value! + } finally { + cleanUp(hThread, we); + } + } + + /** + * Sets the priority value for the specified thread. + * + * @param tid Identifier for the running thread. + * @param nPriority The priority value for the thread. + * @throws Win32Exception if an error occurs. + */ + public static void setThreadPriority(final int tid, final int nPriority) { + if (!isValidThreadPriority(nPriority)) { + throw new IllegalArgumentException("The given priority value is invalid!"); + } + + final HANDLE hThread = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_SET_INFORMATION, false, tid); + if (hThread == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + if (!Kernel32.INSTANCE.SetThreadPriority(hThread, nPriority)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } catch (final Win32Exception e) { + we = e; + } finally { + cleanUp(hThread, we); + } + } + + /** + * Test whether the given priority class is valid. + *

Intentionally does not accept "background" processing mode flags!

+ * + * @param dwPriorityClass The priority value to test. + * @return Returns true, if and only if the given priority value was valid + */ + public static boolean isValidPriorityClass(final DWORD dwPriorityClass) { + return Kernel32.NORMAL_PRIORITY_CLASS.equals(dwPriorityClass) || + Kernel32.IDLE_PRIORITY_CLASS.equals(dwPriorityClass) || + Kernel32.HIGH_PRIORITY_CLASS.equals(dwPriorityClass) || + Kernel32.REALTIME_PRIORITY_CLASS.equals(dwPriorityClass) || + Kernel32.BELOW_NORMAL_PRIORITY_CLASS.equals(dwPriorityClass) || + Kernel32.ABOVE_NORMAL_PRIORITY_CLASS.equals(dwPriorityClass); + } + + /** + * Test whether the given thread priority is valid. + *

Intentionally does not accept "background" processing mode flags!

+ * + * @param nPriority The priority value to test. + * @return Returns true, if and only if the given priority value was valid + */ + public static boolean isValidThreadPriority(final int nPriority) { + switch(nPriority) { + case Kernel32.THREAD_PRIORITY_IDLE: + case Kernel32.THREAD_PRIORITY_LOWEST: + case Kernel32.THREAD_PRIORITY_BELOW_NORMAL: + case Kernel32.THREAD_PRIORITY_NORMAL: + case Kernel32.THREAD_PRIORITY_ABOVE_NORMAL: + case Kernel32.THREAD_PRIORITY_HIGHEST: + case Kernel32.THREAD_PRIORITY_TIME_CRITICAL: + return true; + default: + return false; + } + } + + private static void cleanUp(final HANDLE h, Win32Exception we) { + try { + closeHandle(h); + } catch (final Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressedReflected(e); + } + } + if (we != null) { + throw we; + } + } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java index db8222e769..8a6488ba4d 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java @@ -212,7 +212,7 @@ public static LocalGroup[] getLocalGroups(String serverName) { throw new Win32Exception(rc); } - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); if (entriesRead.getValue() > 0) { LMAccess.LOCALGROUP_INFO_1 group = new LMAccess.LOCALGROUP_INFO_1(bufptr.getValue()); @@ -261,7 +261,7 @@ public static Group[] getGlobalGroups(String serverName) { throw new Win32Exception(rc); } - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); if (entriesRead.getValue() > 0) { LMAccess.GROUP_INFO_1 group = new LMAccess.GROUP_INFO_1(bufptr.getValue()); @@ -311,7 +311,7 @@ public static User[] getUsers(String serverName) { throw new Win32Exception(rc); } - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); if (entriesRead.getValue() > 0) { LMAccess.USER_INFO_1 user = new LMAccess.USER_INFO_1(bufptr.getValue()); @@ -370,7 +370,7 @@ public static Group[] getUserLocalGroups(String userName, String serverName) { if (rc != LMErr.NERR_Success) { throw new Win32Exception(rc); } - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); if (entriesread.getValue() > 0) { LOCALGROUP_USERS_INFO_0 lgroup = new LOCALGROUP_USERS_INFO_0(bufptr.getValue()); LOCALGROUP_USERS_INFO_0[] lgroups = (LOCALGROUP_USERS_INFO_0[]) lgroup.toArray(entriesread.getValue()); @@ -420,7 +420,7 @@ public static Group[] getUserGroups(String userName, String serverName) { throw new Win32Exception(rc); } - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); if (entriesread.getValue() > 0) { GROUP_USERS_INFO_0 lgroup = new GROUP_USERS_INFO_0(bufptr.getValue()); @@ -637,7 +637,7 @@ public static DomainTrust[] getDomainTrusts(String serverName) { throw new Win32Exception(rc); } try { - ArrayList trusts = new ArrayList(domainTrustCount.getValue()); + ArrayList trusts = new ArrayList<>(domainTrustCount.getValue()); if(domainTrustCount.getValue() > 0) { DS_DOMAIN_TRUSTS domainTrustRefs = new DS_DOMAIN_TRUSTS(domainsPointerRef.getValue()); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java b/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java index c6c6929b34..2cfd896162 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java @@ -89,6 +89,7 @@ public interface OaIdl { // The DATE Type is defined in localtime and the java Date type always contains // a a timezone offset, so the difference has to be calculated and can't be // predetermined + @SuppressWarnings("deprecation") public static final long DATE_OFFSET = new Date(1899 - 1900, 12 - 1, 30, 0, 0, 0).getTime(); /** @@ -886,6 +887,7 @@ public void destroy() { /** * Implemented to satisfy Closeable interface, delegates to destroy. */ + @Override public void close() { destroy(); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java index ebfa8e7f60..51a479e7ef 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java @@ -159,8 +159,8 @@ public static int PdhLookupPerfIndexByEnglishName(String szNameBuffer) { */ public static PdhEnumObjectItems PdhEnumObjectItems(String szDataSource, String szMachineName, String szObjectName, int dwDetailLevel) { - List counters = new ArrayList(); - List instances = new ArrayList(); + List counters = new ArrayList<>(); + List instances = new ArrayList<>(); // Call once to get counter and instance string lengths // If zero on input and the object exists, the function returns PDH_MORE_DATA @@ -285,9 +285,9 @@ public List getInstances() { private List copyAndEmptyListForNullList (List inputList) { if(inputList == null) { - return new ArrayList(); + return new ArrayList<>(); } else { - return new ArrayList(inputList); + return new ArrayList<>(inputList); } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java index bd90b8669f..cbced1a8a3 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java @@ -97,7 +97,7 @@ public static SecurityPackage[] getSecurityPackages() { throw new Win32Exception(rc); } SecPkgInfo[] packagesInfo = pPackageInfo.toArray(pcPackages.getValue()); - ArrayList packages = new ArrayList(pcPackages.getValue()); + ArrayList packages = new ArrayList<>(pcPackages.getValue()); for (SecPkgInfo packageInfo : packagesInfo) { SecurityPackage securityPackage = new SecurityPackage(); securityPackage.name = packageInfo.Name.toString(); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java index b21d02fdee..19d834caf7 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java @@ -213,7 +213,7 @@ public Future runAsync(Callable command) { Logger.getLogger(MessageLoopThread.class.getName()).log(Level.SEVERE, null, ex); } } - FutureTask futureTask = new FutureTask(command); + FutureTask futureTask = new FutureTask<>(command); workQueue.add(futureTask); User32.INSTANCE.PostThreadMessage(nativeThreadId, WinUser.WM_USER, null, null); return futureTask; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java b/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java index 0a57eb051a..dc98fa78c2 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java @@ -62,8 +62,8 @@ public FileInfo(File f, HANDLE h, int mask, boolean recurse) { } private Thread watcher; private HANDLE port; - private final Map fileMap = new HashMap(); - private final Map handleMap = new HashMap(); + private final Map fileMap = new HashMap<>(); + private final Map handleMap = new HashMap<>(); private boolean disposing = false; private void handleChanges(FileInfo finfo) throws IOException { diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java b/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java index a3f75edecd..00e36b7302 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java @@ -92,11 +92,7 @@ void addSuppressedReflected(Throwable exception) { } try { addSuppressedMethod.invoke(this, exception); - } catch (IllegalAccessException ex) { - throw new RuntimeException("Failed to call addSuppressedMethod", ex); - } catch (IllegalArgumentException ex) { - throw new RuntimeException("Failed to call addSuppressedMethod", ex); - } catch (InvocationTargetException ex) { + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new RuntimeException("Failed to call addSuppressedMethod", ex); } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index 639dfcf2b1..22e5a7236b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -3208,7 +3208,7 @@ public void read() { */ @Override protected List getFieldList() { - List fields = new ArrayList(super.getFieldList()); + List fields = new ArrayList<>(super.getFieldList()); Iterator fieldIterator = fields.iterator(); while (fieldIterator.hasNext()) { Field field = fieldIterator.next(); @@ -3447,26 +3447,23 @@ public interface LOGICAL_PROCESSOR_RELATIONSHIP { /** *

- * Upcoming value of this enum added for forward compatibility. Documentation - * will be added when available. + * The specified logical processors share a single processor die. *

*/ int RelationProcessorDie = 5; /** *

- * Introduced in TBD - Release Iron. Requests that the full affinity be - * returned. Unlike the other relation types, RelationNumaNodeEx is not used on - * input. It is simply a request for RelationNumaNode with full group - * information. + * Introduced in Windows Server 2022 (21H2, build 20348). Requests that the full affinity be returned. Unlike + * the other relation types, RelationNumaNodeEx is not used on input. It is simply a request for + * RelationNumaNode with full group information. *

*/ int RelationNumaNodeEx = 6; /** *

- * Upcoming value of this enum added for forward compatibility. Documentation - * will be added when available. + * The specified logical processors share a single processor module. *

*/ int RelationProcessorModule = 7; @@ -4423,4 +4420,6 @@ public IO_COUNTERS(Pointer memory) { class TOKEN_ELEVATION extends Structure { public int TokenIsElevated; } + + Guid.GUID GUID_CONSOLE_DISPLAY_STATE = new Guid.GUID("6FE69556-704A-47A0-8F24-C28D936FDA47"); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java b/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java index 9728a36f9f..d24523d37b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java @@ -30,7 +30,6 @@ import com.sun.jna.Structure.FieldOrder; import com.sun.jna.Union; import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; -import com.sun.jna.platform.win32.WinDef.HKL; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.win32.StdCallLibrary.StdCallCallback; import com.sun.jna.win32.W32APITypeMapper; @@ -2088,4 +2087,79 @@ public String toString() { * Bitmask for the RESERVED2 key modifier. */ int MODIFIER_RESERVED2_MASK = 32; + + class HPOWERNOTIFY extends PVOID { + public HPOWERNOTIFY() { + } + + public HPOWERNOTIFY(Pointer pointer) { + super(pointer); + } + } + + /** + * Registers the application to receive power setting notifications for the specific power setting event. + * @param hRecipient Handle indicating where the power setting notifications are to be sent. + * For interactive applications, the Flags parameter should be DEVICE_NOTIFY_WINDOW_HANDLE, + * and the hRecipient parameter should be a window handle. + * For services, the Flags parameter should be DEVICE_NOTIFY_SERVICE_HANDLE, and the hRecipient + * parameter should be a SERVICE_STATUS_HANDLE as returned from RegisterServiceCtrlHandlerEx. + * @param PowerSettingGuid The GUID of the power setting for which notifications are to be sent. + * @param Flags + *
  • DEVICE_NOTIFY_WINDOW_HANDLE - Notifications are sent using WM_POWERBROADCAST messages + * with a wParam parameter of PBT_POWERSETTINGCHANGE. + *
  • DEVICE_NOTIFY_SERVICE_HANDLE - Notifications are sent to the HandlerEx callback function with a dwControl + * parameter of SERVICE_CONTROL_POWEREVENT and a dwEventType of PBT_POWERSETTINGCHANGE. + * @return a notification handle for unregistering for power notifications. If the function fails, the return + * value is NULL. To get extended error information, call GetLastError. + */ + HPOWERNOTIFY RegisterPowerSettingNotification( + /*[in]*/ HANDLE hRecipient, + /*[in]*/ Guid.GUID PowerSettingGuid, + /*[in]*/ int Flags); + + /** + * Unregisters the power setting notification. + * @param Handle The handle returned from the RegisterPowerSettingNotification function. + * @return If the function succeeds, the return value is nonzero. + * If the function fails, the return value is zero. To get extended error information, call GetLastError. + */ + BOOL UnregisterPowerSettingNotification( + /*[in]*/ HPOWERNOTIFY Handle + ); + + int WM_POWERBROADCAST = 0x0218; + + int PBT_APMQUERYSUSPEND = 0x0000; + int PBT_APMQUERYSTANDBY = 0x0001; + int PBT_APMQUERYSUSPENDFAILED = 0x0002; + int PBT_APMQUERYSTANDBYFAILED = 0x0003; + int PBT_APMSUSPEND = 0x0004; + int PBT_APMSTANDBY = 0x0005; + int PBT_APMRESUMECRITICAL = 0x0006; + int PBT_APMRESUMESUSPEND = 0x0007; + int PBT_APMRESUMESTANDBY = 0x0008; + int PBT_APMBATTERYLOW = 0x0009; + int PBT_APMPOWERSTATUSCHANGE = 0x000A; + int PBT_APMOEMEVENT = 0x000B; + int PBT_APMRESUMEAUTOMATIC = 0x0012; + int PBT_POWERSETTINGCHANGE = 0x8013; + + @FieldOrder({"PowerSetting", "DataLength", "Data"}) + class POWERBROADCAST_SETTING extends Structure { + public Guid.GUID PowerSetting; + public int DataLength; + public byte Data[] = new byte[1]; + + public POWERBROADCAST_SETTING(Pointer p) { + super(p); + read(); + } + + @Override + public final void read() { + Data = new byte[getPointer().getInt(fieldOffset("DataLength"))]; + super.read(); + } + } } \ No newline at end of file diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java index 449a53ea70..dc8145d152 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java @@ -47,14 +47,14 @@ public class WininetUtil { * cookie and history entries) */ public static Map getCache() { - List items = new ArrayList(); + List items = new ArrayList<>(); HANDLE cacheHandle = null; Win32Exception we = null; int lastError = 0; // return - Map cacheItems = new LinkedHashMap(); + Map cacheItems = new LinkedHashMap<>(); try { IntByReference size = new IntByReference(); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index 7dcdac4cb4..415fa3df7b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -153,6 +153,11 @@ public interface Winspool extends StdCallLibrary { public static final int PRINTER_ENUM_ICON8 = 0x00800000; public static final int PRINTER_ENUM_HIDE = 0x01000000; + public static final int PRINTER_CONTROL_PAUSE = 0x01; + public static final int PRINTER_CONTROL_PURGE = 0x02; + public static final int PRINTER_CONTROL_RESUME = 0x03; + public static final int PRINTER_CONTROL_SET_STATUS = 0x04; + public static final int PRINTER_NOTIFY_OPTIONS_REFRESH = 0x01; public static final int PRINTER_NOTIFY_INFO_DISCARDED = 0x01; @@ -160,6 +165,16 @@ public interface Winspool extends StdCallLibrary { public static final int PRINTER_NOTIFY_TYPE = 0x00; public static final int JOB_NOTIFY_TYPE = 0x01; + public static final int JOB_CONTROL_PAUSE = 0x01; + public static final int JOB_CONTROL_RESUME = 0x02; + public static final int JOB_CONTROL_CANCEL = 0x03; + public static final int JOB_CONTROL_RESTART = 0x04; + public static final int JOB_CONTROL_DELETE = 0x05; + public static final int JOB_CONTROL_SENT_TO_PRINTER = 0x06; + public static final int JOB_CONTROL_LAST_PAGE_EJECTED = 0x07; + public static final int JOB_CONTROL_RETAIN = 0x08; + public static final int JOB_CONTROL_RELEASE = 0x09; + public static final short PRINTER_NOTIFY_FIELD_SERVER_NAME = 0x00; public static final short PRINTER_NOTIFY_FIELD_PRINTER_NAME = 0x01; public static final short PRINTER_NOTIFY_FIELD_SHARE_NAME = 0x02; @@ -1275,4 +1290,92 @@ public JOB_INFO_1(int size) { super(new Memory(size)); } } + + /** + * The SetJob function pauses, resumes, cancels, or restarts a print job on a specified printer. You can also use + * the SetJob function to set print job parameters, such as the print job priority and the document name. + * + * You can use the SetJob function to give a command to a print job, or to set print job parameters, or to do both + * in the same call. The value of the Command parameter does not affect how the function uses the Level and pJob + * parameters. Also, you can use SetJob with JOB_INFO_3 to link together a set of print jobs. + * + * @param hPrinter + * [in] A handle to the printer object of interest. Use the OpenPrinter, OpenPrinter2, or AddPrinter + * function to retrieve a printer handle. + * @param JobId + * [in] Identifier that specifies the print job. You obtain a print job identifier by calling the AddJob + * function or the StartDoc function. If the Level parameter is set to 3, the JobId parameter must match + * theJobId member of the JOB_INFO_3 structure pointed to by pJob + * @param Level + * [in] The type of job information structure pointed to by the pJob parameter. + * All versions of Windows: You can set the Level parameter to 0, 1, or 2. When you set Level to 0, pJob + * be NULL. Use these values when you are not setting any print job parameters. You can also set the Level + * parameter to 3. Starting with Windows Vista: You can also set the Level parameter to 4. + * @param pJob + * [in] A pointer to a structure that sets the print job parameters. All versions of Windows: pJob can + * point to a JOB_INFO_1 or JOB_INFO_2 structure. pJob can also point to a JOB_INFO_3 structure. You must + * have JOB_ACCESS_ADMINISTER access permission for the jobs specified by the JobId and NextJobId members + * of the JOB_INFO_3 structure. Starting with Windows Vista: pJob can also point to a JOB_INFO_4 structure. + * If the Level parameter is 0, pJob should be NULL. + * @param Command + * [in] The print job operation to perform. This parameter can be one of the JOB_CONTROL_XXX values. + * To cancel a job, do NOT use JOB_CONTROL_CANCEL, intead use JOB_CONTROL_DELETE to delete a job. + * + * @return If the function succeeds, the return value is a nonzero value. If the function fails, the return value is + * zero. + * + * @see + * SetJob function + */ + boolean SetJob( + // _In_ + WinNT.HANDLE hPrinter, + // _In_ + int JobId, + // _In_ + int Level, + // _In_ + Pointer pJob, + // _In_ + int Command); + + /** + * The SetPrinter function sets the data for a specified printer or sets the state of the specified printer by + * pausing printing, resuming printing, or clearing all print jobs. + * + * @param hPrinter + * [in] A handle to the printer. Use the OpenPrinter, OpenPrinter2, or AddPrinter function to retrieve a + * printer handle. + * @param Level + * [in] The type of data that the function stores into the buffer pointed to by pPrinter. If the Command + * parameter is not equal to zero, the Level parameter must be zero. This value can be 0, 2, 3, 4, 5, 6, + * 7, 8, or 9. + * @param pPrinter + * A pointer to a buffer containing data to set for the printer, or containing information for the command + * specified by the Command parameter. The type of data in the buffer is determined by the value of Level. + * @param Command + * The action to perform. If the Level parameter is nonzero, set the value of this parameter to zero. In + * this case, the printer retains its current state and the function reconfigures the printer data as + * specified by the Level and pPrinter parameters. If the Level parameter is zero, set the value of this + * parameter to one of the PRINTER_CONTROL_XXX values. + * + * @return If the function succeeds, the return value is a nonzero value. + * If the function fails, the return value is zero. If Level is 7 and the publish action failed, SetPrinter + * returns ERROR_IO_PENDING and attempts to complete the action in the background. If Level is 7 and the + * update action failed, SetPrinter returns ERROR_FILE_NOT_FOUND. + * + * @see + * SetPrinter function + */ + boolean SetPrinter( + // _In_ + WinNT.HANDLE hPrinter, + // _In_ + int Level, + // _In_ + Pointer pPrinter, + // _In_ + int Command); } diff --git a/contrib/platform/test/com/sun/jna/platform/RasterRangesUtilsTest.java b/contrib/platform/test/com/sun/jna/platform/RasterRangesUtilsTest.java index fe68bb335e..ba8aee36ec 100644 --- a/contrib/platform/test/com/sun/jna/platform/RasterRangesUtilsTest.java +++ b/contrib/platform/test/com/sun/jna/platform/RasterRangesUtilsTest.java @@ -31,15 +31,16 @@ import java.util.HashSet; import java.util.Set; -import junit.framework.TestCase; - import com.sun.jna.platform.RasterRangesUtils.RangesOutput; +import junit.framework.TestCase; + public class RasterRangesUtilsTest extends TestCase { - Set rects = new HashSet(); + Set rects = new HashSet<>(); RangesOutput out = new RangesOutput() { + @Override public boolean outputRange(int x, int y, int w, int h) { rects.add(new Rectangle(x, y, w, h)); return true; diff --git a/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java b/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java index a8062d78e7..3f3761e65d 100644 --- a/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java +++ b/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java @@ -429,7 +429,7 @@ public void run() { WeakReference ref = null; for (int i = 0; i < owned.length; i++) { if (owned[i].getClass().getName().indexOf("Heavy") != -1) { - ref = new WeakReference(owned[i]); + ref = new WeakReference<>(owned[i]); break; } } diff --git a/contrib/platform/test/com/sun/jna/platform/linux/UdevTest.java b/contrib/platform/test/com/sun/jna/platform/linux/UdevTest.java index 90dc035fb9..5724a176a3 100644 --- a/contrib/platform/test/com/sun/jna/platform/linux/UdevTest.java +++ b/contrib/platform/test/com/sun/jna/platform/linux/UdevTest.java @@ -29,6 +29,8 @@ import com.sun.jna.platform.linux.Udev.UdevDevice; import com.sun.jna.platform.linux.Udev.UdevEnumerate; import com.sun.jna.platform.linux.Udev.UdevListEntry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import junit.framework.TestCase; @@ -37,6 +39,8 @@ */ public class UdevTest extends TestCase { + private static final Pattern SCSI_DISK_PATTERN = Pattern.compile(".*/sd[a-z](\\d+)$"); + @Test public void testEnumerateDevices() { // Start with the context object @@ -74,7 +78,10 @@ public void testEnumerateDevices() { // No additional reference is acquired from getParent if (parent != null && parent2 != null) { // Devnode should match same parent without restricting to block and disk - assertEquals("Partition parent should match with and without filter", + assertEquals(String.format( + "Partition parent should match with and without filter (%s)", + devnode + ), parent.getDevnode(), parent2.getDevnode()); // Save the size and major parentSize = parent.getSysattrValue("size"); @@ -82,21 +89,29 @@ public void testEnumerateDevices() { } } String size = device.getSysattrValue("size"); - assertTrue("Size must be nonnegative", 0 <= Long.parseLong(size)); + assertTrue(String.format("Size must be nonnegative (%s)", devnode), 0 <= Long.parseLong(size)); if (parentSize != null) { - assertTrue("Partition can't be bigger than its disk", + assertTrue(String.format("Partition can't be bigger than its disk (%s)", devnode), Long.parseLong(size) <= Long.parseLong(parentSize)); } String major = device.getPropertyValue("MAJOR"); - assertTrue("Major value must be nonnegative", 0 <= Long.parseLong(major)); + assertTrue(String.format("Major value must be nonnegative (%s)", devnode), 0 <= Long.parseLong(major)); if (parentMajor != null) { - assertEquals("Partition and its parent disk should have same major number", major, - parentMajor); + // For scsi disks only the first 15 Partitions have the + // same major as their disk + Matcher scsiMatcher = SCSI_DISK_PATTERN.matcher(devnode); + boolean scsiDiskDynamicMinor = scsiMatcher.matches() && Integer.parseInt(scsiMatcher.group(1)) > 15; + if(! scsiDiskDynamicMinor) { + assertEquals( + String.format("Partition and its parent disk should have same major number (%s)", devnode), + major, parentMajor + ); + } } - assertEquals("DevType mismatch", devType, device.getDevtype()); - assertEquals("Subsystem mismatch", "block", device.getSubsystem()); - assertEquals("Syspath mismatch", syspath, device.getSyspath()); - assertTrue("Syspath should end with name", syspath.endsWith(device.getSysname())); + assertEquals(String.format("DevType mismatch (%s)", devnode), devType, device.getDevtype()); + assertEquals(String.format("Subsystem mismatch (%s)", devnode), "block", device.getSubsystem()); + assertEquals(String.format("Syspath mismatch (%s)", devnode), syspath, device.getSyspath()); + assertTrue(String.format("Syspath should end with name (%s)", devnode), syspath.endsWith(device.getSysname())); } } finally { // Release the reference and iterate to the next device diff --git a/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java b/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java index 60c106ed79..8bdbfec7bd 100644 --- a/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java +++ b/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java @@ -75,7 +75,7 @@ public void testDiskCreate() { assertNotNull(session); // Get IOMedia objects representing whole drives and save the BSD Name - List bsdNames = new ArrayList(); + List bsdNames = new ArrayList<>(); PointerByReference iterPtr = new PointerByReference(); CFMutableDictionaryRef dict = IOKit.INSTANCE.IOServiceMatching("IOMedia"); diff --git a/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java b/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java index 6ab22aa844..e2c2ead788 100644 --- a/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java +++ b/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java @@ -103,7 +103,8 @@ public void testMatching() { String serialNumberViaUtil = platformExpert.getStringProperty("IOPlatformSerialNumber"); assertEquals(serialNumber, serialNumberViaUtil); - assertEquals(12, serialNumber.length()); + assertTrue("Known serial number lengths are 10 and 12, was: " + serialNumber.length(), + serialNumber.length() == 12 || serialNumber.length() == 10); // Get all the keys dict = platformExpert.createCFProperties(); assertNotEquals(0, dict.getValueIfPresent(serialKey, null)); @@ -144,7 +145,7 @@ public void testMatching() { public void testIteratorParentChild() { int masterPort = IOKitUtil.getMasterPort(); - Set uniqueEntryIdSet = new HashSet(); + Set uniqueEntryIdSet = new HashSet<>(); // Iterate over USB Controllers. All devices are children of one of // these controllers in the "IOService" plane // On M1 the IOUSBController service doesn't exist so we navigate from root of @@ -214,7 +215,7 @@ public void testIOConnect() { int masterPort = IOKitUtil.getMasterPort(); IOService smcService = IOKitUtil.getMatchingService("AppleSMC"); - assertNotNull(smcService); + assumeTrue(smcService != null); // Service is not available on github M1 runners PointerByReference connPtr = new PointerByReference(); int taskSelf = SYS.mach_task_self(); diff --git a/contrib/platform/test/com/sun/jna/platform/unix/aix/PerfstatTest.java b/contrib/platform/test/com/sun/jna/platform/unix/aix/PerfstatTest.java index 6c5ee9c70f..75fef4a8b2 100644 --- a/contrib/platform/test/com/sun/jna/platform/unix/aix/PerfstatTest.java +++ b/contrib/platform/test/com/sun/jna/platform/unix/aix/PerfstatTest.java @@ -147,7 +147,7 @@ public void testPerfstatProcesses() { assertTrue("Error fetching processes", 0 < ret); // due to race condition ret may return fewer processes than asked for assertTrue("Fetched too many processes", ret <= procCount); - Set pidSet = new HashSet(); + Set pidSet = new HashSet<>(); for (int i = 0; i < ret; i++) { assertTrue("Must have nonempty process name", 0 < Native.toString(proct[i].proc_name).length()); assertFalse("Pid must be unique", pidSet.contains(proct[i].pid)); @@ -160,7 +160,7 @@ public void testPerfstatProcesses() { public void testPerfstatProtocols() { if (Platform.isAIX()) { // Valid protocol names are union field names - Set protocolNames = new HashSet(); + Set protocolNames = new HashSet<>(); for (Field f : perfstat_protocol_t.AnonymousUnionPayload.class.getDeclaredFields()) { protocolNames.add(f.getName()); } diff --git a/contrib/platform/test/com/sun/jna/platform/unix/solaris/LibKstatTest.java b/contrib/platform/test/com/sun/jna/platform/unix/solaris/LibKstatTest.java index 2bb644c575..23d0f5fa1d 100644 --- a/contrib/platform/test/com/sun/jna/platform/unix/solaris/LibKstatTest.java +++ b/contrib/platform/test/com/sun/jna/platform/unix/solaris/LibKstatTest.java @@ -254,7 +254,7 @@ private static Kstat kstatLookup(KstatCtl kc, String module, int instance, Strin * empty list otherwise */ private static List kstatLookupAll(KstatCtl kc, String module, int instance, String name) { - List kstats = new ArrayList(); + List kstats = new ArrayList<>(); int ret = LibKstat.INSTANCE.kstat_chain_update(kc); if (ret < 0) { fail(String.format("Failed to update kstat chain")); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java b/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java index 159b52494a..acba0ade38 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java @@ -62,8 +62,8 @@ public static final void assertNoDuplicateMethodsNames(Class ifc) { */ public static final Set detectDuplicateMethods(Class ifc) { Method[] methods = ifc.getMethods(); - Set nameSet = new HashSet(methods.length); - Set dupSet = new HashSet(); + Set nameSet = new HashSet<>(methods.length); + Set dupSet = new HashSet<>(); for (Method m : methods) { String name = m.getName(); if (!nameSet.add(name)) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java old mode 100755 new mode 100644 index bbddb75e68..11844df48e --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java @@ -1950,12 +1950,14 @@ public void testDecryptFile() throws Exception { // decrypt a read only file file.setWritable(false); - assertFalse(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0))); - assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError()); + boolean successful = Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)); + if(! successful) { + assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError()); - // decrypt - file.setWritable(true); - assertTrue(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0))); + // decrypt + file.setWritable(true); + assertTrue(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0))); + } file.delete(); } @@ -2146,7 +2148,7 @@ private File createTempFile() throws Exception { file.createNewFile(); FileWriter fileWriter = new FileWriter(file); for (int i = 0; i < 1000; i++) { - fileWriter.write("Sample text " + i + System.getProperty("line.separator")); + fileWriter.write("Sample text " + i + System.lineSeparator()); } fileWriter.close(); return file; @@ -2170,4 +2172,5 @@ public void testCreateProcessWithLogonW() { // should fail with "the user name or password is incorrect" (error 1326) assertEquals("GetLastError() should have returned ERROR_LOGON_FAILURE because the username was bogus.", W32Errors.ERROR_LOGON_FAILURE, Native.getLastError()); } + } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java index 39c19eacce..1c8a739aeb 100755 --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java @@ -788,7 +788,7 @@ public void testGetEnvironmentBlock() { + "\0"; // Order is important to kept checking result simple - Map mockEnvironment = new TreeMap(); + Map mockEnvironment = new TreeMap<>(); mockEnvironment.put("KEY", "value"); mockEnvironment.put("KEY_EMPTY", ""); mockEnvironment.put("KEY_NUMBER", "2"); @@ -934,7 +934,7 @@ private File createTempFile() throws Exception{ file.createNewFile(); FileWriter fileWriter = new FileWriter(file); for (int i = 0; i < 1000; i++) { - fileWriter.write("Sample text " + i + System.getProperty("line.separator")); + fileWriter.write("Sample text " + i + System.lineSeparator()); } fileWriter.close(); return file; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java index a0d94cf897..d8530b7556 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java @@ -23,13 +23,18 @@ package com.sun.jna.platform.win32.COM; import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid; import com.sun.jna.platform.win32.Ole32; -import java.util.Iterator; -import java.util.NoSuchElementException; - +import com.sun.jna.platform.win32.OleAuto; import com.sun.jna.platform.win32.Variant; import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WTypes; import com.sun.jna.platform.win32.WinDef.LONG; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.ptr.PointerByReference; + +import java.util.Iterator; +import java.util.NoSuchElementException; import org.junit.After; import org.junit.Before; @@ -39,16 +44,41 @@ public class ShellApplicationWindowsTest { + private static final Guid.CLSID CLSID_InternetExplorer = new Guid.CLSID("{0002DF01-0000-0000-C000-000000000046}"); + static { ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } + private PointerByReference ieApp; + private Dispatch ieDispatch; + @Before public void setUp() throws Exception { - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + WinNT.HRESULT hr; - // Launch IE in a manner that should ensure it opens even if the system default browser is Chrome, Firefox, or something else. - Runtime.getRuntime().exec("cmd /c start iexplore.exe -nohome \"about:blank\""); + hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + COMUtils.checkRC(hr); + + // IE can not be launched directly anymore - so load it via COM + + ieApp = new PointerByReference(); + hr = Ole32.INSTANCE + .CoCreateInstance(CLSID_InternetExplorer, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ieApp); + COMUtils.checkRC(hr); + + ieDispatch = new Dispatch(ieApp.getValue()); + InternetExplorer ie = new InternetExplorer(ieDispatch); + + ie.setProperty("Visible", true); + COMUtils.checkRC(hr); + + VARIANT url = new VARIANT("about:blank"); + VARIANT result = ie.invoke("Navigate", url); + OleAuto.INSTANCE.VariantClear(url); + OleAuto.INSTANCE.VariantClear(result); + + ieDispatch.Release(); // Even when going to "about:blank", IE still needs a few seconds to start up and add itself to Shell.Application.Windows // Removing this delay will cause the test to fail even on the fastest boxes I can find. @@ -85,6 +115,7 @@ public void testWindowsCount() @After public void tearDown() throws Exception { + Ole32.INSTANCE.CoUninitialize(); Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe"); } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/WbemcliTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/WbemcliTest.java index fbc9591152..3a65c706dc 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/WbemcliTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/WbemcliTest.java @@ -96,7 +96,7 @@ public void unInitCom() { @Test public void testWmiExceptions() { - WmiQuery processQuery = new WmiQuery("Win32_Process", ProcessProperty.class); + WmiQuery processQuery = new WmiQuery<>("Win32_Process", ProcessProperty.class); try { // This query should take more than 0 ms processQuery.execute(0); @@ -142,7 +142,7 @@ public void testNamespace() { @Test public void testWmiProcesses() { - WmiQuery processQuery = new WmiQuery("Win32_Process", ProcessProperty.class); + WmiQuery processQuery = new WmiQuery<>("Win32_Process", ProcessProperty.class); WmiResult processes = processQuery.execute(); // There has to be at least one process (this one!) @@ -199,7 +199,7 @@ public void testShowProperties() { for(IWbemClassObject iwco: results) { resultCount++; - Set names = new HashSet(Arrays.asList(iwco.GetNames(null, 0, null))); + Set names = new HashSet<>(Arrays.asList(iwco.GetNames(null, 0, null))); assertTrue(names.contains("CommandLine")); assertTrue(names.contains("ProcessId")); assertTrue(names.contains("WorkingSetSize")); @@ -276,7 +276,7 @@ public void testShowProperties() { @Test public void testWmiOperatingSystem() { - WmiQuery operatingSystemQuery = new WmiQuery("Win32_OperatingSystem", + WmiQuery operatingSystemQuery = new WmiQuery<>("Win32_OperatingSystem", OperatingSystemProperty.class); WmiResult os = operatingSystemQuery.execute(); @@ -306,7 +306,7 @@ enum Win32_DiskDrive_Values { @Test public void testUnsupportedValues() { - WmiQuery serialNumberQuery = new WmiQuery("Win32_DiskDrive", Win32_DiskDrive_Values.class); + WmiQuery serialNumberQuery = new WmiQuery<>("Win32_DiskDrive", Win32_DiskDrive_Values.class); WmiResult result = serialNumberQuery.execute(); assertTrue(result.getResultCount() > 0); for (int i = 0; i < result.getResultCount(); i++) { @@ -429,6 +429,44 @@ public void testIWbemContextSetValue() { assertEquals(currentPid, pVal.longValue()); } + @Test + public void testWmiObject() { + Wbemcli.IWbemServices svc = null; + Variant.VARIANT.ByReference pVal = new Variant.VARIANT.ByReference(); + + String className = "StdRegProv"; + String methodName = "GetStringValue"; + + IWbemClassObject regClass = null; + IWbemClassObject method = null; + IWbemClassObject instance = null; + IWbemClassObject result = null; + + try { + svc = WbemcliUtil.connectServer("ROOT\\Default"); + + regClass = svc.GetObject(className, 0, null); + method = regClass.GetMethod(methodName); + instance = method.SpawnInstance(); + + instance.Put("sSubKeyName", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion"); + instance.Put("sValueName", "CommonFilesDir"); + + result = svc.ExecMethod(className, methodName, 0, null, instance); + + result.Get("sValue", 0, pVal, null, null); + assertEquals(Variant.VT_BSTR, pVal.getVarType().intValue()); + assertTrue(!pVal.stringValue().isEmpty()); + OleAuto.INSTANCE.VariantClear(pVal); + } finally { + if (svc != null) svc.Release(); + if (result != null) result.Release(); + if (method != null) method.Release(); + if (instance != null) instance.Release(); + if (regClass != null) regClass.Release(); + } + } + /** * Copy from WbemcliUtil#connectServer with American English selected as * locale. diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java index fe01225b9f..b95387f55f 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java @@ -32,7 +32,6 @@ import org.junit.Before; import org.junit.Test; -import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; import com.sun.jna.platform.win32.COM.util.annotation.ComObject; @@ -119,13 +118,13 @@ interface DWebBrowserEvents2 { public static final String IID = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}"; - @ComEventCallback(dispid = 0x000000fd) + @ComMethod(dispId = 0x000000fd) void OnQuit(); - @ComEventCallback(dispid = 0x000000fc) + @ComMethod(dispId = 0x000000fc) void NavigateComplete2(IUnknown source, Object url); - @ComEventCallback(dispid = 0x000000fa) + @ComMethod(dispId = 0x000000fa) void BeforeNavigate2(IUnknown pDisp, String URL, long Flags, @@ -148,6 +147,7 @@ public void errorReceivingCallbackEvent(String message, Exception exception) { volatile boolean blockNavigate = false; + @Override public void BeforeNavigate2( IUnknown pDisp, String URL, @@ -215,6 +215,7 @@ public void errorReceivingCallbackEvent(String message, Exception exception) { volatile boolean blockNavigate = false; + @Override public void BeforeNavigate2( IUnknown pDisp, String URL, @@ -303,6 +304,7 @@ public void unadvise_Quit() throws InterruptedException { } @Test + @SuppressWarnings("SleepWhileInLoop") public void adviseNavigateComplete2() throws InterruptedException { ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); @@ -328,6 +330,7 @@ public void adviseNavigateComplete2() throws InterruptedException { } @Test + @SuppressWarnings("SleepWhileInLoop") public void adviseBeforeNavigate() throws InterruptedException { ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); @@ -424,6 +427,7 @@ interface ComIWebBrowser2WithoutConnectionPoint extends IUnknown { } @Test + @SuppressWarnings("SleepWhileInLoop") public void adviseNavigateComplete2WithoutConnectionPoint() throws InterruptedException { ComInternetExplorerWithoutConnectionPoint ieApp = factory.createObject(ComInternetExplorerWithoutConnectionPoint.class); ComIWebBrowser2WithoutConnectionPoint iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2WithoutConnectionPoint.class); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java index 915e7bc6d7..ea1061080f 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java @@ -270,11 +270,13 @@ public void testConvertFloat() { } @Test + @SuppressWarnings("deprecation") public void testConvertDate() { testConvertDate(new Date(2015 - 1900, 1, 1, 9, 0, 0)); } @Test + @SuppressWarnings("deprecation") public void testConvertDstOffsetTime() { TimeZone timeZone = TimeZone.getDefault(); try { @@ -288,6 +290,7 @@ public void testConvertDstOffsetTime() { } @Test + @SuppressWarnings("deprecation") public void testConvertMillisecondTime() { testConvertDate(new Date(2015 - 1900, 1, 1, 0, 0, 0), 1); testConvertDate(new Date(2015 - 1900, 1, 1, 0, 0, 0), 499); @@ -375,6 +378,7 @@ private TestEnum(long val) { this.value = val; } + @Override public long getValue() { return this.value; } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java index c51b29b780..59813439b8 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java @@ -45,7 +45,6 @@ import com.sun.jna.platform.win32.Variant.VARIANT; import com.sun.jna.platform.win32.WTypes; import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinDef.UINT; import com.sun.jna.platform.win32.WinDef.WORD; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.IntByReference; @@ -176,7 +175,7 @@ public void testOfficeInvocationDemonstration() { hr = dp.Invoke(dispId, new REFIID(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, wFlagsCombined, pDispParams, result, pExcepInfo, puArgErr); assertTrue(COMUtils.SUCCEEDED(hr)); - assertEquals(72.0f, result.floatValue()); + assertEquals(72.0f, result.floatValue(), 0.1d); } @ComObject(clsId = CLSID_WORD_STRING) @@ -197,7 +196,7 @@ public WordApplication(boolean useActiveInstance) { public Float InchesToPoints(Float value) { VARIANT.ByReference pvResult = new VARIANT.ByReference(); - this.oleMethod(OleAuto.DISPATCH_METHOD , pvResult, this.getIDispatch(), "InchesToPoints", new VARIANT[] {new VARIANT(value)}); + this.oleMethod(OleAuto.DISPATCH_METHOD , pvResult, "InchesToPoints", new VARIANT[] {new VARIANT(value)}); return pvResult.floatValue(); } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Cfgmgr32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Cfgmgr32Test.java index ed98d2f12b..987aa8507c 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Cfgmgr32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Cfgmgr32Test.java @@ -124,7 +124,7 @@ public void testDeviceProperties() { int node = outputNode.getValue(); // Navigate the device tree using BFS - Queue deviceQueue = new ArrayDeque(); + Queue deviceQueue = new ArrayDeque<>(); IntByReference child = new IntByReference(); IntByReference sibling = new IntByReference(); // Initialize queue with root node diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java index 11ca96a732..fd2310a43b 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java @@ -34,12 +34,14 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.platform.win32.WTypes.LPSTR; + import static com.sun.jna.platform.win32.WinCrypt.CERT_QUERY_CONTENT_FLAG_ALL; import static com.sun.jna.platform.win32.WinCrypt.CERT_QUERY_CONTENT_FLAG_PFX_AND_LOAD; import static com.sun.jna.platform.win32.WinCrypt.CERT_QUERY_FORMAT_FLAG_ALL; import static com.sun.jna.platform.win32.WinCrypt.CERT_QUERY_OBJECT_FILE; import static com.sun.jna.platform.win32.WinCrypt.PKCS_7_ASN_ENCODING; import static com.sun.jna.platform.win32.WinCrypt.X509_ASN_ENCODING; + import com.sun.jna.platform.win32.WinCryptUtil.MANAGED_CRYPT_SIGN_MESSAGE_PARA; import com.sun.jna.win32.W32APIOptions; @@ -52,6 +54,7 @@ import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; +import java.security.cert.CertificateException; import java.util.Arrays; import java.util.Date; import java.util.List; @@ -71,6 +74,7 @@ import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; /** @@ -464,7 +468,6 @@ private void enumerateRootCertificates(HCERTSTORE hCertStore) { assertNotNull(ctx.pCertInfo.Subject); assertFalse(decodeName(ctx.pCertInfo.Issuer).isEmpty()); assertFalse(decodeName(ctx.pCertInfo.Subject).isEmpty()); - assertEquals(decodeName(ctx.pCertInfo.Issuer), decodeName(ctx.pCertInfo.Subject)); // System.out.printf("%20s: %s%n", "Issuer", decodeName(ctx.pCertInfo.Issuer)); // System.out.printf("%20s: %s%n", "Subject", decodeName(ctx.pCertInfo.Subject)); readCertificates++; @@ -675,6 +678,7 @@ private boolean createTestCertificate() { return true; } + @SuppressWarnings("deprecation") private Path createTestCrl() { try { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); @@ -695,14 +699,8 @@ private Path createTestCrl() { crlBuilder.addExtension(Extension.cRLNumber, false, new CRLNumber(new BigInteger("2"))); X509CRLHolder holder = crlBuilder.build(caSigner); - OutputStream fos = null; - try { - fos = Files.newOutputStream(tempFile); + try (OutputStream fos = Files.newOutputStream(tempFile)) { fos.write(holder.getEncoded()); - } finally { - if (fos != null) { - fos.close(); - } } return tempFile; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java index 2e191e9a38..7b81d425ee 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java @@ -50,7 +50,7 @@ public void testGetScreenshot() { // by checking for 20 distinct colors. // BufferedImages normally start life as one uniform color // so if that's not the case then some data was indeed copied over as a result of the getScreenshot() function. - List distinctPixels = new ArrayList(); + List distinctPixels = new ArrayList<>(); for (int x = 0; x < image.getWidth(); x++) { for (int y = 0; y < image.getHeight(); y++) { int pixel = image.getRGB(x, y); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/IPHlpAPITest.java b/contrib/platform/test/com/sun/jna/platform/win32/IPHlpAPITest.java index bad81f8046..e92ccd99f4 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/IPHlpAPITest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/IPHlpAPITest.java @@ -163,26 +163,51 @@ public void testGetTcpStatistics() { @Test public void testGetUdpStatistics() { + // The Math.min constructs when checking dwNoPorts + dwInErrors in + // comparison to dwInDatagramsis is used, because at least on + // appveyor inconsistent numbers were observed, rendering harder + // constaints useless. + // Sample: + // Datagrams received with errors (332) or no port (2) should be less than inbound datagrams (97). + MIB_UDPSTATS stats = new MIB_UDPSTATS(); int err = IPHlpAPI.INSTANCE.GetUdpStatistics(stats); assertEquals(String.format("Error %d calling GetUdpStatistics.", err), WinError.NO_ERROR, err); - assertTrue("Datagrams received with errors or no port should be less than inbound datagrams.", - stats.dwNoPorts + stats.dwInErrors <= stats.dwInDatagrams); + assertTrue( + String.format("Datagrams received with errors (%d) or no port (%d) should be less than inbound datagrams (%d).", + stats.dwNoPorts, stats.dwInErrors, stats.dwInDatagrams + ), + Math.min(1, stats.dwNoPorts + stats.dwInErrors) <= stats.dwInDatagrams + ); // Above should roughly match IPv4 stats with Ex version MIB_UDPSTATS stats4 = new MIB_UDPSTATS(); err = IPHlpAPI.INSTANCE.GetUdpStatisticsEx(stats4, IPHlpAPI.AF_INET); assertEquals(String.format("Error %d calling GetUdpStatistics.", err), WinError.NO_ERROR, err); assertTrue( - "Datagrams received with no port should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx", - stats.dwNoPorts <= stats4.dwNoPorts); + String.format( + "Datagrams received with no port should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)", + stats.dwNoPorts,stats4.dwNoPorts + ), + stats.dwNoPorts <= stats4.dwNoPorts + ); assertTrue( - "Datagrams received with errors should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx", + String.format( + "Datagrams received with errors should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)", + stats.dwInErrors, stats4.dwInErrors + ), stats.dwInErrors <= stats4.dwInErrors); - assertTrue("Datagrams received should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx", + assertTrue( + String.format( + "Datagrams received should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)", + stats.dwInDatagrams, stats4.dwInDatagrams + ), stats.dwInDatagrams <= stats4.dwInDatagrams); - assertTrue("Datagrams received with errors or no port should be less than inbound datagrams.", - stats4.dwNoPorts + stats4.dwInErrors <= stats4.dwInDatagrams); + assertTrue( + String.format("Datagrams received with errors (%d) or no port (%d) should be less than inbound datagrams (%d). (Ex-Version)", + stats4.dwNoPorts, stats4.dwInErrors, stats4.dwInDatagrams + ), + Math.min(1, stats4.dwNoPorts + stats4.dwInErrors) <= stats4.dwInDatagrams); } @Test 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 d964c70dec..606208b44d 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -119,7 +119,7 @@ public void testGetLastErrorNativeLibraryOverride() { // see https://github.com/twall/jna/issues/482 public void testNoDuplicateMethodsNames() { Collection dupSet = AbstractWin32TestSupport.detectDuplicateMethods(Kernel32.class); - if (dupSet.size() > 0) { + if (!dupSet.isEmpty()) { for (String name : new String[]{ // has 2 overloads by design since the API accepts both OSVERSIONINFO and OSVERSIONINFOEX "GetVersionEx", @@ -648,11 +648,8 @@ public void testReadFile() throws IOException { File tmp = File.createTempFile("testReadFile", "jna"); tmp.deleteOnExit(); - FileWriter fw = new FileWriter(tmp); - try { + try (FileWriter fw = new FileWriter(tmp)) { fw.append(expected); - } finally { - fw.close(); } HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, @@ -786,9 +783,7 @@ public void testDeviceIoControlFsctlReparse() throws IOException { File delLink = link.toFile(); delLink.deleteOnExit(); - // Required for FSCTL_SET_REPARSE_POINT - Advapi32Util.Privilege restore = new Advapi32Util.Privilege(WinNT.SE_RESTORE_NAME); - try { + try (Advapi32Util.Privilege restore = new Advapi32Util.Privilege(WinNT.SE_RESTORE_NAME)) { // Required for FSCTL_SET_REPARSE_POINT restore.enable(); HANDLE hFile = Kernel32.INSTANCE.CreateFile(link.toAbsolutePath().toString(), WinNT.GENERIC_READ | WinNT.FILE_WRITE_ATTRIBUTES | WinNT.FILE_WRITE_EA, @@ -839,9 +834,6 @@ public void testDeviceIoControlFsctlReparse() throws IOException { Kernel32Util.closeHandle(hFile); } } - finally { - restore.close(); - } } public void testCopyFile() throws IOException { @@ -908,19 +900,19 @@ public void testFindFirstFile() throws IOException { // Get data and confirm the 1st name is . for the directory itself. WIN32_FIND_DATA fd = new WIN32_FIND_DATA(p); - String actualFileName = new String(fd.getFileName()); + String actualFileName = fd.getFileName(); assertTrue(actualFileName.contentEquals(".")); // Get data and confirm the 2nd name is .. for the directory's parent assertTrue(Kernel32.INSTANCE.FindNextFile(hFile, p)); fd = new WIN32_FIND_DATA(p); - actualFileName = new String(fd.getFileName()); + actualFileName = fd.getFileName(); assertTrue(actualFileName.contentEquals("..")); // Get data and confirm the 3rd name is the tmp file name assertTrue(Kernel32.INSTANCE.FindNextFile(hFile, p)); fd = new WIN32_FIND_DATA(p); - actualFileName = new String(fd.getFileName()); + actualFileName = fd.getFileName(); assertTrue(actualFileName.contentEquals(tmpFile.getName())); // No more files in directory @@ -951,19 +943,19 @@ public void testFindFirstFileExFindExInfoStandard() throws IOException { // Get data and confirm the 1st name is . for the directory itself. WIN32_FIND_DATA fd = new WIN32_FIND_DATA(p); - String actualFileName = new String(fd.getFileName()); + String actualFileName = fd.getFileName(); assertTrue(actualFileName.contentEquals(".")); // Get data and confirm the 2nd name is .. for the directory's parent assertTrue(Kernel32.INSTANCE.FindNextFile(hFile, p)); fd = new WIN32_FIND_DATA(p); - actualFileName = new String(fd.getFileName()); + actualFileName = fd.getFileName(); assertTrue(actualFileName.contentEquals("..")); // Get data and confirm the 3rd name is the tmp file name assertTrue(Kernel32.INSTANCE.FindNextFile(hFile, p)); fd = new WIN32_FIND_DATA(p); - actualFileName = new String(fd.getFileName()); + actualFileName = fd.getFileName(); assertTrue(actualFileName.contentEquals(tmpFile.getName())); // No more files in directory @@ -994,8 +986,7 @@ public void testFindFirstFileExFindExInfoBasic() throws IOException { try { // Get data and confirm the 1st name is for the file itself WIN32_FIND_DATA fd = new WIN32_FIND_DATA(p); - String actualFileName = new String(fd.getFileName()); - actualFileName = new String(fd.getFileName()); + String actualFileName = fd.getFileName(); assertTrue(actualFileName.contentEquals(tmpFile.getName())); // FindExInfoBasic does not return the short name, so confirm that its empty @@ -1126,6 +1117,7 @@ public void testSetFileInformationByHandleFileDispositionInfo() throws IOExcepti assertFalse(Files.exists(Paths.get(tmp.getAbsolutePath()))); } + @SuppressWarnings("deprecation") public void testGetSetFileTime() throws IOException { File tmp = File.createTempFile("testGetSetFileTime", "jna"); tmp.deleteOnExit(); @@ -1168,7 +1160,7 @@ public void testGetProcessList() throws IOException { assertTrue(Kernel32.INSTANCE.Process32First(processEnumHandle, processEntry)); - List processIdList = new ArrayList(); + List processIdList = new ArrayList<>(); processIdList.add(processEntry.th32ProcessID.longValue()); while (Kernel32.INSTANCE.Process32Next(processEnumHandle, processEntry)) { @@ -1190,7 +1182,7 @@ public void testGetThreadList() throws IOException { assertTrue(Kernel32.INSTANCE.Thread32First(threadEnumHandle, threadEntry)); - List threadIdList = new ArrayList(); + List threadIdList = new ArrayList<>(); threadIdList.add(threadEntry.th32ThreadID); while (Kernel32.INSTANCE.Thread32Next(threadEnumHandle, threadEntry)) { @@ -1206,10 +1198,10 @@ public void testGetThreadList() throws IOException { public final void testGetPrivateProfileInt() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileInt", "ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - writer.println("[Section]"); - writer.println("existingKey = 123"); - writer.close(); + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { + writer.println("[Section]"); + writer.println("existingKey = 123"); + } assertEquals(123, Kernel32.INSTANCE.GetPrivateProfileInt("Section", "existingKey", 456, tmp.getCanonicalPath())); assertEquals(456, Kernel32.INSTANCE.GetPrivateProfileInt("Section", "missingKey", 456, tmp.getCanonicalPath())); @@ -1218,10 +1210,10 @@ public final void testGetPrivateProfileInt() throws IOException { public final void testGetPrivateProfileString() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileString", ".ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - writer.println("[Section]"); - writer.println("existingKey = ABC"); - writer.close(); + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { + writer.println("[Section]"); + writer.println("existingKey = ABC"); + } final char[] buffer = new char[8]; @@ -1237,11 +1229,11 @@ public final void testGetPrivateProfileString() throws IOException { public final void testWritePrivateProfileString() throws IOException { final File tmp = File.createTempFile("testWritePrivateProfileString", ".ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - writer.println("[Section]"); - writer.println("existingKey = ABC"); - writer.println("removedKey = JKL"); - writer.close(); + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { + writer.println("[Section]"); + writer.println("existingKey = ABC"); + writer.println("removedKey = JKL"); + } assertTrue(Kernel32.INSTANCE.WritePrivateProfileString("Section", "existingKey", "DEF", tmp.getCanonicalPath())); assertTrue(Kernel32.INSTANCE.WritePrivateProfileString("Section", "addedKey", "GHI", tmp.getCanonicalPath())); @@ -1259,13 +1251,10 @@ public final void testGetPrivateProfileSection() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileSection", ".ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - try { + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { writer.println("[X]"); writer.println("A=1"); writer.println("B=X"); - } finally { - writer.close(); } final char[] buffer = new char[9]; @@ -1279,12 +1268,9 @@ public final void testGetPrivateProfileSectionNames() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileSectionNames", ".ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - try { + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { writer.println("[S1]"); writer.println("[S2]"); - } finally { - writer.close(); } final char[] buffer = new char[7]; @@ -1297,23 +1283,20 @@ public final void testWritePrivateProfileSection() throws IOException { final File tmp = File.createTempFile("testWritePrivateProfileSection", ".ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - try { + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { writer.println("[S1]"); writer.println("A=1"); writer.println("B=X"); - } finally { - writer.close(); } final boolean result = Kernel32.INSTANCE.WritePrivateProfileSection("S1", "A=3\0E=Z\0\0", tmp.getCanonicalPath()); assertTrue(result); - final BufferedReader reader = new BufferedReader(new FileReader(tmp)); - assertEquals(reader.readLine(), "[S1]"); - assertTrue(reader.readLine().matches("A\\s*=\\s*3")); - assertTrue(reader.readLine().matches("E\\s*=\\s*Z")); - reader.close(); + try (BufferedReader reader = new BufferedReader(new FileReader(tmp))) { + assertEquals(reader.readLine(), "[S1]"); + assertTrue(reader.readLine().matches("A\\s*=\\s*3")); + assertTrue(reader.readLine().matches("E\\s*=\\s*Z")); + } } /** @@ -1710,7 +1693,7 @@ public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam public void testEnumResourceTypes() { - final List types = new ArrayList(); + final List types = new ArrayList<>(); WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { @Override @@ -1732,7 +1715,7 @@ public boolean invoke(HMODULE module, Pointer type, Pointer lParam) { boolean result = Kernel32.INSTANCE.EnumResourceTypes(null, ertp, null); assertTrue("EnumResourceTypes should not have failed.", result); assertEquals("GetLastError should be set to 0", WinError.ERROR_SUCCESS, Kernel32.INSTANCE.GetLastError()); - assertTrue("EnumResourceTypes should return some resource type names", types.size() > 0); + assertTrue("EnumResourceTypes should return some resource type names", !types.isEmpty()); } public void testModule32FirstW() { @@ -1976,12 +1959,9 @@ public void testCreateFileMapping() throws IOException { File testFile = File.createTempFile("jna-test", ".txt"); try { - OutputStream os = new FileOutputStream(testFile); - try { + try (OutputStream os = new FileOutputStream(testFile)) { os.write(testString.getBytes("UTF-8")); os.write(0); - } finally { - os.close(); } SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); @@ -2099,4 +2079,33 @@ public void testVirtualLockUnlock() { // Unlocking an unlocked region should fail assertFalse(Kernel32.INSTANCE.VirtualUnlock(mem, new SIZE_T(4096))); } + + public void testGetPriorityClass() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32.INSTANCE.GetPriorityClass(selfHandle))); + } + + public void testSetPriorityClass() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Kernel32.INSTANCE.SetPriorityClass(selfHandle, Kernel32.HIGH_PRIORITY_CLASS)); + } + + public void testGetThreadPriority() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentThread(); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.INSTANCE.GetThreadPriority(selfHandle))); + } + + public void testSetThreadPriority() { + final HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentThread(); + assertTrue(Kernel32.INSTANCE.SetThreadPriority(selfHandle, Kernel32.THREAD_PRIORITY_ABOVE_NORMAL)); + } + + public void testIsProcessorFeaturePresent() { + // Always returns false for Windows 7 or later + assertFalse(Kernel32.INSTANCE.IsProcessorFeaturePresent(Kernel32.PF_FLOATING_POINT_PRECISION_ERRATA)); + // Always true in 64 bit, requirement to run Windows + assertTrue(Kernel32.INSTANCE.IsProcessorFeaturePresent(Kernel32.PF_MMX_INSTRUCTIONS_AVAILABLE)); + // Invalid values always return false + assertFalse(Kernel32.INSTANCE.IsProcessorFeaturePresent(-1)); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java index cdb5c373f4..d045751ced 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java @@ -37,6 +37,7 @@ import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Tlhelp32.MODULEENTRY32W; +import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinNT.CACHE_RELATIONSHIP; import com.sun.jna.platform.win32.WinNT.GROUP_RELATIONSHIP; import com.sun.jna.platform.win32.WinNT.HANDLE; @@ -210,10 +211,10 @@ public void testGetEnvironmentVariable() { public final void testGetPrivateProfileInt() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileInt", "ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - writer.println("[Section]"); - writer.println("existingKey = 123"); - writer.close(); + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { + writer.println("[Section]"); + writer.println("existingKey = 123"); + } assertEquals(123, Kernel32Util.getPrivateProfileInt("Section", "existingKey", 456, tmp.getCanonicalPath())); assertEquals(456, Kernel32Util.getPrivateProfileInt("Section", "missingKey", 456, tmp.getCanonicalPath())); @@ -222,10 +223,10 @@ public final void testGetPrivateProfileInt() throws IOException { public final void testGetPrivateProfileString() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileString", "ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - writer.println("[Section]"); - writer.println("existingKey = ABC"); - writer.close(); + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { + writer.println("[Section]"); + writer.println("existingKey = ABC"); + } assertEquals("ABC", Kernel32Util.getPrivateProfileString("Section", "existingKey", "DEF", tmp.getCanonicalPath())); assertEquals("DEF", Kernel32Util.getPrivateProfileString("Section", "missingKey", "DEF", tmp.getCanonicalPath())); @@ -234,44 +235,38 @@ public final void testGetPrivateProfileString() throws IOException { public final void testWritePrivateProfileString() throws IOException { final File tmp = File.createTempFile("testWritePrivateProfileString", "ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - writer.println("[Section]"); - writer.println("existingKey = ABC"); - writer.println("removedKey = JKL"); - writer.close(); + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { + writer.println("[Section]"); + writer.println("existingKey = ABC"); + writer.println("removedKey = JKL"); + } Kernel32Util.writePrivateProfileString("Section", "existingKey", "DEF", tmp.getCanonicalPath()); Kernel32Util.writePrivateProfileString("Section", "addedKey", "GHI", tmp.getCanonicalPath()); Kernel32Util.writePrivateProfileString("Section", "removedKey", null, tmp.getCanonicalPath()); - final BufferedReader reader = new BufferedReader(new FileReader(tmp)); - assertEquals(reader.readLine(), "[Section]"); - assertTrue(reader.readLine().matches("existingKey\\s*=\\s*DEF")); - assertTrue(reader.readLine().matches("addedKey\\s*=\\s*GHI")); - assertEquals(reader.readLine(), null); - reader.close(); + try (BufferedReader reader = new BufferedReader(new FileReader(tmp))) { + assertEquals(reader.readLine(), "[Section]"); + assertTrue(reader.readLine().matches("existingKey\\s*=\\s*DEF")); + assertTrue(reader.readLine().matches("addedKey\\s*=\\s*GHI")); + assertEquals(reader.readLine(), null); + } } public final void testGetPrivateProfileSection() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileSection", ".ini"); tmp.deleteOnExit(); - final PrintWriter writer0 = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - try { + try (PrintWriter writer0 = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { writer0.println("[X]"); - } finally { - writer0.close(); } final String[] lines0 = Kernel32Util.getPrivateProfileSection("X", tmp.getCanonicalPath()); assertEquals(lines0.length, 0); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp, true))); - try { + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp, true)))) { writer.println("A=1"); writer.println("foo=bar"); - } finally { - writer.close(); } final String[] lines = Kernel32Util.getPrivateProfileSection("X", tmp.getCanonicalPath()); @@ -284,16 +279,13 @@ public final void testGetPrivateProfileSectionNames() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileSectionNames", "ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - try { + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { writer.println("[S1]"); writer.println("A=1"); writer.println("B=X"); writer.println("[S2]"); writer.println("C=2"); writer.println("D=Y"); - } finally { - writer.close(); } String[] sectionNames = Kernel32Util.getPrivateProfileSectionNames(tmp.getCanonicalPath()); @@ -306,30 +298,24 @@ public final void testWritePrivateProfileSection() throws IOException { final File tmp = File.createTempFile("testWritePrivateProfileSecion", "ini"); tmp.deleteOnExit(); - final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp))); - try { + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmp)))) { writer.println("[S1]"); writer.println("A=1"); writer.println("B=X"); writer.println("[S2]"); writer.println("C=2"); writer.println("foo=bar"); - } finally { - writer.close(); } Kernel32Util.writePrivateProfileSection("S1", new String[] { "A=3", "E=Z" }, tmp.getCanonicalPath()); - final BufferedReader reader = new BufferedReader(new FileReader(tmp)); - try { + try (BufferedReader reader = new BufferedReader(new FileReader(tmp))) { assertEquals(reader.readLine(), "[S1]"); assertEquals(reader.readLine(), "A=3"); assertEquals(reader.readLine(), "E=Z"); assertEquals(reader.readLine(), "[S2]"); assertEquals(reader.readLine(), "C=2"); assertEquals(reader.readLine(), "foo=bar"); - } finally { - reader.close(); } } @@ -412,11 +398,11 @@ public void testGetLogicalProcessorInformation() { public void testGetLogicalProcessorInformationEx() { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX[] procInfo = Kernel32Util .getLogicalProcessorInformationEx(WinNT.LOGICAL_PROCESSOR_RELATIONSHIP.RelationAll); - List groups = new ArrayList(); - List packages = new ArrayList(); - List numaNodes = new ArrayList(); - List caches = new ArrayList(); - List cores = new ArrayList(); + List groups = new ArrayList<>(); + List packages = new ArrayList<>(); + List numaNodes = new ArrayList<>(); + List caches = new ArrayList<>(); + List cores = new ArrayList<>(); for (int i = 0; i < procInfo.length; i++) { // Build list from relationship @@ -513,4 +499,90 @@ public void testGetLogicalProcessorInformationEx() { assertTrue(cache.associativity == WinNT.CACHE_FULLY_ASSOCIATIVE || cache.associativity > 0); } } + + public void testGetCurrentProcessPriority() { + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32Util.getCurrentProcessPriority())); + } + + public void testSetCurrentProcessPriority() { + Kernel32Util.setCurrentProcessPriority(Kernel32.HIGH_PRIORITY_CLASS); + } + + public void testSetCurrentProcessBackgroundMode() { + try { + Kernel32Util.setCurrentProcessBackgroundMode(true); + } finally { + try { + Kernel32Util.setCurrentProcessBackgroundMode(false); // Reset the "background" mode! + } catch (Exception e) { } + } + } + + public void testGetCurrentThreadPriority() { + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32Util.getCurrentThreadPriority())); + } + + public void testSetCurrentThreadPriority() { + Kernel32Util.setCurrentThreadPriority(Kernel32.THREAD_PRIORITY_ABOVE_NORMAL); + } + + public void testSetCurrentThreadBackgroundMode() { + try { + Kernel32Util.setCurrentThreadBackgroundMode(true); + } finally { + try { + Kernel32Util.setCurrentThreadBackgroundMode(false); // Reset the "background" mode! + } catch (Exception e) { } + } + } + + public void testGetProcessPriority() { + final int pid = Kernel32.INSTANCE.GetCurrentProcessId(); + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32Util.getProcessPriority(pid))); + } + + public void testSetProcessPriority() { + final int pid = Kernel32.INSTANCE.GetCurrentProcessId(); + Kernel32Util.setProcessPriority(pid, Kernel32.HIGH_PRIORITY_CLASS); + } + + public void testGetThreadPriority() { + final int tid = Kernel32.INSTANCE.GetCurrentThreadId(); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32Util.getThreadPriority(tid))); + } + + public void testSetThreadPriority() { + final int tid = Kernel32.INSTANCE.GetCurrentThreadId(); + Kernel32Util.setThreadPriority(tid, Kernel32.THREAD_PRIORITY_ABOVE_NORMAL); + } + + public void testIsValidPriorityClass() { + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32.NORMAL_PRIORITY_CLASS)); + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32.IDLE_PRIORITY_CLASS)); + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32.HIGH_PRIORITY_CLASS)); + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32.REALTIME_PRIORITY_CLASS)); + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32.BELOW_NORMAL_PRIORITY_CLASS)); + assertTrue(Kernel32Util.isValidPriorityClass(Kernel32.ABOVE_NORMAL_PRIORITY_CLASS)); + assertFalse(Kernel32Util.isValidPriorityClass(new DWORD(0L))); + assertFalse(Kernel32Util.isValidPriorityClass(new DWORD(1L))); + assertFalse(Kernel32Util.isValidPriorityClass(new DWORD(0xFFFFFFFF))); + assertFalse(Kernel32Util.isValidPriorityClass(Kernel32.PROCESS_MODE_BACKGROUND_BEGIN)); + assertFalse(Kernel32Util.isValidPriorityClass(Kernel32.PROCESS_MODE_BACKGROUND_END)); + } + + public void testIsValidThreadPriority() { + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_PRIORITY_IDLE)); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_PRIORITY_LOWEST)); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_PRIORITY_BELOW_NORMAL)); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_PRIORITY_NORMAL)); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_PRIORITY_ABOVE_NORMAL)); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_PRIORITY_HIGHEST)); + assertTrue(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_PRIORITY_TIME_CRITICAL)); + assertFalse(Kernel32Util.isValidThreadPriority( 3)); + assertFalse(Kernel32Util.isValidThreadPriority( -3)); + assertFalse(Kernel32Util.isValidThreadPriority( 16)); + assertFalse(Kernel32Util.isValidThreadPriority(-16)); + assertFalse(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_MODE_BACKGROUND_BEGIN)); + assertFalse(Kernel32Util.isValidThreadPriority(Kernel32.THREAD_MODE_BACKGROUND_END)); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java b/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java index 4ce1b1947a..3088999d67 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java @@ -130,7 +130,7 @@ private File createTempFile() throws Exception { file.createNewFile(); FileWriter fileWriter = new FileWriter(file); for (int i = 0; i < 1000; i++) { - fileWriter.write("Sample text " + i + System.getProperty("line.separator")); + fileWriter.write("Sample text " + i + System.lineSeparator()); } fileWriter.close(); return file; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java b/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java index 45edbc2de5..18cac051ad 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java @@ -87,7 +87,7 @@ public void testQueryOneCounter() { @Test public void testQueryMultipleCounters() { - Collection names = new LinkedList(); + Collection names = new LinkedList<>(); PDH_COUNTER_PATH_ELEMENTS elems = new PDH_COUNTER_PATH_ELEMENTS(); elems.szObjectName = "Processor"; elems.szInstanceName = "_Total"; @@ -102,7 +102,7 @@ public void testQueryMultipleCounters() { HANDLE hQuery = ref.getValue(); try { - Map handlesMap = new HashMap(names.size()); + Map handlesMap = new HashMap<>(names.size()); try { for (String counterName : names) { ref.setValue(null); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java b/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java index 4b7613d3b6..1014c0df09 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java @@ -133,7 +133,7 @@ public void testEnumProcessModules() { me = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, Kernel32.INSTANCE.GetCurrentProcessId()); assertTrue("Handle to my process should not be null", me != null); - List list = new LinkedList(); + List list = new LinkedList<>(); HMODULE[] lphModule = new HMODULE[100 * 4]; IntByReference lpcbNeeded = new IntByReference(); @@ -175,7 +175,7 @@ public void testGetModuleInformation() { me = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, Kernel32.INSTANCE.GetCurrentProcessId()); assertTrue("Handle to my process should not be null", me != null); - List list = new LinkedList(); + List list = new LinkedList<>(); HMODULE[] lphModule = new HMODULE[100 * 4]; IntByReference lpcbNeeded = new IntByReference(); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java b/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java index b5b7621b76..a7e6d356e6 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java @@ -25,7 +25,6 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; -import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.util.ObjectFactory; @@ -61,21 +60,21 @@ import java.util.Date; import java.util.List; +import org.junit.After; import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertTrue; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import org.junit.After; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -import org.junit.Before; import static com.sun.jna.platform.win32.OaIdlUtil.toPrimitiveArray; import com.sun.jna.platform.win32.WTypes.VARTYPE; import com.sun.jna.platform.win32.WinDef.LONG; import java.lang.reflect.Field; -import org.junit.Assume; public class SAFEARRAYTest { static { @@ -273,6 +272,7 @@ public void testMultidimensionalNotNullBased() { } @Test + @SuppressWarnings("deprecation") public void testDataTypes() { int idx = 1; Pointer dataPointer; @@ -518,8 +518,8 @@ public void testADODB() { recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl, System.DateCreated FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1); // Save complete list for comparison with subscript list - List urls = new ArrayList(5); - List names = new ArrayList(5); + List urls = new ArrayList<>(5); + List names = new ArrayList<>(5); while (!recordset.getEOF()) { WinNT.HRESULT hr; @@ -774,7 +774,7 @@ public static enum CursorTypeEnum implements IComEnum { private CursorTypeEnum(long value) { this.value = value; } - private long value; + private final long value; @Override public long getValue() { @@ -796,7 +796,7 @@ public static enum LockTypeEnum implements IComEnum { private LockTypeEnum(long value) { this.value = value; } - private long value; + private final long value; @Override public long getValue() { @@ -831,6 +831,10 @@ public static interface _Connection { /** *

    * memberId(10)

    + * @param ConnectionString + * @param UserID + * @param Password + * @param Options */ @ComMethod(name = "Open") void Open(String ConnectionString, @@ -851,6 +855,7 @@ public static interface _Recordset { /** *

    * memberId(1006)

    + * @return */ @ComProperty(name = "EOF") Boolean getEOF(); @@ -858,6 +863,10 @@ public static interface _Recordset { /** *

    * memberId(1016)

    + * @param Rows + * @param Start + * @param Fields + * @return */ @ComMethod(name = "GetRows") SAFEARRAY GetRows(int Rows, @@ -867,6 +876,8 @@ SAFEARRAY GetRows(int Rows, /** *

    * memberId(1016)

    + * @param Rows + * @return */ @ComMethod(name = "GetRows") SAFEARRAY GetRows(int Rows); @@ -874,6 +885,7 @@ SAFEARRAY GetRows(int Rows, /** *

    * memberId(1016)

    + * @return */ @ComMethod(name = "GetRows") SAFEARRAY GetRows(); @@ -888,6 +900,11 @@ SAFEARRAY GetRows(int Rows, /** *

    * memberId(1022)

    + * @param Source + * @param ActiveConnection + * @param CursorType + * @param LockType + * @param Options */ @ComMethod(name = "Open") void Open(Object Source, diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java index c7a589bb8b..1c5c5b6a34 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java @@ -190,84 +190,6 @@ public void testAcceptSecurityContext() { phClientCredential)); } - public void testImpersonateRevertSecurityContext() { - // client ----------- acquire outbound credential handle - CredHandle phClientCredential = new CredHandle(); - TimeStamp ptsClientExpiry = new TimeStamp(); - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( - null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, - null, phClientCredential, ptsClientExpiry)); - // client ----------- security context - CtxtHandle phClientContext = new CtxtHandle(); - IntByReference pfClientContextAttr = new IntByReference(); - // server ----------- acquire inbound credential handle - CredHandle phServerCredential = new CredHandle(); - TimeStamp ptsServerExpiry = new TimeStamp(); - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( - null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, - null, phServerCredential, ptsServerExpiry)); - // server ----------- security context - CtxtHandle phServerContext = new CtxtHandle(); - ManagedSecBufferDesc pbServerToken = null; - IntByReference pfServerContextAttr = new IntByReference(); - int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; - int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; - do { - // client ----------- initialize security context, produce a client token - // client token returned is always new - ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); - if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { - // server token is empty the first time - ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null - ? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes()); - clientRc = Secur32.INSTANCE.InitializeSecurityContext( - phClientCredential, - phClientContext.isNull() ? null : phClientContext, - Advapi32Util.getUserName(), - Sspi.ISC_REQ_CONNECTION, - 0, - Sspi.SECURITY_NATIVE_DREP, - pbServerTokenCopy, - 0, - phClientContext, - pbClientToken, - pfClientContextAttr, - null); - assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); - } - // server ----------- accept security context, produce a server token - if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { - pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); - ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes()); - serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, - phServerContext.isNull() ? null : phServerContext, - pbClientTokenByValue, - Sspi.ISC_REQ_CONNECTION, - Sspi.SECURITY_NATIVE_DREP, - phServerContext, - pbServerToken, - pfServerContextAttr, - ptsServerExpiry); - assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); - } - } while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); - // impersonate - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.ImpersonateSecurityContext( - phServerContext)); - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.RevertSecurityContext( - phServerContext)); - // release server context - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( - phServerContext)); - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( - phServerCredential)); - // release client context - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( - phClientContext)); - assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( - phClientCredential)); - } - public void testEnumerateSecurityPackages() { IntByReference pcPackages = new IntByReference(); PSecPkgInfo.ByReference pPackageInfo = new PSecPkgInfo.ByReference(); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Secur32_Impersonate_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Secur32_Impersonate_Test.java new file mode 100644 index 0000000000..6c57d1c002 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/Secur32_Impersonate_Test.java @@ -0,0 +1,113 @@ +/* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.win32; + +import com.sun.jna.ptr.IntByReference; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + + +public class Secur32_Impersonate_Test { + + @Test + public void testImpersonateRevertSecurityContext() { + // client ----------- acquire outbound credential handle + Sspi.CredHandle phClientCredential = new Sspi.CredHandle(); + Sspi.TimeStamp ptsClientExpiry = new Sspi.TimeStamp(); + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( + null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, + null, phClientCredential, ptsClientExpiry)); + // client ----------- security context + Sspi.CtxtHandle phClientContext = new Sspi.CtxtHandle(); + IntByReference pfClientContextAttr = new IntByReference(); + // server ----------- acquire inbound credential handle + Sspi.CredHandle phServerCredential = new Sspi.CredHandle(); + Sspi.TimeStamp ptsServerExpiry = new Sspi.TimeStamp(); + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( + null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, + null, phServerCredential, ptsServerExpiry)); + // server ----------- security context + Sspi.CtxtHandle phServerContext = new Sspi.CtxtHandle(); + SspiUtil.ManagedSecBufferDesc pbServerToken = null; + IntByReference pfServerContextAttr = new IntByReference(); + int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; + int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; + do { + // client ----------- initialize security context, produce a client token + // client token returned is always new + SspiUtil.ManagedSecBufferDesc pbClientToken = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); + if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { + // server token is empty the first time + SspiUtil.ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null + ? null : new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes()); + clientRc = Secur32.INSTANCE.InitializeSecurityContext( + phClientCredential, + phClientContext.isNull() ? null : phClientContext, + Advapi32Util.getUserName(), + Sspi.ISC_REQ_CONNECTION, + 0, + Sspi.SECURITY_NATIVE_DREP, + pbServerTokenCopy, + 0, + phClientContext, + pbClientToken, + pfClientContextAttr, + null); + assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); + } + // server ----------- accept security context, produce a server token + if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { + pbServerToken = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); + SspiUtil.ManagedSecBufferDesc pbClientTokenByValue = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes()); + serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, + phServerContext.isNull() ? null : phServerContext, + pbClientTokenByValue, + Sspi.ISC_REQ_CONNECTION, + Sspi.SECURITY_NATIVE_DREP, + phServerContext, + pbServerToken, + pfServerContextAttr, + ptsServerExpiry); + assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); + } + } while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); + // impersonate + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.ImpersonateSecurityContext( + phServerContext)); + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.RevertSecurityContext( + phServerContext)); + // release server context + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( + phServerContext)); + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( + phServerCredential)); + // release client context + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( + phClientContext)); + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( + phClientCredential)); + } +} diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java index a46c22ae66..570b8fbd1d 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java @@ -228,14 +228,11 @@ public void testShellExecuteEx() { */ private void fillTempFile(File file) throws IOException { file.createNewFile(); - FileWriter fileWriter = new FileWriter(file); - try { + try (FileWriter fileWriter = new FileWriter(file)) { for (int i = 0; i < 10; i++) { fileWriter.write("Sample line of text"); - fileWriter.write(System.getProperty("line.separator")); + fileWriter.write(System.lineSeparator()); } - } finally { - fileWriter.close(); } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java index c3c8321a22..38f82beaa0 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java @@ -150,10 +150,7 @@ public void testRegisterHotKey() { robot.keyRelease(vk); msg = waitForMessage(500); assertNull(msg); - } catch (AWTException e) { - e.printStackTrace(); - fail(); - } catch (InterruptedException e) { + } catch (AWTException | InterruptedException e) { e.printStackTrace(); fail(); } finally { @@ -599,4 +596,12 @@ public void testToUnicodeEx() { // which is in an undefined state at test execution and may change arbitrarily // during the test. } + + @Test + public void testRegisterPowerSettingNotification() { + WinUser.HPOWERNOTIFY hpowernotify = INSTANCE.RegisterPowerSettingNotification( + new HWND(), WinNT.GUID_CONSOLE_DISPLAY_STATE, User32.DEVICE_NOTIFY_WINDOW_HANDLE); + assertNotNull(hpowernotify); + assertNotEquals(0, INSTANCE.UnregisterPowerSettingNotification(hpowernotify)); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java b/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java index d034875cb4..4ab8c162a7 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java @@ -112,6 +112,7 @@ public void testVariantRecord() { pvRecord2 = (VARIANT._VARIANT.__VARIANT.BRECORD)variant.getValue(); } + @SuppressWarnings("deprecation") public void testDATECalculation() { // Samples from MSDN to ensure correct implementation // Definition is to be found here: https://msdn.microsoft.com/de-de/library/82ab7w69.aspx @@ -164,6 +165,7 @@ public void testDATECalculation() { testDate, new DATE(testDate).getAsJavaDate()); } + @SuppressWarnings("deprecation") public void testVariantConstructors() { VARIANT variant; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java b/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java index 16cbaca68b..392f9ef1ce 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java @@ -47,7 +47,7 @@ public static void main(String[] args) { private File tmpdir; protected void setUp() throws Exception { - events = new HashMap(); + events = new HashMap<>(); final FileListener listener = new FileListener() { public void fileChanged(FileEvent e) { events.put(Integer.valueOf(e.getType()), e); @@ -115,11 +115,8 @@ public void testNotifyOnFileModification() throws Exception { monitor.addWatch(tmpdir); File file = File.createTempFile(getName(), ".tmp", tmpdir); file.deleteOnExit(); - final FileOutputStream os = new FileOutputStream(file); - try { + try (FileOutputStream os = new FileOutputStream(file)) { os.write(getName().getBytes()); - } finally { - os.close(); } final FileEvent event = waitForFileEvent(FileMonitor.FILE_MODIFIED); assertNotNull("No file modified event: " + events, event); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceManagerTest.java b/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceManagerTest.java index d9a0f18699..77de21b4b4 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceManagerTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceManagerTest.java @@ -65,7 +65,7 @@ public void testEnumServices() { W32ServiceManager manager = new W32ServiceManager(); // It is expected, that these services are present - List expectedServices = new ArrayList(4); + List expectedServices = new ArrayList<>(4); expectedServices.add("Schedule"); if (VersionHelpers.IsWindows8OrGreater()) { expectedServices.add("SystemEventsBroker"); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java b/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java index 3ccaed3d9c..006e9e1a62 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java @@ -99,7 +99,7 @@ public void testSetAndGetFailureActions() { W32Service service = _serviceManager.openService(svcId, Winsvc.SC_MANAGER_ALL_ACCESS); SERVICE_FAILURE_ACTIONS prevActions = service.getFailureActions(); - List actions = new LinkedList(); + List actions = new LinkedList<>(); SC_ACTION action = new SC_ACTION(); action.type = Winsvc.SC_ACTION_RESTART; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java index ba482d5540..a235731a81 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java @@ -69,6 +69,7 @@ public void testLPWSTRConstruction() { assertEquals(fromPointer.getValue(), TEST_STRING); } + @SuppressWarnings("deprecation") public void testBSTRBasic() { String demoString = "input\u00D6\u00E4\u00DC?!"; // Allocation via system and the "correct" way diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java index 6b334a911b..cfe096b862 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java @@ -255,7 +255,7 @@ public void testEvtOpenLog() throws Exception { public void testEvtOpenChannelEnum() throws Exception { EVT_HANDLE channelHandle = null; - List channelList = new ArrayList(); + List channelList = new ArrayList<>(); try { channelHandle = Wevtapi.INSTANCE.EvtOpenChannelEnum(null, 0); if (channelHandle == null) { @@ -337,7 +337,7 @@ public void testEvtOpenPublisherEnum() throws Exception { Winevt.EVT_RPC_LOGIN_FLAGS.EvtRpcLoginAuthDefault); EVT_HANDLE session = null; EVT_HANDLE publisherEnumHandle = null; - List publisherList = new ArrayList(); + List publisherList = new ArrayList<>(); try { session = Wevtapi.INSTANCE.EvtOpenSession(Winevt.EVT_LOGIN_CLASS.EvtRpcLogin, login, 0, 0); if (session == null) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java b/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java index 99200fd8da..8641536295 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java @@ -72,12 +72,13 @@ public static void main(String[] args) { public static final String serviceName = "Win32ServiceDemo"; public static final String description = "TestService Description"; - private static final Set SUFFIXES = new HashSet(); + private static final Set SUFFIXES = new HashSet<>(); static { SUFFIXES.add("jna.jar"); SUFFIXES.add("jna-test.jar"); SUFFIXES.add("classes"); + SUFFIXES.add("test-classes"); } private final Object waitObject = new Object(); @@ -121,7 +122,7 @@ public static boolean install() { } } - String JAVA_HOME = System.getenv("JAVA_HOME"); + String JAVA_HOME = System.getProperty("java.home", System.getenv("JAVA_HOME")); String javaBinary = "java.exe"; if(JAVA_HOME != null) { javaBinary = "\"" + new File(JAVA_HOME, "\\bin\\java.exe").getAbsolutePath() + "\""; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinPerfTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinPerfTest.java index c5913239b8..47a6d920c9 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinPerfTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinPerfTest.java @@ -122,7 +122,7 @@ public void testPerfDataBLock() { // PERF_INSTANCE_DEFINITION test long perfInstanceOffset = perfObjectOffset + perfObject.DefinitionLength; - Set pidSet = new HashSet(); + Set pidSet = new HashSet<>(); for (int inst = 0; inst < perfObject.NumInstances; inst++) { PERF_INSTANCE_DEFINITION perfInstance = new PERF_INSTANCE_DEFINITION( pPerfData.share(perfInstanceOffset)); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java index a4fa822505..cde138518d 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java @@ -23,6 +23,12 @@ */ package com.sun.jna.platform.win32; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.COM.COMLateBindingObject; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.IDispatch; +import com.sun.jna.ptr.PointerByReference; import java.util.Map; import org.junit.After; @@ -37,13 +43,41 @@ public static void main(String[] args) { jUnitCore.run(WininetUtilTest.class); } + private static final Guid.CLSID CLSID_InternetExplorer = new Guid.CLSID("{0002DF01-0000-0000-C000-000000000046}"); + + private PointerByReference ieApp; + private Dispatch ieDispatch; + @Before public void setUp() throws Exception { // Launch IE in a manner that should ensure it opens even if the system // default browser is Chrome, Firefox, or something else. // Launching IE to a page ensures there will be content in the WinInet // cache. - Runtime.getRuntime().exec("cmd /c start iexplore.exe -nomerge -nohome \"http://www.google.com\""); + WinNT.HRESULT hr; + + hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + COMUtils.checkRC(hr); + + // IE can not be launched directly anymore - so load it via COM + + ieApp = new PointerByReference(); + hr = Ole32.INSTANCE + .CoCreateInstance(CLSID_InternetExplorer, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ieApp); + COMUtils.checkRC(hr); + + ieDispatch = new Dispatch(ieApp.getValue()); + LocalLateBinding ie = new LocalLateBinding(ieDispatch); + + ie.setProperty("Visible", true); + + Variant.VARIANT url = new Variant.VARIANT("http://www.google.com"); + Variant.VARIANT result = ie.invoke("Navigate", url); + OleAuto.INSTANCE.VariantClear(url); + OleAuto.INSTANCE.VariantClear(result); + + ieDispatch.Release(); + Ole32.INSTANCE.CoUninitialize(); // There's no easy way to monitor IE and see when it's done loading // google.com, so just give it 10 seconds. @@ -77,6 +111,24 @@ public void testGetCache() throws Exception { @After public void tearDown() throws Exception { // only kill the freshly opened Google window, unless someone has two IE windows open to Google. - Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe /fi \"windowtitle eq Google*\""); + Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe"); + } + + private static class LocalLateBinding extends COMLateBindingObject { + + public LocalLateBinding(IDispatch iDispatch) { + super(iDispatch); + } + + @Override + public void setProperty(String propertyName, boolean value) { + super.setProperty(propertyName, value); + } + + @Override + public Variant.VARIANT invoke(String methodName, Variant.VARIANT arg) { + return super.invoke(methodName, arg); + } + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java index ce465b9419..a603b3780c 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java @@ -81,7 +81,7 @@ public void testWTSEnumerateProcessesEx() { WTS_PROCESS_INFO_EX processInfoRef = new WTS_PROCESS_INFO_EX(pProcessInfo); WTS_PROCESS_INFO_EX[] processInfo = (WTS_PROCESS_INFO_EX[]) processInfoRef.toArray(pCount.getValue()); - Set pidSet = new HashSet(); + Set pidSet = new HashSet<>(); for (WTS_PROCESS_INFO_EX procInfo : processInfo) { // PIDs should be unique if (procInfo.ProcessId != 0) { diff --git a/dist/aix-ppc.jar b/dist/aix-ppc.jar index 5dbaeafba6..b276542d2c 100644 Binary files a/dist/aix-ppc.jar and b/dist/aix-ppc.jar differ diff --git a/dist/aix-ppc64.jar b/dist/aix-ppc64.jar index 08c16e7e56..c8d1cbacf2 100644 Binary files a/dist/aix-ppc64.jar and b/dist/aix-ppc64.jar differ diff --git a/dist/android-aarch64.jar b/dist/android-aarch64.jar index 3e5e03a5f5..3355b63c87 100644 Binary files a/dist/android-aarch64.jar and b/dist/android-aarch64.jar differ diff --git a/dist/android-arm.jar b/dist/android-arm.jar index 1252debd52..aa53b982d4 100644 Binary files a/dist/android-arm.jar and b/dist/android-arm.jar differ diff --git a/dist/android-armv7.jar b/dist/android-armv7.jar index 132521d1eb..ee41cbafdc 100644 Binary files a/dist/android-armv7.jar and b/dist/android-armv7.jar differ diff --git a/dist/android-mips.jar b/dist/android-mips.jar index af584cde11..49ecc391a3 100644 Binary files a/dist/android-mips.jar and b/dist/android-mips.jar differ diff --git a/dist/android-mips64.jar b/dist/android-mips64.jar index 3c72497d02..8b7cde1d89 100644 Binary files a/dist/android-mips64.jar and b/dist/android-mips64.jar differ diff --git a/dist/android-x86-64.jar b/dist/android-x86-64.jar index fbed760bce..4b5dc2294d 100644 Binary files a/dist/android-x86-64.jar and b/dist/android-x86-64.jar differ diff --git a/dist/android-x86.jar b/dist/android-x86.jar index 5c24529963..b535a29269 100644 Binary files a/dist/android-x86.jar and b/dist/android-x86.jar differ diff --git a/dist/darwin-aarch64.jar b/dist/darwin-aarch64.jar index ee47153a2b..6aae8d2303 100644 Binary files a/dist/darwin-aarch64.jar and b/dist/darwin-aarch64.jar differ diff --git a/dist/darwin-x86-64.jar b/dist/darwin-x86-64.jar index 7ba4c7e015..46ca9c0a3e 100644 Binary files a/dist/darwin-x86-64.jar and b/dist/darwin-x86-64.jar differ diff --git a/dist/doc.zip b/dist/doc.zip index c0b1e1db67..59c408ff40 100644 Binary files a/dist/doc.zip and b/dist/doc.zip differ diff --git a/dist/dragonflybsd-x86-64.jar b/dist/dragonflybsd-x86-64.jar new file mode 100644 index 0000000000..75a6adbc0c Binary files /dev/null and b/dist/dragonflybsd-x86-64.jar differ diff --git a/dist/freebsd-aarch64.jar b/dist/freebsd-aarch64.jar new file mode 100644 index 0000000000..d863968141 Binary files /dev/null and b/dist/freebsd-aarch64.jar differ diff --git a/dist/freebsd-ppc64.jar b/dist/freebsd-ppc64.jar new file mode 100644 index 0000000000..6716399ab6 Binary files /dev/null and b/dist/freebsd-ppc64.jar differ diff --git a/dist/freebsd-ppc64le.jar b/dist/freebsd-ppc64le.jar new file mode 100644 index 0000000000..6716399ab6 Binary files /dev/null and b/dist/freebsd-ppc64le.jar differ diff --git a/dist/freebsd-x86-64.jar b/dist/freebsd-x86-64.jar index a76b1d0666..769191b3b7 100644 Binary files a/dist/freebsd-x86-64.jar and b/dist/freebsd-x86-64.jar differ diff --git a/dist/freebsd-x86.jar b/dist/freebsd-x86.jar index 3566f8ad79..46563688d2 100644 Binary files a/dist/freebsd-x86.jar and b/dist/freebsd-x86.jar differ diff --git a/dist/jna-jpms.jar b/dist/jna-jpms.jar index b832449ca0..5df007e7dc 100644 Binary files a/dist/jna-jpms.jar and b/dist/jna-jpms.jar differ diff --git a/dist/jna-min.jar b/dist/jna-min.jar index 1a45510170..0a010d05a4 100644 Binary files a/dist/jna-min.jar and b/dist/jna-min.jar differ diff --git a/dist/jna-platform-jpms.jar b/dist/jna-platform-jpms.jar index 0a4406c9aa..360db0f071 100644 Binary files a/dist/jna-platform-jpms.jar and b/dist/jna-platform-jpms.jar differ diff --git a/dist/jna-platform.jar b/dist/jna-platform.jar index 816a567ccc..deee8da31d 100644 Binary files a/dist/jna-platform.jar and b/dist/jna-platform.jar differ diff --git a/dist/jna.aar b/dist/jna.aar index 210183a14d..d8bc589b7e 100644 Binary files a/dist/jna.aar and b/dist/jna.aar differ diff --git a/dist/jna.jar b/dist/jna.jar index 3d49c81881..7b920a8beb 100644 Binary files a/dist/jna.jar and b/dist/jna.jar differ diff --git a/dist/jnacontrib/demo-alphamask.jar b/dist/jnacontrib/demo-alphamask.jar index 941ab74ec2..9ed48f947c 100644 Binary files a/dist/jnacontrib/demo-alphamask.jar and b/dist/jnacontrib/demo-alphamask.jar differ diff --git a/dist/jnacontrib/demo-balloonmanager.jar b/dist/jnacontrib/demo-balloonmanager.jar index 34b3c361ad..46d95eabff 100644 Binary files a/dist/jnacontrib/demo-balloonmanager.jar and b/dist/jnacontrib/demo-balloonmanager.jar differ diff --git a/dist/jnacontrib/demo-balloontips.jar b/dist/jnacontrib/demo-balloontips.jar index 62ae49387c..ca80da4c78 100644 Binary files a/dist/jnacontrib/demo-balloontips.jar and b/dist/jnacontrib/demo-balloontips.jar differ diff --git a/dist/jnacontrib/demo-dnd.jar b/dist/jnacontrib/demo-dnd.jar index ea451ab9f8..4231bb744c 100644 Binary files a/dist/jnacontrib/demo-dnd.jar and b/dist/jnacontrib/demo-dnd.jar differ diff --git a/dist/jnacontrib/demo-monitordemo.jar b/dist/jnacontrib/demo-monitordemo.jar index 8378588f97..d09c6c7f24 100644 Binary files a/dist/jnacontrib/demo-monitordemo.jar and b/dist/jnacontrib/demo-monitordemo.jar differ diff --git a/dist/jnacontrib/demo-msoffice.jar b/dist/jnacontrib/demo-msoffice.jar index 596d9ade7e..db33f368dc 100644 Binary files a/dist/jnacontrib/demo-msoffice.jar and b/dist/jnacontrib/demo-msoffice.jar differ diff --git a/dist/jnacontrib/demo-nativewindowmsg.jar b/dist/jnacontrib/demo-nativewindowmsg.jar index 19564b2547..c39a633682 100644 Binary files a/dist/jnacontrib/demo-nativewindowmsg.jar and b/dist/jnacontrib/demo-nativewindowmsg.jar differ diff --git a/dist/jnacontrib/demo-shapedwindow.jar b/dist/jnacontrib/demo-shapedwindow.jar index 49358a8ad1..2f8f4e82d2 100644 Binary files a/dist/jnacontrib/demo-shapedwindow.jar and b/dist/jnacontrib/demo-shapedwindow.jar differ diff --git a/dist/jnacontrib/demo-w32printing.jar b/dist/jnacontrib/demo-w32printing.jar index e81eedd0a0..aec8550ac9 100644 Binary files a/dist/jnacontrib/demo-w32printing.jar and b/dist/jnacontrib/demo-w32printing.jar differ diff --git a/dist/jnacontrib/demo-w32windowhooks.jar b/dist/jnacontrib/demo-w32windowhooks.jar index d57387bbcb..2a414e378f 100644 Binary files a/dist/jnacontrib/demo-w32windowhooks.jar and b/dist/jnacontrib/demo-w32windowhooks.jar differ diff --git a/dist/jnacontrib/demo-x11.jar b/dist/jnacontrib/demo-x11.jar index 9fd82c69d4..566cd3e366 100644 Binary files a/dist/jnacontrib/demo-x11.jar and b/dist/jnacontrib/demo-x11.jar differ diff --git a/dist/linux-aarch64.jar b/dist/linux-aarch64.jar index cb9b710d4f..c8ce19c087 100644 Binary files a/dist/linux-aarch64.jar and b/dist/linux-aarch64.jar differ diff --git a/dist/linux-arm.jar b/dist/linux-arm.jar index e6a2d70033..216e015244 100644 Binary files a/dist/linux-arm.jar and b/dist/linux-arm.jar differ diff --git a/dist/linux-armel.jar b/dist/linux-armel.jar index 03645a2aff..be85543293 100644 Binary files a/dist/linux-armel.jar and b/dist/linux-armel.jar differ diff --git a/dist/linux-loongarch64.jar b/dist/linux-loongarch64.jar index 45f36fb8b2..c627ff6f13 100644 Binary files a/dist/linux-loongarch64.jar and b/dist/linux-loongarch64.jar differ diff --git a/dist/linux-mips64el.jar b/dist/linux-mips64el.jar index b2b9324a54..d6098a65dd 100644 Binary files a/dist/linux-mips64el.jar and b/dist/linux-mips64el.jar differ diff --git a/dist/linux-ppc.jar b/dist/linux-ppc.jar index f67a1371d9..28a8042cd7 100644 Binary files a/dist/linux-ppc.jar and b/dist/linux-ppc.jar differ diff --git a/dist/linux-ppc64le.jar b/dist/linux-ppc64le.jar index 273363eacf..4d6a2d6679 100644 Binary files a/dist/linux-ppc64le.jar and b/dist/linux-ppc64le.jar differ diff --git a/dist/linux-riscv64.jar b/dist/linux-riscv64.jar index d142a94ab2..1acdb1994f 100644 Binary files a/dist/linux-riscv64.jar and b/dist/linux-riscv64.jar differ diff --git a/dist/linux-s390x.jar b/dist/linux-s390x.jar index bce7b3ef62..bb049c0af4 100644 Binary files a/dist/linux-s390x.jar and b/dist/linux-s390x.jar differ diff --git a/dist/linux-x86-64.jar b/dist/linux-x86-64.jar index a1a5ed51aa..d659f63ac1 100644 Binary files a/dist/linux-x86-64.jar and b/dist/linux-x86-64.jar differ diff --git a/dist/linux-x86.jar b/dist/linux-x86.jar index 668f4887d7..e4b7ac14f2 100644 Binary files a/dist/linux-x86.jar and b/dist/linux-x86.jar differ diff --git a/dist/openbsd-x86-64.jar b/dist/openbsd-x86-64.jar index 2dc7f1c741..67a905ba36 100644 Binary files a/dist/openbsd-x86-64.jar and b/dist/openbsd-x86-64.jar differ diff --git a/dist/openbsd-x86.jar b/dist/openbsd-x86.jar index 25015ec32f..5082e73dd9 100644 Binary files a/dist/openbsd-x86.jar and b/dist/openbsd-x86.jar differ diff --git a/dist/src-full.zip b/dist/src-full.zip index e7d93630ee..258c75d7bf 100644 Binary files a/dist/src-full.zip and b/dist/src-full.zip differ diff --git a/dist/src.zip b/dist/src.zip index 7e06c5111f..3fa1d0d4dc 100644 Binary files a/dist/src.zip and b/dist/src.zip differ diff --git a/dist/sunos-sparc.jar b/dist/sunos-sparc.jar index d2424561b8..0ee42c41e1 100644 Binary files a/dist/sunos-sparc.jar and b/dist/sunos-sparc.jar differ diff --git a/dist/sunos-sparcv9.jar b/dist/sunos-sparcv9.jar index 9c4d5cdfab..960b7a5e5f 100644 Binary files a/dist/sunos-sparcv9.jar and b/dist/sunos-sparcv9.jar differ diff --git a/dist/sunos-x86-64.jar b/dist/sunos-x86-64.jar index 34c99261c9..c320a9f8ca 100644 Binary files a/dist/sunos-x86-64.jar and b/dist/sunos-x86-64.jar differ diff --git a/dist/sunos-x86.jar b/dist/sunos-x86.jar index de97018ccd..40b902412f 100644 Binary files a/dist/sunos-x86.jar and b/dist/sunos-x86.jar differ diff --git a/dist/win32-aarch64.jar b/dist/win32-aarch64.jar index da00be995c..776476ef4e 100644 Binary files a/dist/win32-aarch64.jar and b/dist/win32-aarch64.jar differ diff --git a/dist/win32-x86-64.jar b/dist/win32-x86-64.jar index c60497f050..f684cc150e 100644 Binary files a/dist/win32-x86-64.jar and b/dist/win32-x86-64.jar differ diff --git a/dist/win32-x86.jar b/dist/win32-x86.jar index 3dc3c4529a..45d7274509 100644 Binary files a/dist/win32-x86.jar and b/dist/win32-x86.jar differ diff --git a/lib/animal-sniffer-ant-tasks-1.17.jar b/lib/animal-sniffer-ant-tasks-1.17.jar deleted file mode 100644 index 06e7d7d8b8..0000000000 Binary files a/lib/animal-sniffer-ant-tasks-1.17.jar and /dev/null differ diff --git a/lib/maven-ant-tasks-2.1.3.jar b/lib/maven-ant-tasks-2.1.3.jar deleted file mode 100644 index bec446fff5..0000000000 Binary files a/lib/maven-ant-tasks-2.1.3.jar and /dev/null differ diff --git a/lib/native/aix-ppc.jar b/lib/native/aix-ppc.jar index 5dbaeafba6..b276542d2c 100644 Binary files a/lib/native/aix-ppc.jar and b/lib/native/aix-ppc.jar differ diff --git a/lib/native/aix-ppc64.jar b/lib/native/aix-ppc64.jar index 08c16e7e56..c8d1cbacf2 100644 Binary files a/lib/native/aix-ppc64.jar and b/lib/native/aix-ppc64.jar differ diff --git a/lib/native/android-aarch64.jar b/lib/native/android-aarch64.jar index 3e5e03a5f5..3355b63c87 100644 Binary files a/lib/native/android-aarch64.jar and b/lib/native/android-aarch64.jar differ diff --git a/lib/native/android-arm.jar b/lib/native/android-arm.jar index 1252debd52..aa53b982d4 100644 Binary files a/lib/native/android-arm.jar and b/lib/native/android-arm.jar differ diff --git a/lib/native/android-armv7.jar b/lib/native/android-armv7.jar index 132521d1eb..ee41cbafdc 100644 Binary files a/lib/native/android-armv7.jar and b/lib/native/android-armv7.jar differ diff --git a/lib/native/android-mips.jar b/lib/native/android-mips.jar index af584cde11..49ecc391a3 100644 Binary files a/lib/native/android-mips.jar and b/lib/native/android-mips.jar differ diff --git a/lib/native/android-mips64.jar b/lib/native/android-mips64.jar index 3c72497d02..8b7cde1d89 100644 Binary files a/lib/native/android-mips64.jar and b/lib/native/android-mips64.jar differ diff --git a/lib/native/android-x86-64.jar b/lib/native/android-x86-64.jar index fbed760bce..4b5dc2294d 100644 Binary files a/lib/native/android-x86-64.jar and b/lib/native/android-x86-64.jar differ diff --git a/lib/native/android-x86.jar b/lib/native/android-x86.jar index 5c24529963..b535a29269 100644 Binary files a/lib/native/android-x86.jar and b/lib/native/android-x86.jar differ diff --git a/lib/native/darwin-aarch64.jar b/lib/native/darwin-aarch64.jar index ee47153a2b..6aae8d2303 100644 Binary files a/lib/native/darwin-aarch64.jar and b/lib/native/darwin-aarch64.jar differ diff --git a/lib/native/darwin-x86-64.jar b/lib/native/darwin-x86-64.jar index 7ba4c7e015..46ca9c0a3e 100644 Binary files a/lib/native/darwin-x86-64.jar and b/lib/native/darwin-x86-64.jar differ diff --git a/lib/native/dragonflybsd-x86-64.jar b/lib/native/dragonflybsd-x86-64.jar new file mode 100644 index 0000000000..75a6adbc0c Binary files /dev/null and b/lib/native/dragonflybsd-x86-64.jar differ diff --git a/lib/native/freebsd-aarch64.jar b/lib/native/freebsd-aarch64.jar new file mode 100644 index 0000000000..d863968141 Binary files /dev/null and b/lib/native/freebsd-aarch64.jar differ diff --git a/lib/native/freebsd-ppc64.jar b/lib/native/freebsd-ppc64.jar new file mode 100644 index 0000000000..6716399ab6 Binary files /dev/null and b/lib/native/freebsd-ppc64.jar differ diff --git a/lib/native/freebsd-ppc64le.jar b/lib/native/freebsd-ppc64le.jar new file mode 100644 index 0000000000..6716399ab6 Binary files /dev/null and b/lib/native/freebsd-ppc64le.jar differ diff --git a/lib/native/freebsd-x86-64.jar b/lib/native/freebsd-x86-64.jar index a76b1d0666..769191b3b7 100644 Binary files a/lib/native/freebsd-x86-64.jar and b/lib/native/freebsd-x86-64.jar differ diff --git a/lib/native/freebsd-x86.jar b/lib/native/freebsd-x86.jar index 3566f8ad79..46563688d2 100644 Binary files a/lib/native/freebsd-x86.jar and b/lib/native/freebsd-x86.jar differ diff --git a/lib/native/linux-aarch64.jar b/lib/native/linux-aarch64.jar index cb9b710d4f..c8ce19c087 100644 Binary files a/lib/native/linux-aarch64.jar and b/lib/native/linux-aarch64.jar differ diff --git a/lib/native/linux-arm.jar b/lib/native/linux-arm.jar index e6a2d70033..216e015244 100644 Binary files a/lib/native/linux-arm.jar and b/lib/native/linux-arm.jar differ diff --git a/lib/native/linux-armel.jar b/lib/native/linux-armel.jar index 03645a2aff..be85543293 100644 Binary files a/lib/native/linux-armel.jar and b/lib/native/linux-armel.jar differ diff --git a/lib/native/linux-loongarch64.jar b/lib/native/linux-loongarch64.jar index 45f36fb8b2..c627ff6f13 100644 Binary files a/lib/native/linux-loongarch64.jar and b/lib/native/linux-loongarch64.jar differ diff --git a/lib/native/linux-mips64el.jar b/lib/native/linux-mips64el.jar index b2b9324a54..d6098a65dd 100644 Binary files a/lib/native/linux-mips64el.jar and b/lib/native/linux-mips64el.jar differ diff --git a/lib/native/linux-ppc.jar b/lib/native/linux-ppc.jar index f67a1371d9..28a8042cd7 100644 Binary files a/lib/native/linux-ppc.jar and b/lib/native/linux-ppc.jar differ diff --git a/lib/native/linux-ppc64le.jar b/lib/native/linux-ppc64le.jar index 273363eacf..4d6a2d6679 100644 Binary files a/lib/native/linux-ppc64le.jar and b/lib/native/linux-ppc64le.jar differ diff --git a/lib/native/linux-riscv64.jar b/lib/native/linux-riscv64.jar index d142a94ab2..1acdb1994f 100644 Binary files a/lib/native/linux-riscv64.jar and b/lib/native/linux-riscv64.jar differ diff --git a/lib/native/linux-s390x.jar b/lib/native/linux-s390x.jar index bce7b3ef62..bb049c0af4 100644 Binary files a/lib/native/linux-s390x.jar and b/lib/native/linux-s390x.jar differ diff --git a/lib/native/linux-x86-64.jar b/lib/native/linux-x86-64.jar index a1a5ed51aa..d659f63ac1 100644 Binary files a/lib/native/linux-x86-64.jar and b/lib/native/linux-x86-64.jar differ diff --git a/lib/native/linux-x86.jar b/lib/native/linux-x86.jar index 668f4887d7..e4b7ac14f2 100644 Binary files a/lib/native/linux-x86.jar and b/lib/native/linux-x86.jar differ diff --git a/lib/native/openbsd-x86-64.jar b/lib/native/openbsd-x86-64.jar index 2dc7f1c741..67a905ba36 100644 Binary files a/lib/native/openbsd-x86-64.jar and b/lib/native/openbsd-x86-64.jar differ diff --git a/lib/native/openbsd-x86.jar b/lib/native/openbsd-x86.jar index 25015ec32f..5082e73dd9 100644 Binary files a/lib/native/openbsd-x86.jar and b/lib/native/openbsd-x86.jar differ diff --git a/lib/native/sunos-sparc.jar b/lib/native/sunos-sparc.jar index d2424561b8..0ee42c41e1 100644 Binary files a/lib/native/sunos-sparc.jar and b/lib/native/sunos-sparc.jar differ diff --git a/lib/native/sunos-sparcv9.jar b/lib/native/sunos-sparcv9.jar index 9c4d5cdfab..960b7a5e5f 100644 Binary files a/lib/native/sunos-sparcv9.jar and b/lib/native/sunos-sparcv9.jar differ diff --git a/lib/native/sunos-x86-64.jar b/lib/native/sunos-x86-64.jar index 34c99261c9..c320a9f8ca 100644 Binary files a/lib/native/sunos-x86-64.jar and b/lib/native/sunos-x86-64.jar differ diff --git a/lib/native/sunos-x86.jar b/lib/native/sunos-x86.jar index de97018ccd..40b902412f 100644 Binary files a/lib/native/sunos-x86.jar and b/lib/native/sunos-x86.jar differ diff --git a/lib/native/win32-aarch64.jar b/lib/native/win32-aarch64.jar index da00be995c..776476ef4e 100644 Binary files a/lib/native/win32-aarch64.jar and b/lib/native/win32-aarch64.jar differ diff --git a/lib/native/win32-x86-64.jar b/lib/native/win32-x86-64.jar index c60497f050..f684cc150e 100644 Binary files a/lib/native/win32-x86-64.jar and b/lib/native/win32-x86-64.jar differ diff --git a/lib/native/win32-x86.jar b/lib/native/win32-x86.jar index 3dc3c4529a..45d7274509 100644 Binary files a/lib/native/win32-x86.jar and b/lib/native/win32-x86.jar differ diff --git a/native/Makefile b/native/Makefile index 98bf357d8e..4bce56b606 100644 --- a/native/Makefile +++ b/native/Makefile @@ -15,7 +15,9 @@ # Linux (i386/amd64/ppc/arm) # Solaris (i386/amd64/sparc/sparcv9) # AIX (ppc/ppc64) -# FreeBSD/OpenBSD/NetBSD (i386/amd64) +# DragonFly (x86-64) +# FreeBSD (i386/amd64/aarch64) +# OpenBSD/NetBSD (i386/amd64) # Android (arm/armv7/aarch64/x86/x86-64/mipsel/mips64el) # # Built, but with outstanding bugs (not necessarily within JNA): @@ -45,6 +47,7 @@ OS=$(shell uname | sed -e 's/CYGWIN.*/win32/g' \ -e 's/NetBSD/netbsd/g' \ -e 's/GNU\/kFreeBSD/kfreebsd/g' \ -e 's/FreeBSD/freebsd/g' \ + -e 's/DragonFly/dragonfly/g' \ -e 's/OpenBSD/openbsd/g' \ -e 's/Darwin.*/darwin/g' \ -e 's/AIX.*/aix/g' \ @@ -86,6 +89,7 @@ LD=$(CC) LIBS= # Default to Sun recommendations for JNI compilation COPT=-O2 -fno-omit-frame-pointer -fno-strict-aliasing +COPT+=-Wno-implicit-function-declaration CASM=-S ifeq ($(DEBUG),true) CDEBUG=-g @@ -172,12 +176,12 @@ CPP=$(PREFIX)cpp LD=$(CC) RANLIB=$(PREFIX)ranlib STRIP=$(PREFIX)strip -x -CDEFINES=-DFFI_STATIC_BUILD -DNO_JAWT -DNO_WEAK_GLOBALS -DFFI_MMAP_EXEC_WRIT=1 -DFFI_MMAP_EXEC_SELINUX=0 +CDEFINES=-DFFI_STATIC_BUILD -DNO_JAWT -DNO_WEAK_GLOBALS -DFFI_MMAP_EXEC_WRIT=1 -DFFI_MMAP_EXEC_SELINUX=0 -Dmalloc_getpagesize='getpagesize()' COPT+=-fpic -ffunction-sections -funwind-tables -fno-short-enums JAVA_INCLUDES= CINCLUDES+=-I"$(NDK_PLATFORM)/arch-$(AARCH)/usr/include" # -I/usr/include LIBS=-nostdlib -L"$(NDK_PLATFORM)/arch-$(AARCH)$(ALIBDIR)/" -lgcc -lc -ldl -lm -LDFLAGS+=-Wl,-shared,-Bsymbolic +LDFLAGS+=-Wl,-shared,-Bsymbolic -Wl,--build-id=sha1 -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384 FFI_ENV=CPP="$(CPP)" CC="$(CC)" CFLAGS="$(COPT) $(CDEBUG) $(CINCLUDES)" CPPFLAGS="$(CDEFINES) $(CINCLUDES)" LIBS="$(LIBS)" RANLIB="$(RANLIB)" FFI_CONFIG=--enable-static --disable-shared --with-pic=yes --host=$(HOST) endif @@ -288,10 +292,14 @@ LDFLAGS+=-Wl,-soname,$@,-Bsymbolic endif endif -ifneq (,$(findstring bsd,$(OS))) +ifneq (,$(or $(findstring bsd,$(OS)),$(findstring dragonfly,$(OS)))) ARCH=$(shell uname -m | sed 's/i.86/i386/g') PCFLAGS+=-fPIC -CINCLUDES+=-I/usr/X11R6/include +# This is a mess: X11 headers locate in /usr/local/include on FreeBSD and +# DragonFly, in /usr/X11R7/include on NetBSD, and in /usr/X11R6/include on +# OpenBSD. +CINCLUDES+=-I/usr/local/include -I/usr/X11R7/include -I/usr/X11R6/include +CINCLUDES+=$(X11INC) # Allow extra X11 include path if necessary. LDFLAGS=-o $@ -shared CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT -DUSE_DEAFULT_LIBNAME_ENCODING endif diff --git a/native/build.xml b/native/build.xml index 5b6c7101fb..7a2745727b 100644 --- a/native/build.xml +++ b/native/build.xml @@ -23,6 +23,9 @@ + + + @@ -347,6 +350,7 @@ + diff --git a/native/callback.c b/native/callback.c index 99a9e831a3..7872693315 100644 --- a/native/callback.c +++ b/native/callback.c @@ -133,19 +133,19 @@ create_callback(JNIEnv* env, jobject obj, jobject method, } argc = (*env)->GetArrayLength(env, arg_classes); - cb = (callback *)malloc(sizeof(callback)); + cb = (callback *)calloc(1, sizeof(callback)); cb->closure = ffi_closure_alloc(sizeof(ffi_closure), &cb->x_closure); cb->saved_x_closure = cb->x_closure; cb->object = (*env)->NewWeakGlobalRef(env, obj); cb->methodID = (*env)->FromReflectedMethod(env, method); cb->vm = vm; - cb->arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * argc); - cb->java_arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * (argc + 3)); - cb->arg_jtypes = (char*)malloc(sizeof(char) * argc); - cb->conversion_flags = (int *)malloc(sizeof(int) * argc); + cb->arg_types = (ffi_type**)calloc(argc, sizeof(ffi_type*)); + cb->java_arg_types = (ffi_type**)calloc(argc + 3, sizeof(ffi_type*)); + cb->arg_jtypes = (char*)calloc(argc, sizeof(char)); + cb->conversion_flags = (int *)calloc(argc, sizeof(int)); cb->rflag = CVT_DEFAULT; - cb->arg_classes = (jobject*)malloc(sizeof(jobject) * argc); + cb->arg_classes = (jobject*)calloc(argc, sizeof(jobject)); cb->direct = direct; cb->java_arg_types[0] = cb->java_arg_types[1] = cb->java_arg_types[2] = &ffi_type_pointer; @@ -154,7 +154,7 @@ create_callback(JNIEnv* env, jobject obj, jobject method, for (i=0;i < argc;i++) { int jtype; jclass cls = (*env)->GetObjectArrayElement(env, arg_classes, i); - if ((cb->conversion_flags[i] = get_conversion_flag(env, cls)) != CVT_DEFAULT) { + if (direct && ((cb->conversion_flags[i] = get_conversion_flag(env, cls)) != CVT_DEFAULT)) { cb->arg_classes[i] = (*env)->NewWeakGlobalRef(env, cls); cvt = 1; } @@ -163,6 +163,9 @@ create_callback(JNIEnv* env, jobject obj, jobject method, } jtype = get_java_type(env, cls); + if((*env)->ExceptionCheck(env)) { + goto failure_cleanup; + } if (jtype == -1) { snprintf(msg, sizeof(msg), "Unsupported callback argument at index %d", i); throw_type = EIllegalArgument; @@ -179,7 +182,13 @@ create_callback(JNIEnv* env, jobject obj, jobject method, || cb->conversion_flags[i] == CVT_INTEGER_TYPE) { jclass ncls; ncls = getNativeType(env, cls); + if((*env)->ExceptionCheck(env)) { + goto failure_cleanup; + } jtype = get_java_type(env, ncls); + if((*env)->ExceptionCheck(env)) { + goto failure_cleanup; + } if (jtype == -1) { snprintf(msg, sizeof(msg), "Unsupported NativeMapped callback argument native type at argument %d", i); throw_type = EIllegalArgument; @@ -560,7 +569,7 @@ static TLS_KEY_T tls_thread_data_key; static thread_storage* get_thread_storage(JNIEnv* env) { thread_storage* tls = (thread_storage *)TLS_GET(tls_thread_data_key); if (tls == NULL) { - tls = (thread_storage*)malloc(sizeof(thread_storage)); + tls = (thread_storage*)calloc(1, sizeof(thread_storage)); if (!tls) { throwByName(env, EOutOfMemory, "JNA: Can't allocate thread storage"); } diff --git a/native/dispatch.c b/native/dispatch.c index c662725383..8a03a643b9 100644 --- a/native/dispatch.c +++ b/native/dispatch.c @@ -71,7 +71,7 @@ #define DEFAULT_LOAD_OPTS (RTLD_LAZY|RTLD_GLOBAL) #define LOAD_LIBRARY(NAME,OPTS) dlopen(NAME, OPTS) static inline char * LOAD_ERROR() { - char* message = dlerror(); + const char* message = dlerror(); char* buf = (char*) malloc(strlen(message) + 1 /* null */); strcpy(buf, message); return buf; @@ -144,9 +144,10 @@ extern "C" { PSTART(); memset(D,C,L); PEND(ENV); \ } while(0) -#define MASK_CC com_sun_jna_Function_MASK_CC -#define THROW_LAST_ERROR com_sun_jna_Function_THROW_LAST_ERROR -#define USE_VARARGS com_sun_jna_Function_USE_VARARGS +#define MASK_CC com_sun_jna_Function_MASK_CC +#define THROW_LAST_ERROR com_sun_jna_Function_THROW_LAST_ERROR +#define USE_VARARGS com_sun_jna_Function_USE_VARARGS +#define USE_VARARGS_SHIFT com_sun_jna_Function_USE_VARARGS_SHIFT /* Cached class, field and method IDs */ static jclass classObject; @@ -480,7 +481,7 @@ dispatch(JNIEnv *env, void* func, jint flags, jobjectArray args, callconv_t callconv = flags & MASK_CC; const char* volatile throw_type = NULL; const char* volatile throw_msg = NULL; - int fixed_args = (flags & USE_VARARGS) >> 7; + int fixed_args = (flags >> USE_VARARGS_SHIFT) & USE_VARARGS; nargs = (*env)->GetArrayLength(env, args); @@ -3496,7 +3497,7 @@ Java_com_sun_jna_Native_registerMethod(JNIEnv *env, jclass UNUSED(ncls), const char* sig = newCStringUTF8(env, signature); void *code; void *closure; - method_data* data = malloc(sizeof(method_data)); + method_data* data = calloc(1, sizeof(method_data)); ffi_cif* closure_cif = &data->closure_cif; int status; int i; @@ -3518,12 +3519,12 @@ Java_com_sun_jna_Native_registerMethod(JNIEnv *env, jclass UNUSED(ncls), } data->throw_last_error = throw_last_error; - data->arg_types = malloc(sizeof(ffi_type*) * argc); - data->closure_arg_types = malloc(sizeof(ffi_type*) * (argc + 2)); + data->arg_types = calloc(argc, sizeof(ffi_type*)); + data->closure_arg_types = calloc(argc + 2, sizeof(ffi_type*)); data->closure_arg_types[0] = &ffi_type_pointer; data->closure_arg_types[1] = &ffi_type_pointer; data->closure_method = NULL; - data->flags = cvts ? malloc(sizeof(jint)*argc) : NULL; + data->flags = cvts ? calloc(argc, sizeof(jint)) : NULL; data->rflag = rconversion; data->to_native = NULL; data->from_native = from_native ? (*env)->NewWeakGlobalRef(env, from_native) : NULL; @@ -3611,7 +3612,7 @@ Java_com_sun_jna_Native_ffi_1prep_1cif(JNIEnv *env, jclass UNUSED(cls), jint abi JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_ffi_1prep_1closure(JNIEnv *env, jclass UNUSED(cls), jlong cif, jobject obj) { - callback* cb = (callback *)malloc(sizeof(callback)); + callback* cb = (callback *)calloc(1, sizeof(callback)); ffi_status s; if ((*env)->GetJavaVM(env, &cb->vm) != JNI_OK) { diff --git a/native/testlib.c b/native/testlib.c index d438ffd750..b7a41233c4 100644 --- a/native/testlib.c +++ b/native/testlib.c @@ -31,6 +31,8 @@ extern "C" { #include #include #include +#include + #if !defined(_WIN32_WCE) #include #endif @@ -906,6 +908,20 @@ addVarArgs(const char *fmt, ...) { return sum; } +EXPORT int32_t +addSeveralFixedArgsAndVarArgs(int a, int b, int c, int d, int n_varargs, ...) { + va_list ap; + int i; + int32_t sum = a + b + c + d; + va_start(ap, n_varargs); + + for (i = 0; i < n_varargs; i++) { + sum += va_arg(ap, int32_t); + } + va_end(ap); + return sum; +} + EXPORT void modifyStructureVarArgs(const char* fmt, ...) { struct _ss { @@ -1078,6 +1094,36 @@ returnLastElementOfComponentsDSDAL(DemoStructureDifferentArrayLengths ts, int de return result; } +/** + * Copy the input char array to the output char array. The caller is responsible + * to allocate a correctly sized buffer. + */ +EXPORT size_t copyString(char* input, char* output) { + size_t len = strlen(input) + 1; + memcpy(output, input, len); + return len; +} + +/** + * Copy the input array of char arrays to the output char array. The caller is + * responsible to allocate a correctly sized buffer. + */ +EXPORT size_t copyStringArray(char** input, char* output) { + int i; + size_t len = 0; + for(i = 0;; i++) { + char* currInput = input[i]; + if(currInput == NULL) { + break; + } + size_t localLen = strlen(currInput) + 1; + memcpy(output, currInput, localLen); + output += localLen; + len += localLen; + } + return len; +} + #ifdef __cplusplus } #endif diff --git a/nbproject/ide-file-targets.xml b/nbproject/ide-file-targets.xml index 149419762a..4d439b0c36 100644 --- a/nbproject/ide-file-targets.xml +++ b/nbproject/ide-file-targets.xml @@ -62,4 +62,32 @@ + + + Must set property 'tests.include.fullpath' + + + + test.includes: ${tests.include} + + + + + + + + Must set property 'tests.include.fullpath' + + + + test.includes: ${tests.include} + + + + + + + + + diff --git a/nbproject/project.xml b/nbproject/project.xml index c05eefc132..e284dbe752 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -41,6 +41,7 @@ auxiliary.show.customizer.message= + compile-tests jar @@ -54,6 +55,7 @@ auxiliary.show.customizer.message= clean + compile-tests jar @@ -108,6 +110,32 @@ auxiliary.show.customizer.message= + + + test-single + + tests.include.fullpath + test + \.java$ + absolute-path + + + + + + + + debug-test-single + + tests.include.fullpath + test + \.java$ + absolute-path + + + + + @@ -141,7 +169,7 @@ auxiliary.show.customizer.message= src src - 1.6 + 1.8 test @@ -152,7 +180,7 @@ auxiliary.show.customizer.message= ant-tools-src src:lib/ant.jar:lib/asm-8.0.1.jar - 1.6 + 1.8 diff --git a/src/com/sun/jna/CallbackReference.java b/src/com/sun/jna/CallbackReference.java index 6639300c95..9533fb715c 100644 --- a/src/com/sun/jna/CallbackReference.java +++ b/src/com/sun/jna/CallbackReference.java @@ -53,16 +53,16 @@ public class CallbackReference extends WeakReference implements Closea // Access to callbackMap, directCallbackMap, pointerCallbackMap is protected // by synchonizing on pointerCallbackMap - static final Map callbackMap = new WeakHashMap(); - static final Map directCallbackMap = new WeakHashMap(); + static final Map callbackMap = new WeakHashMap<>(); + static final Map directCallbackMap = new WeakHashMap<>(); //callbacks with different signatures sharing the same pointer - static final Map[]> pointerCallbackMap = new WeakHashMap[]>(); + static final Map[]> pointerCallbackMap = new WeakHashMap<>(); // Track memory allocations associated with this closure (usually String args) static final Map allocations = - Collections.synchronizedMap(new WeakHashMap()); + Collections.synchronizedMap(new WeakHashMap<>()); // Global map of allocated closures to facilitate centralized cleanup private static final Map> allocatedMemory = - new ConcurrentHashMap>(); + new ConcurrentHashMap<>(); private static final Method PROXY_CALLBACK_METHOD; static { @@ -87,7 +87,7 @@ public class CallbackReference extends WeakReference implements Closea } } - private static final Map initializers = new WeakHashMap(); + private static final Map initializers = new WeakHashMap<>(); /** * @param cb The {@link Callback} instance * @param initializer The {@link CallbackThreadInitializer} - if {@code null} then the @@ -211,14 +211,14 @@ private static Reference[] addCallbackToArray(Callback cb,Reference(cb); + newArray[nidx] = new WeakReference<>(cb); return newArray; } private static Callback createCallback(Class type, Pointer p) { int ctype = AltCallingConvention.class.isAssignableFrom(type) ? Function.ALT_CONVENTION : Function.C_CONVENTION; - Map foptions = new HashMap(Native.getLibraryOptions(type)); + Map foptions = new HashMap<>(Native.getLibraryOptions(type)); foptions.put(Function.OPTION_INVOKING_METHOD, getCallbackMethod(type)); NativeFunctionHandler h = new NativeFunctionHandler(p, ctype, foptions); return (Callback)Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, h); @@ -330,7 +330,7 @@ private CallbackReference(Callback callback, int callingConvention, boolean dire } cbstruct = peer != 0 ? new Pointer(peer) : null; if(peer != 0) { - allocatedMemory.put(peer, new WeakReference(this)); + allocatedMemory.put(peer, new WeakReference<>(this)); cleanable = Cleaner.getCleaner().register(this, new CallbackReferenceDisposer(cbstruct)); } } @@ -401,7 +401,7 @@ private static Method getCallbackMethod(Class cls) { // Look at only public methods defined by the Callback class Method[] pubMethods = cls.getDeclaredMethods(); Method[] classMethods = cls.getMethods(); - Set pmethods = new HashSet(Arrays.asList(pubMethods)); + Set pmethods = new HashSet<>(Arrays.asList(pubMethods)); pmethods.retainAll(Arrays.asList(classMethods)); // Remove Object methods disallowed as callback method names @@ -456,7 +456,7 @@ protected void dispose() { /** Dispose of all memory allocated for callbacks. */ static void disposeAll() { // use a copy since dispose() modifes the map - Collection> refs = new LinkedList>(allocatedMemory.values()); + Collection> refs = new LinkedList<>(allocatedMemory.values()); for (Reference r : refs) { CallbackReference ref = r.get(); if(ref != null) { @@ -508,7 +508,7 @@ private static Pointer getFunctionPointer(Callback cb, boolean direct) { Map map = direct ? directCallbackMap : callbackMap; synchronized(pointerCallbackMap) { CallbackReference cbref = map.get(cb); - if (cbref == null) { + if (cbref == null || cbref.cbstruct == null) { cbref = new CallbackReference(cb, callingConvention, direct); map.put(cb, cbref); pointerCallbackMap.put(cbref.getTrampoline(), @@ -584,10 +584,7 @@ private Object invokeCallback(Object[] args) { try { result = convertResult(callbackMethod.invoke(cb, callbackArgs)); } - catch (IllegalArgumentException e) { - Native.getCallbackExceptionHandler().uncaughtException(cb, e); - } - catch (IllegalAccessException e) { + catch (IllegalArgumentException | IllegalAccessException e) { Native.getCallbackExceptionHandler().uncaughtException(cb, e); } catch (InvocationTargetException e) { diff --git a/src/com/sun/jna/DefaultTypeMapper.java b/src/com/sun/jna/DefaultTypeMapper.java index e0d41a01fd..5f1c9524c5 100644 --- a/src/com/sun/jna/DefaultTypeMapper.java +++ b/src/com/sun/jna/DefaultTypeMapper.java @@ -52,8 +52,8 @@ public Entry(Class type, Object converter) { } } - private List toNativeConverters = new ArrayList(); - private List fromNativeConverters = new ArrayList(); + private List toNativeConverters = new ArrayList<>(); + private List fromNativeConverters = new ArrayList<>(); private Class getAltClass(Class cls) { if (cls == Boolean.class) { diff --git a/src/com/sun/jna/ELFAnalyser.java b/src/com/sun/jna/ELFAnalyser.java index fc322ae098..d50f522626 100644 --- a/src/com/sun/jna/ELFAnalyser.java +++ b/src/com/sun/jna/ELFAnalyser.java @@ -62,6 +62,18 @@ class ELFAnalyser { private static final int EI_DATA_BIG_ENDIAN = 2; private static final int E_MACHINE_ARM = 0x28; private static final int EI_CLASS_64BIT = 2; + /** + * An undefined, missing, irrelevant, or otherwise meaningless section + * reference. For example, a symbol defined relative to section number + * SHN_UNDEF is an undefined symbol. + */ + private static final int SHN_UNDEF = 0; + /** + * An escape value indicating that the actual section header index is too + * large to fit in the containing field. The header section index is found + * in another location specific to the structure where it appears. + */ + private static final int SHN_XINDEX = 0xffff; public static ELFAnalyser analyse(String filename) throws IOException { ELFAnalyser res = new ELFAnalyser(filename); @@ -203,7 +215,7 @@ private void parseEabiAapcsVfp(ByteBuffer headerData, RandomAccessFile raf) thro for (ELFSectionHeaderEntry eshe : sectionHeaders.getEntries()) { if(".ARM.attributes".equals(eshe.getName())) { - ByteBuffer armAttributesBuffer = ByteBuffer.allocate(eshe.getSize()); + ByteBuffer armAttributesBuffer = ByteBuffer.allocate((int) eshe.getSize()); armAttributesBuffer.order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); raf.getChannel().read(armAttributesBuffer, eshe.getOffset()); armAttributesBuffer.rewind(); @@ -230,13 +242,14 @@ private void parseEabiAapcsVfp(ByteBuffer headerData, RandomAccessFile raf) thro } static class ELFSectionHeaders { - private final List entries = new ArrayList(); + private final List entries = new ArrayList<>(); public ELFSectionHeaders(boolean _64bit, boolean bigEndian, ByteBuffer headerData, RandomAccessFile raf) throws IOException { long shoff; int shentsize; int shnum; - short shstrndx; + int shstrndx; + int sectionCount; if (_64bit) { shoff = headerData.getLong(0x28); shentsize = headerData.getShort(0x3A); @@ -249,7 +262,27 @@ public ELFSectionHeaders(boolean _64bit, boolean bigEndian, ByteBuffer headerDat shstrndx = headerData.getShort(0x32); } - int tableLength = shnum * shentsize; + ByteBuffer sectionBuffer = ByteBuffer.allocate(shentsize); + raf.getChannel().read(sectionBuffer, shoff); + ELFSectionHeaderEntry section0 = new ELFSectionHeaderEntry(_64bit, sectionBuffer); + + if (shnum == 0 && shoff != 0) { + sectionCount = (int) section0.getSize(); + } else { + sectionCount = shnum; + } + + if (shstrndx == SHN_XINDEX) { + shstrndx = section0.getLink(); + } + + int tableLength = sectionCount * shentsize; + + if (tableLength == 0 || shstrndx == SHN_UNDEF) { + // There is either no section header table or no section name + // string table. + return; + } ByteBuffer data = ByteBuffer.allocate(tableLength); data.order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); @@ -264,7 +297,7 @@ public ELFSectionHeaders(boolean _64bit, boolean bigEndian, ByteBuffer headerDat } ELFSectionHeaderEntry stringTable = entries.get(shstrndx); - ByteBuffer stringBuffer = ByteBuffer.allocate(stringTable.getSize()); + ByteBuffer stringBuffer = ByteBuffer.allocate((int) stringTable.getSize()); stringBuffer.order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); raf.getChannel().read(stringBuffer, stringTable.getOffset()); stringBuffer.rewind(); @@ -297,16 +330,20 @@ static class ELFSectionHeaderEntry { private final int nameOffset; private String name; private final int type; - private final int flags; - private final int offset; - private final int size; + private final long flags; + private final long addr; + private final long offset; + private final long size; + private final int link; public ELFSectionHeaderEntry(boolean _64bit, ByteBuffer sectionHeaderData) { - this.nameOffset = sectionHeaderData.getInt(0x0); - this.type = sectionHeaderData.getInt(0x4); - this.flags = (int) (_64bit ? sectionHeaderData.getLong(0x8) : sectionHeaderData.getInt(0x8)); - this.offset = (int) (_64bit ? sectionHeaderData.getLong(0x18) : sectionHeaderData.getInt(0x10)); - this.size = (int) (_64bit ? sectionHeaderData.getLong(0x20) : sectionHeaderData.getInt(0x14)); + this.nameOffset = sectionHeaderData.getInt(0); + this.type = sectionHeaderData.getInt(4); + this.flags = _64bit ? sectionHeaderData.getLong(8) : sectionHeaderData.getInt(8); + this.addr = _64bit ? sectionHeaderData.getLong(16) : sectionHeaderData.getInt(12); + this.offset = _64bit ? sectionHeaderData.getLong(24) : sectionHeaderData.getInt(16); + this.size = _64bit ? sectionHeaderData.getLong(32) : sectionHeaderData.getInt(20); + this.link = sectionHeaderData.getInt(_64bit ? 40 : 24); } public String getName() { @@ -325,21 +362,46 @@ public int getType() { return type; } - public int getFlags() { + public long getFlags() { return flags; } - public int getOffset() { + public long getOffset() { return offset; } - public int getSize() { + public long getSize() { return size; } + public long getAddr() { + return addr; + } + + public int getLink() { + return link; + } + @Override public String toString() { - return "ELFSectionHeaderEntry{" + "nameIdx=" + nameOffset + ", name=" + name + ", type=" + type + ", flags=" + flags + ", offset=" + offset + ", size=" + size + '}'; + return String.format("ELFSectionHeaderEntry{" + + "nameOffset=%1$d (0x%1$x)" + + ", name=%2$s" + + ", type=%3$d (0x%3$x)" + + ", flags=%4$d (0x%4$x)" + + ", addr=%5$d (0x%5$x)" + + ", offset=%6$d (0x%6$x)" + + ", size=%7$d (0x%7$x)" + + ", link=%8$d (0x%8$x)}", + nameOffset, + name, + type, + flags, + addr, + offset, + size, + link + ); } } @@ -401,9 +463,9 @@ public boolean equals(Object obj) { return true; } - private static final List tags = new LinkedList(); - private static final Map valueMap = new HashMap(); - private static final Map nameMap = new HashMap(); + private static final List tags = new LinkedList<>(); + private static final Map valueMap = new HashMap<>(); + private static final Map nameMap = new HashMap<>(); // Enumerated from ARM IHI 0045E, 2.5 Attributes summary and history public static final ArmAeabiAttributesTag File = addTag(1, "File", ParameterType.UINT32); @@ -520,7 +582,7 @@ private static Map> parseArmAttribut } private static Map> parseAEABI(ByteBuffer buffer) { - Map> data = new HashMap>(); + Map> data = new HashMap<>(); while (buffer.position() < buffer.limit()) { int pos = buffer.position(); int subsectionTag = readULEB128(buffer).intValue(); @@ -534,7 +596,7 @@ private static Map> parseAEABI(ByteB } private static Map parseFileAttribute(ByteBuffer bb) { - Map result = new HashMap(); + Map result = new HashMap<>(); while (bb.position() < bb.limit()) { int tagValue = readULEB128(bb).intValue(); ArmAeabiAttributesTag tag = ArmAeabiAttributesTag.getByValue(tagValue); diff --git a/src/com/sun/jna/Function.java b/src/com/sun/jna/Function.java index a56cb711e0..c40c0427cb 100644 --- a/src/com/sun/jna/Function.java +++ b/src/com/sun/jna/Function.java @@ -76,9 +76,12 @@ public interface PostCallRead { /** Whether to throw an exception if last error is non-zero after call. */ @java.lang.annotation.Native public static final int THROW_LAST_ERROR = 0x40; - /** Mask for number of fixed args (1-3) for varargs calls. */ + /** Mask for number of fixed args (max 255) for varargs calls. */ @java.lang.annotation.Native - public static final int USE_VARARGS = 0x180; + public static final int USE_VARARGS = 0xFF; + /** Offset of USE_VARARGS in call flags */ + @java.lang.annotation.Native + private static final int USE_VARARGS_SHIFT = 7; static final Integer INTEGER_TRUE = Integer.valueOf(-1); static final Integer INTEGER_FALSE = Integer.valueOf(0); @@ -242,7 +245,7 @@ public static Function getFunction(Pointer p, int callFlags, String encoding) { this.library = library; this.functionName = functionName; this.callFlags = callFlags; - this.options = library.options; + this.options = library.getOptions(); this.encoding = encoding != null ? encoding : Native.getDefaultStringEncoding(); try { this.peer = library.getSymbolAddress(functionName); @@ -410,7 +413,7 @@ Object invoke(Object[] args, Class returnType, boolean allowObjects) { /* @see NativeLibrary#NativeLibrary(String,String,long,Map) implementation */ Object invoke(Object[] args, Class returnType, boolean allowObjects, int fixedArgs) { Object result = null; - int callFlags = this.callFlags | ((fixedArgs & 0x3) << 7); + int callFlags = this.callFlags | ((fixedArgs & USE_VARARGS) << USE_VARARGS_SHIFT); if (returnType == null || returnType==void.class || returnType==Void.class) { Native.invokeVoid(this, this.peer, callFlags, args); result = null; @@ -561,7 +564,7 @@ private Object convertArgument(Object[] args, int index, // than in native code so that the values will be valid until // this method returns. // Convert String to native pointer (const) - return new NativeString((String)arg, false).getPointer(); + return new NativeString((String)arg, encoding).getPointer(); } else if (arg instanceof WString) { // Convert WString to native pointer (const) return new NativeString(arg.toString(), true).getPointer(); diff --git a/src/com/sun/jna/Klass.java b/src/com/sun/jna/Klass.java index da16e6f8c6..aee4282a28 100644 --- a/src/com/sun/jna/Klass.java +++ b/src/com/sun/jna/Klass.java @@ -46,23 +46,7 @@ private Klass() { public static T newInstance(Class klass) { try { return klass.getDeclaredConstructor().newInstance(); - } catch (IllegalAccessException e) { - String msg = "Can't create an instance of " + klass - + ", requires a public no-arg constructor: " + e; - throw new IllegalArgumentException(msg, e); - } catch (IllegalArgumentException e) { - String msg = "Can't create an instance of " + klass - + ", requires a public no-arg constructor: " + e; - throw new IllegalArgumentException(msg, e); - } catch (InstantiationException e) { - String msg = "Can't create an instance of " + klass - + ", requires a public no-arg constructor: " + e; - throw new IllegalArgumentException(msg, e); - } catch (NoSuchMethodException e) { - String msg = "Can't create an instance of " + klass - + ", requires a public no-arg constructor: " + e; - throw new IllegalArgumentException(msg, e); - } catch (SecurityException e) { + } catch (IllegalAccessException | IllegalArgumentException | InstantiationException | NoSuchMethodException | SecurityException e) { String msg = "Can't create an instance of " + klass + ", requires a public no-arg constructor: " + e; throw new IllegalArgumentException(msg, e); diff --git a/src/com/sun/jna/Library.java b/src/com/sun/jna/Library.java index 3b79fabde0..71745ffd73 100644 --- a/src/com/sun/jna/Library.java +++ b/src/com/sun/jna/Library.java @@ -172,7 +172,7 @@ private static final class FunctionInfo { // Library invocation options private final Map options; private final InvocationMapper invocationMapper; - private final Map functions = new WeakHashMap(); + private final Map functions = new WeakHashMap<>(); public Handler(String libname, Class interfaceClass, Map options) { if (libname != null && "".equals(libname.trim())) { @@ -184,7 +184,7 @@ public Handler(String libname, Class interfaceClass, Map options) } this.interfaceClass = interfaceClass; - this.options = new HashMap(options); + this.options = new HashMap<>(options); int callingConvention = AltCallingConvention.class.isAssignableFrom(interfaceClass) ? Function.ALT_CONVENTION : Function.C_CONVENTION; @@ -247,7 +247,7 @@ public Object invoke(Object proxy, Method method, Object[] inArgs) // Find the function to invoke function = nativeLibrary.getFunction(method.getName(), method); parameterTypes = method.getParameterTypes(); - options = new HashMap(this.options); + options = new HashMap<>(this.options); options.put(Function.OPTION_INVOKING_METHOD, method); } f = new FunctionInfo(handler, function, parameterTypes, isVarArgs, options); diff --git a/src/com/sun/jna/Memory.java b/src/com/sun/jna/Memory.java index c83bfed9b5..cea967e617 100644 --- a/src/com/sun/jna/Memory.java +++ b/src/com/sun/jna/Memory.java @@ -54,7 +54,7 @@ public class Memory extends Pointer implements Closeable { /** Keep track of all allocated memory so we can dispose of it before unloading. */ private static final Map> allocatedMemory = - new ConcurrentHashMap>(); + new ConcurrentHashMap<>(); private static final WeakMemoryHolder buffers = new WeakMemoryHolder(); @@ -68,7 +68,7 @@ public static void purge() { /** Dispose of all allocated memory. */ public static void disposeAll() { // use a copy since dispose() modifies the map - Collection> refs = new ArrayList>(allocatedMemory.values()); + Collection> refs = new ArrayList<>(allocatedMemory.values()); for (Reference r : refs) { Memory m = r.get(); if(m != null) { @@ -118,7 +118,7 @@ public Memory(long size) { if (peer == 0) throw new OutOfMemoryError("Cannot allocate " + size + " bytes"); - allocatedMemory.put(peer, new WeakReference(this)); + allocatedMemory.put(peer, new WeakReference<>(this)); cleanable = Cleaner.getCleaner().register(this, new MemoryDisposer(peer)); } diff --git a/src/com/sun/jna/Native.java b/src/com/sun/jna/Native.java index e3c3d8ebef..5226b36ddc 100644 --- a/src/com/sun/jna/Native.java +++ b/src/com/sun/jna/Native.java @@ -221,7 +221,7 @@ static boolean isCompatibleVersion(String expectedVersion, String nativeVersion) loadNativeDispatchLibrary(); if (! isCompatibleVersion(VERSION_NATIVE, getNativeVersion())) { - String LS = System.getProperty("line.separator"); + String LS = System.lineSeparator(); throw new Error(LS + LS + "There is an incompatible JNA native library installed on this system" + LS + "Expected: " + VERSION_NATIVE + LS @@ -397,11 +397,7 @@ private static Charset getCharset(String encoding) { try { charset = Charset.forName(encoding); } - catch(IllegalCharsetNameException e) { - LOG.log(Level.WARNING, "JNA Warning: Encoding ''{0}'' is unsupported ({1})", - new Object[]{encoding, e.getMessage()}); - } - catch(UnsupportedCharsetException e) { + catch(IllegalCharsetNameException | UnsupportedCharsetException e) { LOG.log(Level.WARNING, "JNA Warning: Encoding ''{0}'' is unsupported ({1})", new Object[]{encoding, e.getMessage()}); } @@ -517,7 +513,7 @@ public static List toStringList(char[] buf) { * @return A {@link List} of all the strings in the buffer */ public static List toStringList(char[] buf, int offset, int len) { - List list = new ArrayList(); + List list = new ArrayList<>(); int lastPos = offset; int maxPos = offset + len; for (int curPos = offset; curPos < maxPos; curPos++) { @@ -691,7 +687,7 @@ private static void loadLibraryInstance(Class cls) { && Modifier.isStatic(field.getModifiers())) { // Ensure the field gets initialized by reading it field.setAccessible(true); // interface might be private - libraries.put(cls, new WeakReference(field.get(null))); + libraries.put(cls, new WeakReference<>(field.get(null))); break; } } @@ -785,7 +781,7 @@ public static Map getLibraryOptions(Class type) { throw new IllegalArgumentException("OPTIONS must be a public field of type java.util.Map (" + e + "): " + mappingClass); } // Make a clone of the original options - libraryOptions = new HashMap(libraryOptions); + libraryOptions = new HashMap<>(libraryOptions); if (!libraryOptions.containsKey(Library.OPTION_TYPE_MAPPER)) { libraryOptions.put(Library.OPTION_TYPE_MAPPER, lookupField(mappingClass, "TYPE_MAPPER", TypeMapper.class)); } @@ -1330,7 +1326,7 @@ static File getTempDir() throws IOException { if(Platform.isMac()) { // https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html jnatmp = new File(System.getProperty("user.home"), "Library/Caches/JNA/temp"); - } else if (Platform.isLinux() || Platform.isSolaris() || Platform.isAIX() || Platform.isFreeBSD() || Platform.isNetBSD() || Platform.isOpenBSD() || Platform.iskFreeBSD()) { + } else if (Platform.isLinux() || Platform.isSolaris() || Platform.isAIX() || Platform.isDragonFlyBSD() || Platform.isFreeBSD() || Platform.isNetBSD() || Platform.isOpenBSD() || Platform.iskFreeBSD()) { // https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html // The XDG_CACHE_DIR is expected to be per user String xdgCacheEnvironment = System.getenv("XDG_CACHE_HOME"); @@ -1552,8 +1548,8 @@ public static void setCallbackThreadInitializer(Callback cb, CallbackThreadIniti CallbackReference.setCallbackThreadInitializer(cb, initializer); } - private static final Map, long[]> registeredClasses = new WeakHashMap, long[]>(); - private static final Map, NativeLibrary> registeredLibraries = new WeakHashMap, NativeLibrary>(); + private static final Map, long[]> registeredClasses = new WeakHashMap<>(); + private static final Map, NativeLibrary> registeredLibraries = new WeakHashMap<>(); private static void unregisterAll() { synchronized(registeredClasses) { @@ -1786,7 +1782,7 @@ public static void register(Class cls, String libName) { // method name, library name, call conv public static void register(Class cls, NativeLibrary lib) { Method[] methods = cls.getDeclaredMethods(); - List mlist = new ArrayList(); + List mlist = new ArrayList<>(); Map options = lib.getOptions(); TypeMapper mapper = (TypeMapper) options.get(Library.OPTION_TYPE_MAPPER); boolean allowObjects = Boolean.TRUE.equals(options.get(Library.OPTION_ALLOW_OBJECTS)); @@ -1922,15 +1918,61 @@ public static void register(Class cls, NativeLibrary lib) { } } + /** + * Get the {@link NativeLibrary} instance that is wrapped by the given + * {@link Library} interface instance. + * + * @param library the {@link Library} interface instance, which was created + * by the {@link Native#load Native.load()} method + * @return the wrapped {@link NativeLibrary} instance + */ + public static NativeLibrary getNativeLibrary(final Library library) { + if(library == null) { + throw new IllegalArgumentException("null passed to getNativeLibrary"); + } + if(! Proxy.isProxyClass(library.getClass())) { + throw new IllegalArgumentException("library object passed to getNativeLibrary in not a proxy"); + } + final InvocationHandler handler = Proxy.getInvocationHandler(library); + if (!(handler instanceof Library.Handler)) { + throw new IllegalArgumentException("Object is not a properly initialized Library interface instance"); + } + return ((Library.Handler) handler).getNativeLibrary(); + } + + /** + * Get the {@link NativeLibrary} instance to which the given "registered" + * class is bound. + * + * @param cls the "registered" class, which was previously registered via + * the {@link Native#register register()} method + * @return the {@link NativeLibrary} instance to which the "registered" + * class is bound + */ + public static NativeLibrary getNativeLibrary(final Class cls) { + if(cls == null) { + throw new IllegalArgumentException("null passed to getNativeLibrary"); + } + final Class mappedClass = findDirectMappedClass(cls); + synchronized(registeredClasses) { + final NativeLibrary nativeLibrary = registeredLibraries.get(mappedClass); + if (nativeLibrary == null) { + throw new IllegalArgumentException("Class " + cls.getName() + " is not currently registered"); + } else { + return nativeLibrary; + } + } + } + /* Take note of options used for a given library mapping, to facilitate * looking them up later. */ private static Map cacheOptions(Class cls, Map options, Object proxy) { - Map libOptions = new HashMap(options); + Map libOptions = new HashMap<>(options); libOptions.put(_OPTION_ENCLOSING_LIBRARY, cls); typeOptions.put(cls, libOptions); if (proxy != null) { - libraries.put(cls, new WeakReference(proxy)); + libraries.put(cls, new WeakReference<>(proxy)); } // If it's a direct mapping, AND implements a Library interface, diff --git a/src/com/sun/jna/NativeLibrary.java b/src/com/sun/jna/NativeLibrary.java index 27eb569423..ea5278b9b4 100644 --- a/src/com/sun/jna/NativeLibrary.java +++ b/src/com/sun/jna/NativeLibrary.java @@ -95,20 +95,20 @@ public long getSymbolAddress(long handle, String name, SymbolProvider parent) { } }; - private Cleaner.Cleanable cleanable; - private long handle; + private final Cleaner.Cleanable cleanable; + private volatile long handle; private final String libraryName; private final String libraryPath; - private final Map functions = new HashMap(); + private final Map functions = new HashMap<>(); private final SymbolProvider symbolProvider; - final int callFlags; - private String encoding; - final Map options; + private final int callFlags; + private final String encoding; + private final Map options; - private static final Map> libraries = new HashMap>(); + private static final Map> libraries = new HashMap<>(); - private static final Map> searchPaths = new ConcurrentHashMap>(); - private static final LinkedHashSet librarySearchPath = new LinkedHashSet(); + private static final Map> searchPaths = new ConcurrentHashMap<>(); + private static final LinkedHashSet librarySearchPath = new LinkedHashSet<>(); static { // Force initialization of native library @@ -120,6 +120,7 @@ private static String functionKey(String name, int flags, String encoding) { return name + "|" + flags + "|" + encoding; } + @SuppressWarnings("LeakingThisInConstructor") private NativeLibrary(String libraryName, String libraryPath, long handle, Map options) { this.libraryName = getLibraryName(libraryName); this.libraryPath = libraryPath; @@ -129,7 +130,6 @@ private NativeLibrary(String libraryName, String libraryPath, long handle, Map options) { private static NativeLibrary loadLibrary(final String libraryName, final Map options) { LOG.log(DEBUG_LOAD_LEVEL, "Looking for library '" + libraryName + "'"); - List exceptions = new ArrayList(); + List exceptions = new ArrayList<>(); boolean isAbsolutePath = new File(libraryName).isAbsolute(); - LinkedHashSet searchPath = new LinkedHashSet(); + LinkedHashSet searchPath = new LinkedHashSet<>(); int openFlags = openFlags(options); // @@ -350,18 +352,14 @@ private static void addSuppressedReflected(Throwable target, Throwable suppresse } try { addSuppressedMethod.invoke(target, suppressed); - } catch (IllegalAccessException ex) { - throw new RuntimeException("Failed to call addSuppressedMethod", ex); - } catch (IllegalArgumentException ex) { - throw new RuntimeException("Failed to call addSuppressedMethod", ex); - } catch (InvocationTargetException ex) { + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new RuntimeException("Failed to call addSuppressedMethod", ex); } } /** Look for a matching framework (OSX) */ static String[] matchFramework(String libraryName) { - Set paths = new LinkedHashSet(); + Set paths = new LinkedHashSet<>(); File framework = new File(libraryName); if (framework.isAbsolute()) { if (libraryName.contains(".framework")) { @@ -460,7 +458,7 @@ public static final NativeLibrary getInstance(String libraryName, ClassLoader cl * @param libraryOptions Native library options for the given library (see {@link Library}). */ public static final NativeLibrary getInstance(String libraryName, Map libraryOptions) { - Map options = new HashMap(libraryOptions); + Map options = new HashMap<>(libraryOptions); if (options.get(Library.OPTION_CALLING_CONVENTION) == null) { options.put(Library.OPTION_CALLING_CONVENTION, Integer.valueOf(Function.C_CONVENTION)); } @@ -482,7 +480,7 @@ public static final NativeLibrary getInstance(String libraryName, Map else { library = loadLibrary(libraryName, options); } - ref = new WeakReference(library); + ref = new WeakReference<>(library); libraries.put(library.getName() + options, ref); File file = library.getFile(); if (file != null) { @@ -675,7 +673,7 @@ public File getFile() { static void disposeAll() { Set> values; synchronized(libraries) { - values = new LinkedHashSet>(libraries.values()); + values = new LinkedHashSet<>(libraries.values()); } for (Reference ref : values) { NativeLibrary lib = ref.get(); @@ -687,7 +685,7 @@ static void disposeAll() { /** Close the native library we're mapped to. */ public void close() { - Set keys = new HashSet(); + Set keys = new HashSet<>(); synchronized(libraries) { for (Map.Entry> e : libraries.entrySet()) { Reference ref = e.getValue(); @@ -703,8 +701,8 @@ public void close() { synchronized(this) { if (handle != 0) { - cleanable.clean(); handle = 0; + cleanable.clean(); } } } @@ -720,7 +718,7 @@ private static List initPaths(String key) { return Collections.emptyList(); } StringTokenizer st = new StringTokenizer(value, File.pathSeparator); - List list = new ArrayList(); + List list = new ArrayList<>(); while (st.hasMoreTokens()) { String path = st.nextToken(); if (!"".equals(path)) { @@ -852,7 +850,7 @@ public boolean accept(File dir, String filename) { } }; - Collection matches = new LinkedList(); + Collection matches = new LinkedList<>(); for (String path : searchPath) { File[] files = new File(path).listFiles(filter); if (files != null && files.length > 0) { @@ -1018,7 +1016,7 @@ else if (Platform.ARCH.equals("mips64el")) { * Get the library paths from ldconfig cache. Tested against ldconfig 2.13. */ private static ArrayList getLinuxLdPaths() { - ArrayList ldPaths = new ArrayList(); + ArrayList ldPaths = new ArrayList<>(); Process process = null; BufferedReader reader = null; try { diff --git a/src/com/sun/jna/NativeMappedConverter.java b/src/com/sun/jna/NativeMappedConverter.java index 0c54e43494..ee13fe1e57 100644 --- a/src/com/sun/jna/NativeMappedConverter.java +++ b/src/com/sun/jna/NativeMappedConverter.java @@ -32,7 +32,7 @@ /** Provides type conversion for instances of {@link NativeMapped}. */ public class NativeMappedConverter implements TypeConverter { private static final Map, Reference> converters = - new WeakHashMap, Reference>(); + new WeakHashMap<>(); private final Class type; private final Class nativeType; private final NativeMapped instance; @@ -43,7 +43,7 @@ public static NativeMappedConverter getInstance(Class cls) { NativeMappedConverter nmc = r != null ? r.get() : null; if (nmc == null) { nmc = new NativeMappedConverter(cls); - converters.put(cls, new SoftReference(nmc)); + converters.put(cls, new SoftReference<>(nmc)); } return nmc; } diff --git a/src/com/sun/jna/Platform.java b/src/com/sun/jna/Platform.java index ac1395e95d..ee2dc90a51 100644 --- a/src/com/sun/jna/Platform.java +++ b/src/com/sun/jna/Platform.java @@ -42,6 +42,7 @@ public final class Platform { public static final int GNU = 9; public static final int KFREEBSD = 10; public static final int NETBSD = 11; + public static final int DRAGONFLYBSD = 12; /** Whether read-only (final) fields within Structures are supported. */ public static final boolean RO_FIELDS; @@ -110,6 +111,9 @@ else if (osName.equalsIgnoreCase("gnu/kfreebsd")) { else if (osName.equalsIgnoreCase("netbsd")) { osType = NETBSD; } + else if (osName.equalsIgnoreCase("dragonflybsd")) { + osType = DRAGONFLYBSD; + } else { osType = UNSPECIFIED; } @@ -160,6 +164,9 @@ public static final boolean isWindows() { public static final boolean isSolaris() { return osType == SOLARIS; } + public static final boolean isDragonFlyBSD() { + return osType == DRAGONFLYBSD; + } public static final boolean isFreeBSD() { return osType == FREEBSD; } @@ -329,6 +336,9 @@ static String getNativeLibraryResourcePrefix(int osType, String arch, String nam case Platform.SOLARIS: osPrefix = "sunos-" + arch; break; + case Platform.DRAGONFLYBSD: + osPrefix = "dragonflybsd-" + arch; + break; case Platform.FREEBSD: osPrefix = "freebsd-" + arch; break; diff --git a/src/com/sun/jna/Pointer.java b/src/com/sun/jna/Pointer.java index 1a3fe5d60f..444035f51a 100644 --- a/src/com/sun/jna/Pointer.java +++ b/src/com/sun/jna/Pointer.java @@ -748,7 +748,7 @@ public double[] getDoubleArray(long offset, int arraySize) { * determined by a NULL-valued terminating element. */ public Pointer[] getPointerArray(long offset) { - List array = new ArrayList(); + List array = new ArrayList<>(); int addOffset = 0; Pointer p = getPointer(offset); while (p != null) { @@ -811,7 +811,7 @@ public String[] getWideStringArray(long offset, int length) { * @param encoding */ public String[] getStringArray(long offset, int length, String encoding) { - List strings = new ArrayList(); + List strings = new ArrayList<>(); Pointer p; int addOffset = 0; if (length != -1) { diff --git a/src/com/sun/jna/StringArray.java b/src/com/sun/jna/StringArray.java index daf4c108b0..d7096e8bba 100644 --- a/src/com/sun/jna/StringArray.java +++ b/src/com/sun/jna/StringArray.java @@ -34,7 +34,7 @@ */ public class StringArray extends Memory implements Function.PostCallRead { private String encoding; - private List natives = new ArrayList(); + private List natives = new ArrayList<>(); private Object[] original; /** Create a native array of strings. */ public StringArray(String[] strings) { diff --git a/src/com/sun/jna/Structure.java b/src/com/sun/jna/Structure.java index 39d3da0efa..b29f6741fb 100644 --- a/src/com/sun/jna/Structure.java +++ b/src/com/sun/jna/Structure.java @@ -48,6 +48,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.logging.Logger; @@ -155,8 +156,14 @@ private static class NativeStringTracking { //public static final int ALIGN_8 = 6; protected static final int CALCULATE_SIZE = -1; - static final Map, LayoutInfo> layoutInfo = new WeakHashMap, LayoutInfo>(); - static final Map, List> fieldOrder = new WeakHashMap, List>(); + static final ReentrantReadWriteLock layoutInfoLock = new ReentrantReadWriteLock(); + static final ReentrantReadWriteLock fieldOrderLock = new ReentrantReadWriteLock(); + static final ReentrantReadWriteLock fieldListLock = new ReentrantReadWriteLock(); + static final ReentrantReadWriteLock validationLock = new ReentrantReadWriteLock(); + static final Map, LayoutInfo> layoutInfo = new WeakHashMap<>(); + static final Map, List> fieldOrder = new WeakHashMap<>(); + static final Map, List> fieldList = new WeakHashMap<>(); + static final Map, Boolean> validationMap = new WeakHashMap<>(); // This field is accessed by native code private Pointer memory; @@ -168,7 +175,7 @@ private static class NativeStringTracking { private Map structFields; // Keep track of native C strings which have been allocated, // corresponding to String fields of this Structure - private final Map nativeStrings = new HashMap(8); + private final Map nativeStrings = new HashMap<>(8); private TypeMapper typeMapper; // This field is accessed by native code private long typeInfo; @@ -479,7 +486,7 @@ public Pointer getPointer() { private static final ThreadLocal> reads = new ThreadLocal>() { @Override protected synchronized Map initialValue() { - return new HashMap(); + return new HashMap<>(); } }; @@ -981,7 +988,7 @@ private void writeField(StructField structField, Object value) { */ // TODO(idosu 28 Apr 2018): Maybe deprecate this method to let users know they should use @FieldOrder protected List getFieldOrder() { - List fields = new LinkedList(); + List fields = new LinkedList<>(); for (Class clazz = getClass(); clazz != Structure.class; clazz = clazz.getSuperclass()) { FieldOrder order = clazz.getAnnotation(FieldOrder.class); if (order != null) { @@ -1015,22 +1022,43 @@ protected void sortFields(List fields, List names) { * this {@link Structure} class. */ protected List getFieldList() { - List flist = new ArrayList(); - for (Class cls = getClass(); - !cls.equals(Structure.class); - cls = cls.getSuperclass()) { - List classFields = new ArrayList(); - Field[] fields = cls.getDeclaredFields(); - for (int i=0;i < fields.length;i++) { - int modifiers = fields[i].getModifiers(); - if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { - continue; - } - classFields.add(fields[i]); + Class clazz = getClass(); + // Try to read the value under the read lock + fieldListLock.readLock().lock(); + try { + List fields = fieldList.get(clazz); + if (fields != null) { + return fields; // Return the cached result if found } - flist.addAll(0, classFields); + } finally { + fieldListLock.readLock().unlock(); + } + + // If not found, compute the value under the write lock + fieldListLock.writeLock().lock(); + try { + // Double-check if another thread has computed the value before we do + return fieldList.computeIfAbsent(clazz, (c) -> { + List flist = new ArrayList<>(); + List classFields = new ArrayList<>(); + for (Class cls = clazz; + !cls.equals(Structure.class); + cls = cls.getSuperclass()) { + for (Field field : cls.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { + continue; + } + classFields.add(field); + } + flist.addAll(0, classFields); + classFields.clear(); + } + return flist; + }); + } finally { + fieldListLock.writeLock().unlock(); } - return flist; } /** Cache field order per-class. @@ -1038,13 +1066,24 @@ protected List getFieldList() { */ private List fieldOrder() { Class clazz = getClass(); - synchronized(fieldOrder) { - List list = fieldOrder.get(clazz); - if (list == null) { - list = getFieldOrder(); - fieldOrder.put(clazz, list); + // Try to read the value under the read lock + fieldOrderLock.readLock().lock(); + try { + List order = fieldOrder.get(clazz); + if (order != null) { + return order; // Return the cached result if found } - return list; + } finally { + fieldOrderLock.readLock().unlock(); + } + + // If not found, compute the value under the write lock + fieldOrderLock.writeLock().lock(); + try { + // Double-check if another thread has computed the value before we do (see JavaDoc) + return fieldOrder.computeIfAbsent(clazz, (c) -> getFieldOrder()); + } finally { + fieldOrderLock.writeLock().unlock(); } } @@ -1053,7 +1092,7 @@ public static List createFieldsOrder(List baseFields, String ... } public static List createFieldsOrder(List baseFields, List extraFields) { - List fields = new ArrayList(baseFields.size() + extraFields.size()); + List fields = new ArrayList<>(baseFields.size() + extraFields.size()); fields.addAll(baseFields); fields.addAll(extraFields); return Collections.unmodifiableList(fields); @@ -1076,7 +1115,7 @@ public static List createFieldsOrder(String ... fields) { } private static > List sort(Collection c) { - List list = new ArrayList(c); + List list = new ArrayList<>(c); Collections.sort(list); return list; } @@ -1090,7 +1129,7 @@ private static > List sort(Collection c) **/ protected List getFields(boolean force) { List flist = getFieldList(); - Set names = new HashSet(); + Set names = new HashSet<>(); for (Field f : flist) { names.add(f.getName()); } @@ -1113,7 +1152,7 @@ protected List getFields(boolean force) { return null; } - Set orderedNames = new HashSet(fieldOrder); + Set orderedNames = new HashSet<>(fieldOrder); if (!orderedNames.equals(names)) { throw new Error("Structure.getFieldOrder() on " + getClass() + " returns names (" @@ -1159,8 +1198,11 @@ static int size(Class type) { */ static int size(Class type, T value) { LayoutInfo info; - synchronized(layoutInfo) { + layoutInfoLock.readLock().lock(); + try { info = layoutInfo.get(type); + } finally { + layoutInfoLock.readLock().unlock(); } int sz = (info != null && !info.variable) ? info.size : CALCULATE_SIZE; if (sz == CALCULATE_SIZE) { @@ -1183,8 +1225,11 @@ int calculateSize(boolean force, boolean avoidFFIType) { int size = CALCULATE_SIZE; Class clazz = getClass(); LayoutInfo info; - synchronized(layoutInfo) { + layoutInfoLock.readLock().lock(); + try { info = layoutInfo.get(clazz); + } finally { + layoutInfoLock.readLock().unlock(); } if (info == null || this.alignType != info.alignType @@ -1196,7 +1241,8 @@ int calculateSize(boolean force, boolean avoidFFIType) { this.structFields = info.fields; if (!info.variable) { - synchronized(layoutInfo) { + layoutInfoLock.readLock().lock(); + try { // If we've already cached it, only override layout if // we're using non-default values for alignment and/or // type mapper; this way we don't override the cache @@ -1205,8 +1251,18 @@ int calculateSize(boolean force, boolean avoidFFIType) { if (!layoutInfo.containsKey(clazz) || this.alignType != ALIGN_DEFAULT || this.typeMapper != null) { + // Must release read lock before acquiring write lock (see JavaDoc lock escalation example) + layoutInfoLock.readLock().unlock(); + layoutInfoLock.writeLock().lock(); + layoutInfo.put(clazz, info); + + // Downgrade by acquiring read lock before releasing write lock (again, see JavaDoc) + layoutInfoLock.readLock().lock(); + layoutInfoLock.writeLock().unlock();; } + } finally { + layoutInfoLock.readLock().unlock(); } } size = info.size; @@ -1250,9 +1306,28 @@ private void validateField(String name, Class type) { /** ensure all fields are of valid type. */ private void validateFields() { - List fields = getFieldList(); - for (Field f : fields) { - validateField(f.getName(), f.getType()); + // Try to read the value under the read lock + validationLock.readLock().lock(); + try { + if (validationMap.containsKey(getClass())) { + return; // Return because this Structure has already been validated + } + } finally { + validationLock.readLock().unlock(); + } + + // If not found, perform validation and update the cache under the write lock + validationLock.writeLock().lock(); + try { + // Double-check if another thread has computed the value before we do (see JavaDoc) + validationMap.computeIfAbsent(getClass(), (cls) -> { + for (Field f : getFieldList()) { + validateField(f.getName(), f.getType()); + } + return true; + }); + } finally { + validationLock.writeLock().unlock(); } } @@ -1563,7 +1638,7 @@ private String format(Class type) { private String toString(int indent, boolean showContents, boolean dumpMemory) { ensureAllocated(); - String LS = System.getProperty("line.separator"); + String LS = System.lineSeparator(); String name = format(getClass()) + "(" + getPointer() + ")"; if (!(getPointer() instanceof Memory)) { name += " (" + size() + " bytes)"; @@ -1955,9 +2030,9 @@ public static class size_t extends IntegerType { public size_t(long value) { super(Native.SIZE_T_SIZE, value); } } - private static final Map> typeInfoMap = new WeakHashMap>(); - private static final Map unionHelper = new WeakHashMap(); - private static final Map ffiTypeInfo = new HashMap(); + private static final Map> typeInfoMap = new WeakHashMap<>(); + private static final Map unionHelper = new WeakHashMap<>(); + private static final Map ffiTypeInfo = new HashMap<>(); // Native.initIDs initializes these fields to their appropriate // pointer values. These are in a separate class from FFIType so that @@ -2206,7 +2281,7 @@ private static void storeTypeInfo(Class clazz, int elementCount, FFIType type) { synchronized (typeInfoMap) { Map typeMap = typeInfoMap.get(clazz); if(typeMap == null) { - typeMap = new HashMap(); + typeMap = new HashMap<>(); typeInfoMap.put(clazz, typeMap); } typeMap.put(elementCount, type); @@ -2325,9 +2400,7 @@ static void validate(Class cls) { try { cls.getConstructor(); return; - }catch(NoSuchMethodException e) { - } - catch(SecurityException e) { + }catch(NoSuchMethodException | SecurityException e) { } throw new IllegalArgumentException("No suitable constructor found for class: " + cls.getName()); } diff --git a/src/com/sun/jna/Union.java b/src/com/sun/jna/Union.java index 28ef5169f8..b21937385f 100644 --- a/src/com/sun/jna/Union.java +++ b/src/com/sun/jna/Union.java @@ -67,7 +67,7 @@ protected Union(Pointer p, int alignType, TypeMapper mapper) { @Override protected List getFieldOrder() { List flist = getFieldList(); - List list = new ArrayList(flist.size()); + List list = new ArrayList<>(flist.size()); for (Field f : flist) { list.add(f.getName()); } diff --git a/src/com/sun/jna/VarArgsChecker.java b/src/com/sun/jna/VarArgsChecker.java index ae3a5cdf29..7d25a7b0db 100644 --- a/src/com/sun/jna/VarArgsChecker.java +++ b/src/com/sun/jna/VarArgsChecker.java @@ -83,9 +83,7 @@ static VarArgsChecker create() { } else { return new NoVarArgsChecker(); } - } catch (NoSuchMethodException e) { - return new NoVarArgsChecker(); - } catch (SecurityException e) { + } catch (NoSuchMethodException | SecurityException e) { return new NoVarArgsChecker(); } } diff --git a/src/com/sun/jna/WeakMemoryHolder.java b/src/com/sun/jna/WeakMemoryHolder.java index 1526e8dc44..610b2d494d 100644 --- a/src/com/sun/jna/WeakMemoryHolder.java +++ b/src/com/sun/jna/WeakMemoryHolder.java @@ -38,12 +38,12 @@ * The references to the memory objects are released on access of WeakMemoryHolder. */ public class WeakMemoryHolder { - ReferenceQueue referenceQueue = new ReferenceQueue(); - IdentityHashMap, Memory> backingMap = new IdentityHashMap, Memory>(); + ReferenceQueue referenceQueue = new ReferenceQueue<>(); + IdentityHashMap, Memory> backingMap = new IdentityHashMap<>(); public synchronized void put(Object o, Memory m) { clean(); - Reference reference = new WeakReference(o, referenceQueue); + Reference reference = new WeakReference<>(o, referenceQueue); backingMap.put(reference, m); } diff --git a/src/com/sun/jna/internal/Cleaner.java b/src/com/sun/jna/internal/Cleaner.java index 7d0ec8e28e..a2095937fc 100644 --- a/src/com/sun/jna/internal/Cleaner.java +++ b/src/com/sun/jna/internal/Cleaner.java @@ -45,35 +45,11 @@ public static Cleaner getCleaner() { } private final ReferenceQueue referenceQueue; - private final Thread cleanerThread; + private Thread cleanerThread; private CleanerRef firstCleanable; private Cleaner() { - referenceQueue = new ReferenceQueue(); - cleanerThread = new Thread() { - @Override - public void run() { - while(true) { - try { - Reference ref = referenceQueue.remove(); - if(ref instanceof CleanerRef) { - ((CleanerRef) ref).clean(); - } - } catch (InterruptedException ex) { - // Can be raised on shutdown. If anyone else messes with - // our reference queue, well, there is no way to separate - // the two cases. - // https://groups.google.com/g/jna-users/c/j0fw96PlOpM/m/vbwNIb2pBQAJ - break; - } catch (Exception ex) { - Logger.getLogger(Cleaner.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - }; - cleanerThread.setName("JNA Cleaner"); - cleanerThread.setDaemon(true); - cleanerThread.start(); + referenceQueue = new ReferenceQueue<>(); } public synchronized Cleanable register(Object obj, Runnable cleanupTask) { @@ -83,34 +59,43 @@ public synchronized Cleanable register(Object obj, Runnable cleanupTask) { } private synchronized CleanerRef add(CleanerRef ref) { - if(firstCleanable == null) { - firstCleanable = ref; - } else { - ref.setNext(firstCleanable); - firstCleanable.setPrevious(ref); - firstCleanable = ref; + synchronized (referenceQueue) { + if (firstCleanable == null) { + firstCleanable = ref; + } else { + ref.setNext(firstCleanable); + firstCleanable.setPrevious(ref); + firstCleanable = ref; + } + if (cleanerThread == null) { + Logger.getLogger(Cleaner.class.getName()).log(Level.FINE, "Starting CleanerThread"); + cleanerThread = new CleanerThread(); + cleanerThread.start(); + } + return ref; } - return ref; } private synchronized boolean remove(CleanerRef ref) { - boolean inChain = false; - if(ref == firstCleanable) { - firstCleanable = ref.getNext(); - inChain = true; - } - if(ref.getPrevious() != null) { - ref.getPrevious().setNext(ref.getNext()); - } - if(ref.getNext() != null) { - ref.getNext().setPrevious(ref.getPrevious()); - } - if(ref.getPrevious() != null || ref.getNext() != null) { - inChain = true; + synchronized (referenceQueue) { + boolean inChain = false; + if (ref == firstCleanable) { + firstCleanable = ref.getNext(); + inChain = true; + } + if (ref.getPrevious() != null) { + ref.getPrevious().setNext(ref.getNext()); + } + if (ref.getNext() != null) { + ref.getNext().setPrevious(ref.getPrevious()); + } + if (ref.getPrevious() != null || ref.getNext() != null) { + inChain = true; + } + ref.setNext(null); + ref.setPrevious(null); + return inChain; } - ref.setNext(null); - ref.setPrevious(null); - return inChain; } private static class CleanerRef extends PhantomReference implements Cleanable { @@ -125,6 +110,7 @@ public CleanerRef(Cleaner cleaner, Object referent, ReferenceQueue ref = referenceQueue.remove(CLEANER_LINGER_TIME); + if (ref instanceof CleanerRef) { + ((CleanerRef) ref).clean(); + } else if (ref == null) { + synchronized (referenceQueue) { + Logger logger = Logger.getLogger(Cleaner.class.getName()); + if (firstCleanable == null) { + cleanerThread = null; + logger.log(Level.FINE, "Shutting down CleanerThread"); + break; + } else if (logger.isLoggable(Level.FINER)) { + StringBuilder registeredCleaners = new StringBuilder(); + for(CleanerRef cleanerRef = firstCleanable; cleanerRef != null; cleanerRef = cleanerRef.next) { + if(registeredCleaners.length() != 0) { + registeredCleaners.append(", "); + } + registeredCleaners.append(cleanerRef.cleanupTask.toString()); + } + logger.log(Level.FINER, "Registered Cleaners: {0}", registeredCleaners.toString()); + } + } + } + } catch (InterruptedException ex) { + // Can be raised on shutdown. If anyone else messes with + // our reference queue, well, there is no way to separate + // the two cases. + // https://groups.google.com/g/jna-users/c/j0fw96PlOpM/m/vbwNIb2pBQAJ + break; + } catch (Exception ex) { + Logger.getLogger(Cleaner.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + } } diff --git a/src/com/sun/jna/internal/ReflectionUtils.java b/src/com/sun/jna/internal/ReflectionUtils.java index ee85767da3..72e9cb3c4b 100644 --- a/src/com/sun/jna/internal/ReflectionUtils.java +++ b/src/com/sun/jna/internal/ReflectionUtils.java @@ -136,9 +136,7 @@ public static boolean isDefault(Method method) { } try { return (boolean) (Boolean) METHOD_IS_DEFAULT.invoke(method); - } catch (IllegalAccessException ex) { - throw new RuntimeException(ex); - } catch (IllegalArgumentException ex) { + } catch (IllegalAccessException | IllegalArgumentException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { Throwable cause = ex.getCause(); diff --git a/test/com/sun/jna/CallbacksTest.java b/test/com/sun/jna/CallbacksTest.java index da6918e83a..ff801fb7e5 100644 --- a/test/com/sun/jna/CallbacksTest.java +++ b/test/com/sun/jna/CallbacksTest.java @@ -354,7 +354,7 @@ public void callback() { lib.callVoidCallback(cb); assertTrue("Callback not called", called[0]); - Map refs = new WeakHashMap(callbackCache()); + Map refs = new WeakHashMap<>(callbackCache()); assertTrue("Callback not cached", refs.containsKey(cb)); CallbackReference ref = refs.get(cb); refs = callbackCache(); @@ -694,7 +694,7 @@ public String callback(String arg, String arg2) { String arg = getName() + "1" + charset.decode(charset.encode(UNICODE)); String arg2 = getName() + "2" + charset.decode(charset.encode(UNICODE)); String value = lib.callStringCallback(cb, arg, arg2); - WeakReference ref = new WeakReference(value); + WeakReference ref = new WeakReference<>(value); arg = null; value = null; @@ -1331,7 +1331,7 @@ public void callback() { // as daemon to avoid VM having to wait for it. public void testCallbackThreadPersistence() throws Exception { final int[] called = {0}; - final Set threads = new HashSet(); + final Set threads = new HashSet<>(); final int COUNT = 5; CallbackThreadInitializer init = new CallbackThreadInitializer(true, false) { @@ -1360,12 +1360,12 @@ public void callback() { // Thread object is never GC'd on linux-amd64 and darwin-amd64 (w/openjdk7) public void testCleanupUndetachedThreadOnThreadExit() throws Exception { - final Set> threads = new HashSet>(); + final Set> threads = new HashSet<>(); final int[] called = { 0 }; TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { @Override public void callback() { - threads.add(new WeakReference(Thread.currentThread())); + threads.add(new WeakReference<>(Thread.currentThread())); if (++called[0] == 1) { Thread.currentThread().setName(getName() + " (Thread to be cleaned up)"); } @@ -1414,7 +1414,7 @@ public String getName(Callback cb) { // but callback explicitly detaches it on final invocation. public void testCallbackIndicatedThreadDetach() throws Exception { final int[] called = {0}; - final Set threads = new HashSet(); + final Set threads = new HashSet<>(); final int COUNT = 5; TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { @Override @@ -1477,7 +1477,7 @@ public void callback() { assertEquals("Wrong module HANDLE for DLL function pointer", handle, pref.getValue()); // Check slot re-use - Map refs = new WeakHashMap(callbackCache()); + Map refs = new WeakHashMap<>(callbackCache()); assertTrue("Callback not cached", refs.containsKey(cb)); CallbackReference ref = refs.get(cb); refs = callbackCache(); diff --git a/test/com/sun/jna/DirectArgumentsWrappersMarshalTest.java b/test/com/sun/jna/DirectArgumentsWrappersMarshalTest.java index ffa1383b56..960c361d81 100644 --- a/test/com/sun/jna/DirectArgumentsWrappersMarshalTest.java +++ b/test/com/sun/jna/DirectArgumentsWrappersMarshalTest.java @@ -92,7 +92,7 @@ public Object toNative(Object value, ToNativeContext context) { } } } - final Map converters = new HashMap(); + final Map converters = new HashMap<>(); converters.put(Boolean.class, new PrimitiveConverter(boolean.class)); converters.put(Byte.class, new PrimitiveConverter(byte.class)); converters.put(Short.class, new PrimitiveConverter(short.class)); diff --git a/test/com/sun/jna/DirectTest.java b/test/com/sun/jna/DirectTest.java index 3e2f4b563f..203e9a2669 100644 --- a/test/com/sun/jna/DirectTest.java +++ b/test/com/sun/jna/DirectTest.java @@ -23,18 +23,20 @@ */ package com.sun.jna; -import junit.framework.*; -import java.lang.reflect.Method; import java.io.File; +import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import junit.framework.TestCase; + //@SuppressWarnings("unused") public class DirectTest extends TestCase implements Paths { @@ -202,8 +204,8 @@ public void testGetOptionsForDirectMappingWithMemberInitializer() { }; final TypeMapper mapper = new DefaultTypeMapper(); final int alignment = Structure.ALIGN_NONE; - final String encoding = System.getProperty("file.encoding"); - Map options = new HashMap(); + final String encoding = Charset.defaultCharset().name(); + Map options = new HashMap<>(); options.put(Library.OPTION_TYPE_MAPPER, mapper); options.put(Library.OPTION_STRUCTURE_ALIGNMENT, alignment); options.put(Library.OPTION_STRING_ENCODING, encoding); @@ -223,7 +225,7 @@ public void testGetOptionsForDirectMappingWithMemberInitializer() { public static class DirectMappingStatic { final static TypeMapper TEST_MAPPER = new DefaultTypeMapper(); final static int TEST_ALIGNMENT = Structure.ALIGN_DEFAULT; - final static String TEST_ENCODING = System.getProperty("file.encoding"); + final static String TEST_ENCODING = Charset.defaultCharset().name(); final static Map TEST_OPTIONS = new HashMap() { private static final long serialVersionUID = 1L; // we're not serializing it diff --git a/test/com/sun/jna/ELFAnalyserTest.java b/test/com/sun/jna/ELFAnalyserTest.java index 16a7ef5fa2..a8da0b2c4f 100644 --- a/test/com/sun/jna/ELFAnalyserTest.java +++ b/test/com/sun/jna/ELFAnalyserTest.java @@ -128,16 +128,9 @@ public static void afterClass() throws IOException { private static void extractTestFile(File outputFile) throws IOException { String inputPath = "/com/sun/jna/data/" + outputFile.getName(); - InputStream is = ELFAnalyserTest.class.getResourceAsStream(inputPath); - try { - OutputStream os = new FileOutputStream(outputFile); - try { - copyStream(is, os); - } finally { - os.close(); - } - } finally { - is.close(); + try (InputStream is = ELFAnalyserTest.class.getResourceAsStream(inputPath); + OutputStream os = new FileOutputStream(outputFile)) { + copyStream(is, os); } } diff --git a/test/com/sun/jna/FunctionTest.java b/test/com/sun/jna/FunctionTest.java index c63315d78b..fc3333de87 100644 --- a/test/com/sun/jna/FunctionTest.java +++ b/test/com/sun/jna/FunctionTest.java @@ -23,7 +23,11 @@ */ package com.sun.jna; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.Collections; import junit.framework.TestCase; +import org.junit.Assert; /** Exercise the {@link Function} class. * @@ -32,6 +36,29 @@ //@SuppressWarnings("unused") public class FunctionTest extends TestCase { + private NativeLibrary libUTF8; + private NativeLibrary libLatin1; + private TestLibUTF8 libUTF8Direct; + private TestLibLatin1 libLatin1Direct; + private TestLib libUTF8Interface; + private TestLib libLatin1Interface; + + @Override + protected void setUp() { + libUTF8 = NativeLibrary.getInstance("testlib", + Collections.singletonMap(Library.OPTION_STRING_ENCODING, "UTF-8")); + libLatin1 = NativeLibrary.getInstance("testlib", + Collections.singletonMap(Library.OPTION_STRING_ENCODING, "ISO-8859-1")); + Native.register(TestLibUTF8.class, libUTF8); + Native.register(TestLibLatin1.class, libLatin1); + libUTF8Direct = new TestLibUTF8(); + libLatin1Direct = new TestLibLatin1(); + libUTF8Interface = Native.load("testlib", TestLib.class, + Collections.singletonMap(Library.OPTION_STRING_ENCODING, "UTF-8")); + libLatin1Interface = Native.load("testlib", TestLib.class, + Collections.singletonMap(Library.OPTION_STRING_ENCODING, "ISO-8859-1")); + } + public void testTooManyArgs() { NativeLibrary lib = NativeLibrary.getInstance(Platform.C_LIBRARY_NAME); Function f = lib.getFunction("printf"); @@ -58,8 +85,121 @@ public void testUnsupportedReturnType() { } } + public void testStringEncodingArgument() throws UnsupportedEncodingException { + // String with german umlauts + String input = "Hallo äöüß"; + byte[] result = new byte[32]; + Arrays.fill(result, (byte) 0); + libUTF8Interface.copyString(input, result); + Assert.assertArrayEquals(toByteArray(input, "UTF-8", 32), result); + Arrays.fill(result, (byte) 0); + libLatin1Interface.copyString(input, result); + Assert.assertArrayEquals(toByteArray(input, "ISO-8859-1", 32), result); + + // String array with german umlauts + String[] inputArray = new String[]{"1Hallo äöüß1", "2Hallo äöüß2"}; + result = new byte[64]; + Arrays.fill(result, (byte) 0); + libUTF8Interface.copyStringArray(inputArray, result); + Assert.assertArrayEquals(toByteArray(inputArray, "UTF-8", 64), result); + Arrays.fill(result, (byte) 0); + libLatin1Interface.copyStringArray(inputArray, result); + Assert.assertArrayEquals(toByteArray(inputArray, "ISO-8859-1", 64), result); + } + + public void testStringEncodingArgumentDirect() throws UnsupportedEncodingException { + // String with german umlauts + String input = "Hallo äöüß"; + byte[] result = new byte[32]; + Arrays.fill(result, (byte) 0); + libUTF8Direct.copyString(input, result); + Assert.assertArrayEquals(toByteArray(input, "UTF-8", 32), result); + Arrays.fill(result, (byte) 0); + libLatin1Direct.copyString(input, result); + Assert.assertArrayEquals(toByteArray(input, "ISO-8859-1", 32), result); + } + + public void testStringReturn() throws UnsupportedEncodingException { + // String with german umlauts + String input = "Hallo äöüß"; + + String result; + Memory mem = new Memory(32); + mem.clear(); + mem.write(0, input.getBytes("UTF-8"), 0, input.getBytes("UTF-8").length); + result = libUTF8Interface.returnStringArgument(mem); + assertEquals(input, result); + mem.clear(); + mem.write(0, input.getBytes("ISO-8859-1"), 0, input.getBytes("ISO-8859-1").length); + result = libLatin1Interface.returnStringArgument(mem); + assertEquals(input, result); + } + + public void testStringReturnDirect() throws UnsupportedEncodingException { + // String with german umlauts + String input = "Hallo äöüß"; + + String result; + Memory mem = new Memory(32); + mem.clear(); + mem.write(0, input.getBytes("UTF-8"), 0, input.getBytes("UTF-8").length); + result = libUTF8Direct.returnStringArgument(mem); + assertEquals(input, result); + mem.clear(); + mem.write(0, input.getBytes("ISO-8859-1"), 0, input.getBytes("ISO-8859-1").length); + result = libLatin1Direct.returnStringArgument(mem); + assertEquals(input, result); + } + + private byte[] toByteArray(String input, String encoding, int targetLength) throws UnsupportedEncodingException { + byte[] result = new byte[targetLength]; + byte[] encoded = input.getBytes(encoding); + System.arraycopy(encoded, 0, result, 0, encoded.length); + return result; + } + + private byte[] toByteArray(String[] input, String encoding, int targetLength) throws UnsupportedEncodingException { + byte[] result = new byte[targetLength]; + int offset = 0; + for(String currInput: input) { + byte[] encoded = currInput.getBytes(encoding); + System.arraycopy(encoded, 0, result, offset, encoded.length); + offset += encoded.length; + offset++; + } + return result; + } + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(FunctionTest.class); } + private static class TestLibUTF8 implements Library { + native String returnStringArgument(Pointer input); + native SizeT copyString(String input, byte[] output); + } + + private static class TestLibLatin1 implements Library { + native String returnStringArgument(Pointer input); + native SizeT copyString(String input, byte[] output); + } + + private interface TestLib extends Library { + public String returnStringArgument(Pointer input); + public SizeT copyString(String input, byte[] output); + public SizeT copyStringArray(String[] input, byte[] output); + } + + private static class SizeT extends IntegerType { + public static final int SIZE = Native.SIZE_T_SIZE; + + public SizeT() { + this(0); + } + + public SizeT(long value) { + super(SIZE, value, true); + } + + } } diff --git a/test/com/sun/jna/JNALoadTest.java b/test/com/sun/jna/JNALoadTest.java index 466b5baf5f..98c3f24051 100644 --- a/test/com/sun/jna/JNALoadTest.java +++ b/test/com/sun/jna/JNALoadTest.java @@ -136,8 +136,8 @@ public void testLoadAndUnloadFromJar() throws Exception { assertTrue("Native library not unpacked from jar: " + path, path.startsWith(Native.getTempDir().getAbsolutePath())); - Reference> ref = new WeakReference>(cls); - Reference clref = new WeakReference(loader); + Reference> ref = new WeakReference<>(cls); + Reference clref = new WeakReference<>(loader); loader = null; cls = null; field = null; @@ -191,8 +191,8 @@ public void testLoadAndUnloadFromResourcePath() throws Exception { String path = (String)field.get(null); assertNotNull("Native library not found", path); - Reference> ref = new WeakReference>(cls); - Reference clref = new WeakReference(loader); + Reference> ref = new WeakReference<>(cls); + Reference clref = new WeakReference<>(loader); loader = null; cls = null; field = null; diff --git a/test/com/sun/jna/LastErrorTest.java b/test/com/sun/jna/LastErrorTest.java index 7435f97f94..8356dba70e 100644 --- a/test/com/sun/jna/LastErrorTest.java +++ b/test/com/sun/jna/LastErrorTest.java @@ -69,7 +69,7 @@ public void testLastErrorPerThreadStorage() throws Exception { final TestLibrary lib = Native.load("testlib", TestLibrary.class); final int NTHREADS = 100; final int[] errors = new int[NTHREADS]; - List threads = new ArrayList(NTHREADS); + List threads = new ArrayList<>(NTHREADS); for (int i=0;i < NTHREADS;i++) { final int idx = i; Thread t = new Thread("tLastErrorSetter-" + i) { diff --git a/test/com/sun/jna/MemoryTest.java b/test/com/sun/jna/MemoryTest.java index b287c6e7a7..5cbbafff06 100644 --- a/test/com/sun/jna/MemoryTest.java +++ b/test/com/sun/jna/MemoryTest.java @@ -42,7 +42,7 @@ public class MemoryTest extends TestCase { public void testAutoFreeMemory() throws Exception { Memory core = new Memory(10); Pointer shared = core.share(0, 5); - Reference ref = new WeakReference(core); + Reference ref = new WeakReference<>(core); core = null; System.gc(); @@ -133,8 +133,8 @@ public void testAvoidGCWithExtantBuffer() throws Exception { m.clear(); ByteBuffer b = m.getByteBuffer(0, m.size()); - Reference ref = new WeakReference(m); - Reference bref = new WeakReference(b); + Reference ref = new WeakReference<>(m); + Reference bref = new WeakReference<>(b); // Create a second byte buffer "equal" to the first m = new Memory(1024); @@ -172,7 +172,7 @@ public void testDump() { m.setByte(i, (byte) i); } - String ls = System.getProperty("line.separator"); + String ls = System.lineSeparator(); assertEquals("memory dump" + ls + "[00010203]" + ls + diff --git a/test/com/sun/jna/NativeGetNativeLibraryTest.java b/test/com/sun/jna/NativeGetNativeLibraryTest.java new file mode 100644 index 0000000000..017625c0a7 --- /dev/null +++ b/test/com/sun/jna/NativeGetNativeLibraryTest.java @@ -0,0 +1,94 @@ +/* Copyright (c) 2024 Matthias Bläsing, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna; + +import java.util.Collections; +import junit.framework.TestCase; + +/** + * Check getNativeLibrary functions in Native + */ +public class NativeGetNativeLibraryTest extends TestCase { + + private NativeLibrary libUTF8; + private TestLib libUTF8Interface; + + @Override + protected void setUp() { + libUTF8 = NativeLibrary.getInstance("testlib", + Collections.singletonMap(Library.OPTION_STRING_ENCODING, "UTF-8")); + Native.register(TestLibUTF8.class, libUTF8); + libUTF8Interface = Native.load("testlib", TestLib.class, + Collections.singletonMap(Library.OPTION_STRING_ENCODING, "UTF-8")); + } + + public void testGetNativeLibraryInterface() { + NativeLibrary nl = Native.getNativeLibrary(libUTF8Interface); + assertTrue(nl instanceof NativeLibrary); + } + + public void testGetNativeLibraryDirect() { + NativeLibrary nl = Native.getNativeLibrary(TestLibUTF8.class); + assertTrue(nl instanceof NativeLibrary); + // This only makes sense for the direct case, as that directly wraps + // a supplied instance + assertEquals(libUTF8, nl); + } + + public void testGetNativeLibraryOnUnboundShouldFail() { + try { + Native.getNativeLibrary(new TestLib() { + @Override + public String returnStringArgument(Pointer input) { + return ""; + } + }); + assertTrue("Exception not thrown", false); + } catch (IllegalArgumentException ex) { + // This should be reached + } + } + + public void testGetNativeLibraryOnNullShouldFail() { + try { + Native.getNativeLibrary((Class) null); + assertTrue("Exception not thrown", false); + } catch (IllegalArgumentException ex) { + // This should be reached + } + } + + public static void main(java.lang.String[] argList) { + junit.textui.TestRunner.run(NativeGetNativeLibraryTest.class); + } + + private static class TestLibUTF8 implements Library { + native String returnStringArgument(Pointer input); + } + + private interface TestLib extends Library { + public String returnStringArgument(Pointer input); + } + +} diff --git a/test/com/sun/jna/NativeLibraryTest.java b/test/com/sun/jna/NativeLibraryTest.java index 57f89a26e2..2ef8b09700 100644 --- a/test/com/sun/jna/NativeLibraryTest.java +++ b/test/com/sun/jna/NativeLibraryTest.java @@ -48,6 +48,7 @@ public void testMapSharedLibraryName() { { Platform.LINUX, "lib", ".so" }, { Platform.WINDOWS, "", ".dll" }, { Platform.SOLARIS, "lib", ".so" }, + { Platform.DRAGONFLYBSD, "lib", ".so" }, { Platform.FREEBSD, "lib", ".so" }, { Platform.OPENBSD, "lib", ".so" }, { Platform.WINDOWSCE, "", ".dll" }, @@ -69,7 +70,7 @@ public void testMapSharedLibraryName() { public void testGCNativeLibrary() throws Exception { NativeLibrary lib = NativeLibrary.getInstance("testlib"); - Reference ref = new WeakReference(lib); + Reference ref = new WeakReference<>(lib); lib = null; System.gc(); long start = System.currentTimeMillis(); @@ -82,16 +83,22 @@ public void testGCNativeLibrary() throws Exception { } public void testAvoidDuplicateLoads() throws Exception { - NativeLibrary.disposeAll(); - // Give the system a moment to unload the library; on OSX we - // occasionally get the same library handle back on subsequent dlopen - Thread.sleep(2); - - TestLibrary lib = Native.load("testlib", TestLibrary.class); - assertEquals("Library should be newly loaded after explicit dispose of all native libraries", - 1, lib.callCount()); - if (lib.callCount() <= 1) { - fail("Library should not be reloaded without dispose"); + // This test basicly tests whether unloading works. It relies on the + // runtime to unload the library when dlclose is called. This is not + // required by POSIX and dt time of writing macOS is known to be flaky + // in that regard. + // + // This test causes false test failures + if (!Platform.isMac()) { + NativeLibrary.disposeAll(); + Thread.sleep(2); + + TestLibrary lib = Native.load("testlib", TestLibrary.class); + assertEquals("Library should be newly loaded after explicit dispose of all native libraries", + 1, lib.callCount()); + if (lib.callCount() <= 1) { + fail("Library should not be reloaded without dispose"); + } } } @@ -125,7 +132,7 @@ public void testAliasLibraryFullPath() { public void testAliasSimpleLibraryName() throws Exception { NativeLibrary nl = NativeLibrary.getInstance("testlib"); File file = nl.getFile(); - Reference ref = new WeakReference(nl); + Reference ref = new WeakReference<>(nl); nl = null; System.gc(); long start = System.currentTimeMillis(); @@ -165,7 +172,7 @@ public void testIncludeSymbolNameInLookupError() { public void testFunctionHoldsLibraryReference() throws Exception { NativeLibrary lib = NativeLibrary.getInstance("testlib"); - Reference ref = new WeakReference(lib); + Reference ref = new WeakReference<>(lib); Function f = lib.getFunction("callCount"); lib = null; System.gc(); diff --git a/test/com/sun/jna/NativeTest.java b/test/com/sun/jna/NativeTest.java index 7a9ffcb3fc..0dd7bf8d63 100644 --- a/test/com/sun/jna/NativeTest.java +++ b/test/com/sun/jna/NativeTest.java @@ -85,7 +85,7 @@ public void testLongStringGeneration() { } public void testCustomStringEncoding() throws Exception { - final String ENCODING = System.getProperty("file.encoding"); + final String ENCODING = Charset.defaultCharset().name(); // Keep stuff within the extended ASCII range so we work with more // limited native encodings String UNICODE = "Un \u00e9l\u00e9ment gr\u00e2ce \u00e0 l'index"; @@ -477,7 +477,7 @@ public void testGetBytesWithCharset() throws Exception { public void testGetBytesBadEncoding() throws Exception { byte[] buf = Native.getBytes(getName(), "unsupported"); assertEquals("Incorrect fallback bytes with bad encoding", - getName(), new String(buf, System.getProperty("file.encoding"))); + getName(), new String(buf, Charset.defaultCharset().name())); } public void testFindDirectMappedClassFailure() { diff --git a/test/com/sun/jna/PlatformTest.java b/test/com/sun/jna/PlatformTest.java index 58b92551b3..5a4a9e0abe 100644 --- a/test/com/sun/jna/PlatformTest.java +++ b/test/com/sun/jna/PlatformTest.java @@ -83,6 +83,9 @@ public void testOSPrefix() { Platform.getNativeLibraryResourcePrefix(Platform.LINUX, "arm", "Linux/Gnu")); } + assertEquals("Wrong resource path DragonFlyBSD/x86-64", "dragonflybsd-x86-64", + Platform.getNativeLibraryResourcePrefix(Platform.DRAGONFLYBSD, + "x86-64", "DragonFlyBSD")); assertEquals("Wrong resource path OpenBSD/x86", "openbsd-x86", Platform.getNativeLibraryResourcePrefix(Platform.OPENBSD, "x86", "OpenBSD")); diff --git a/test/com/sun/jna/StructureFieldOrderInspector.java b/test/com/sun/jna/StructureFieldOrderInspector.java index 8ea1987eba..a9c26fc92b 100644 --- a/test/com/sun/jna/StructureFieldOrderInspector.java +++ b/test/com/sun/jna/StructureFieldOrderInspector.java @@ -74,7 +74,7 @@ public static void batchCheckStructureGetFieldOrder(final Class classDeclared final boolean onlyInnerClasses) { final Set> classes = StructureFieldOrderInspector.findSubTypesOfStructure(classDeclaredInSourceTreeToSearch, onlyInnerClasses); - final List problems = new ArrayList(); + final List problems = new ArrayList<>(); for (final Class structureSubType : classes) { try { @@ -121,7 +121,7 @@ public static Set> findSubTypesOfStructure(final Clas .setUrls(ClasspathHelper.forClass(classDeclaredInSourceTreeToSearch)) ); - Set> types = new HashSet>(reflections.getSubTypesOf(Structure.class)); + Set> types = new HashSet<>(reflections.getSubTypesOf(Structure.class)); if(onlyInnerClasses) { Iterator> it = types.iterator(); while(it.hasNext()) { @@ -172,9 +172,7 @@ public static void checkMethodGetFieldOrder(final Class str final Structure structure; try { structure= structConstructor.newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException("Could not instantiate Structure sub type: " + structureSubType.getName(), e); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException e) { throw new RuntimeException("Could not instantiate Structure sub type: " + structureSubType.getName(), e); } catch (InvocationTargetException e) { // this is triggered by checks in Structure.getFields(), and static loadlibrary() failures @@ -192,7 +190,7 @@ public static void checkMethodGetFieldOrder(final Class str final List methodCallFieldOrder = structure.getFieldOrder(); final List actualFields = structure.getFieldList(); - final List actualFieldNames = new ArrayList(actualFields.size()); + final List actualFieldNames = new ArrayList<>(actualFields.size()); for (final Field field : actualFields) { // ignore static fields if (!Modifier.isStatic(field.getModifiers())) { diff --git a/test/com/sun/jna/StructureFieldOrderInspectorTest.java b/test/com/sun/jna/StructureFieldOrderInspectorTest.java index 5780e5274a..488af97e63 100644 --- a/test/com/sun/jna/StructureFieldOrderInspectorTest.java +++ b/test/com/sun/jna/StructureFieldOrderInspectorTest.java @@ -148,7 +148,7 @@ public void testCheckMethodGetFieldOrderWithAbstractSubtype() throws Exception { } public void testCheckMethodGetFieldOrderWithIgnoreCtorError() throws Exception { - final List ignoreConstructorError = new ArrayList(); + final List ignoreConstructorError = new ArrayList<>(); ignoreConstructorError.add(StructureFieldOrderInspectorTest.class.getName()); StructureFieldOrderInspector.checkMethodGetFieldOrder(MyStructExtraField.class, ignoreConstructorError); } diff --git a/test/com/sun/jna/StructureTest.java b/test/com/sun/jna/StructureTest.java index db7c1aeacd..93918ea95f 100644 --- a/test/com/sun/jna/StructureTest.java +++ b/test/com/sun/jna/StructureTest.java @@ -1429,7 +1429,7 @@ protected List getFieldOrder() { } } TestStructure s = new TestStructure(); - final String LS = System.getProperty("line.separator"); + final String LS = System.lineSeparator(); System.setProperty("jna.dump_memory", "true"); final String EXPECTED = "(?m).*" + s.size() + " bytes.*\\{" + LS + " int intField@0x0=0x0000" + LS @@ -1667,7 +1667,7 @@ protected List getFieldOrder() { public static class XTestStructureSub extends XTestStructure { public static final List EXTRA_FIELDS = createFieldsOrder("second"); - private static final AtomicReference> fieldsHolder = new AtomicReference>(null); + private static final AtomicReference> fieldsHolder = new AtomicReference<>(null); private static List resolveEffectiveFields(List baseFields) { List fields; synchronized (fieldsHolder) { @@ -1713,7 +1713,7 @@ class DerivedTestStructure extends TestStructure { public int four = 4; @Override protected List getFieldOrder() { - List list = new ArrayList(super.getFieldOrder()); + List list = new ArrayList<>(super.getFieldOrder()); list.addAll(Arrays.asList("four", "five")); return list; } diff --git a/test/com/sun/jna/VarArgsTest.java b/test/com/sun/jna/VarArgsTest.java index 47dc9d8d60..a626304909 100644 --- a/test/com/sun/jna/VarArgsTest.java +++ b/test/com/sun/jna/VarArgsTest.java @@ -41,6 +41,7 @@ protected List getFieldOrder() { } } public int addVarArgs(String fmt, Number... args); + public int addSeveralFixedArgsAndVarArgs(int a, int b, int c, int d, int nArgs, Integer... args); public String returnStringVarArgs(String fmt, Object... args); public void modifyStructureVarArgs(String fmt, Object... args); public String returnStringVarArgs2(String fmt, String... args); @@ -102,6 +103,22 @@ public void testStringVarArgsFull() { lib.returnStringVarArgs2("", "Test")); } + public void testSeveralFixedAndVarArgs() { + int fixedarg1 = 1; + int fixedarg2 = 2; + int fixedarg3 = 3; + int fixedarg4 = 4; + int vararg1 = 100; + int vararg2 = 200; + + int expected = fixedarg1 + fixedarg2 + fixedarg3 + fixedarg4 + vararg1 + vararg2; + int result = lib.addSeveralFixedArgsAndVarArgs(fixedarg1, fixedarg2, fixedarg3, fixedarg4, + 2, vararg1, vararg2); + + assertEquals("varargs not passed correctly with multiple fixed args", + expected, result); + } + public void testAppendNullToVarargs() { Number[] args = new Number[] { Integer.valueOf(1) }; assertEquals("No trailing NULL was appended to varargs list", diff --git a/test/com/sun/jna/WebStartTest.java b/test/com/sun/jna/WebStartTest.java index 25edd6d908..2e1b58e3f1 100644 --- a/test/com/sun/jna/WebStartTest.java +++ b/test/com/sun/jna/WebStartTest.java @@ -145,8 +145,7 @@ private void runTestUnderWebStart(String testClass, String testMethod) throws Ex String dir = System.getProperty("jna.builddir", BUILDDIR); String codebase = new File(dir, "jws").toURI().toURL().toString(); - ServerSocket s = new ServerSocket(0); - try { + try (ServerSocket s = new ServerSocket(0)) { s.setSoTimeout(SOCKET_TIMEOUT); int port = s.getLocalPort(); @@ -233,8 +232,6 @@ public void run() { finally { jnlp.delete(); } - } finally { - s.close(); } } @@ -291,7 +288,7 @@ private String findJWS() throws IOException { String JAVA_HOME = System.getProperty("java.home"); String BIN = new File(JAVA_HOME, "/bin").getAbsolutePath(); File javaws = new File(BIN, "javaws" + (Platform.isWindows()?".exe":"")); - List tried = new ArrayList(); + List tried = new ArrayList<>(); tried.add(javaws); if (!javaws.exists()) { // NOTE: OSX puts javaws somewhere else entirely diff --git a/www/BuildingNativeLibraries.md b/www/BuildingNativeLibraries.md new file mode 100644 index 0000000000..98596bef60 --- /dev/null +++ b/www/BuildingNativeLibraries.md @@ -0,0 +1,238 @@ +# Building native libraries + +The native library part of JNA needs to be rebuild when the embedded copy of +libffi is updated or the gluecode is updated/bugfixed. + +## Supported build architectures and instructions + +### Linux + +The linux binaries are build in various debian and Ubuntu chroots. The setup +can be found her: https://github.com/matthiasblaesing/docker-jna-build + +The build assumes, that the packages to be build are prepared using the +`prepare-build-libraries.sh` script, which exports zip files with the native +code for: + +- Linux aarch64 +- Linux arm hardfloat +- Linux arm softfloat +- Linux mips64el +- Linux ppc +- Linux ppc64le +- Linux riscv64 +- Linux s390x +- Linux x86-64 +- Linux x86 + +### AIX + +The AIX binaries are build on cfarm (https://portal.cfarm.net/) for AIX ppc and +ppc64. Basis are the build packages generated by `prepare-build-libraries.sh`, +see the Linux section. The host is `cfarm111.cfarm.net`. The packages +autoconf (2.71), libtool (2.4.7) and m4 (1.4.19) are installed in the home +folder. + +1. Copy the build packages for `aix-ppc` and `aix-ppc64` to the host using scp + `scp build-package-aix-ppc* user@cfarm111.cfarm.net:` +2. ssh to the host +3. Unzip the packages `for i in *.zip; do unzip $i; done` +4. Setup the environment: + ```bash + # Ensure `gmake` is used + export MAKE=gmake + # Place local binaries on the path + export PATH=/home/$USER/local/bin:$PATH + # Ensure working ARFLAGS are used + export ARFLAGS='-X32_64 cru' + ``` +5. Build 32bit: + ```bash + # Reference the 32bit JKD 6 + export JAVA_HOME=/usr/java6 + # Build + cd build-package-aix-ppc-7.0.2 + bash build.sh + # Copy result + cp aix-ppc.jar ../ + cd .. + ``` +6. Build 64bit: + ```bash + # Reference the 64bit JKD 7 + export JAVA_HOME=/usr/java7_64 + # Build + cd build-package-aix-ppc64-7.0.2 + bash build.sh + # Copy result + cp aix-ppc64.jar ../ + cd .. + ``` +7. Cleanup: `rm -r build-package-aix-ppc-7.0.2 build-package-aix-ppc-7.0.2.zip build-package-aix-ppc64-7.0.2 build-package-aix-ppc64-7.0.2.zip` +8. Exit build system: `exit` +9. Copy binaries to local system `scp "user@cfarm111.cfarm.net:*.jar" lib/native` + +### Darwin / mac OS + +Darwin binaries are build for x86-64bit and aarch64 on github using the +corresponding pipeline. + +### Android + +Android binaries are build using the Android NDK r12b for: + +- Android aarch64 +- Android armv7 +- Android arm +- Android mips64 +- Android mips +- Android x86-64 +- Android x86 + +The documentation can be found in `AndroidDevelopmentEnvironment.md`. + +### Solaris + +Build on the opencsw buildfarm https://www.opencsw.org/. + +1. Copy the build packages for `solaris` to the host using scp + `scp build-package-sunos-* user@login.opencsw.org:` +2. Login to the gateway system `ssh user@login.opencsw.org` +3. Unzip the packages `for i in *.zip; do unzip $i; done` +4. SSH to the sparc build system `ssh unstable11s` +5. Setup the environment: + ```bash + # Ensure `gmake` is used + export MAKE=gmake + # Place local binaries on the path + export PATH=$HOME/local/bin:$PATH +6. Build 32bit: + ```bash + # Reference the 32bit JKD 7 + export JAVA_HOME=/opt/csw/java/jdk1.7.0_80 + # Build + cd build-package-sunos-sparc-7.0.2/native/libffi + bash autogen.sh + ./configure + cd ../.. + bash build.sh + # Copy result + cp sunos-sparc.jar ../ + cd .. + ``` +7. Build 64bit: + ```bash + # Reference the 64bit JKD 8 + export JAVA_HOME=/opt/csw/java/jdk1.8.0_201 + # Build + cd build-package-sunos-sparcv9-7.0.2/native/libffi + bash autogen.sh + ./configure + cd ../.. + bash build.sh + # Copy result + cp sunos-sparcv9.jar ../ + cd .. + ``` +8. Switch to the x86 build system: + ```bash + logout + ssh unstable11x + ``` +9. Setup the environment: + ```bash + # Ensure `gmake` is used + export MAKE=gmake + # Place local binaries on the path + export PATH=$HOME/local/bin:$PATH +10. Build 32bit: + ```bash + # Reference the 32bit JKD 7 + export JAVA_HOME=/opt/csw/java/jdk1.7.0_80 + # Build + cd build-package-sunos-x86-7.0.2/native/libffi + bash autogen.sh + ./configure + cd ../.. + bash build.sh + # Copy result + cp sunos-x86.jar ../ + cd .. + ``` +11. Build 64bit: + ```bash + # Reference the 64bit JKD 8 + export JAVA_HOME=/opt/csw/java/jdk1.8.0_201 + # Build + cd build-package-sunos-x86-64-7.0.2/native/libffi + bash autogen.sh + ./configure + cd ../.. + bash build.sh + # Copy result + cp sunos-x86-64.jar ../ + cd .. + ``` +12. Return to login system `logout` +13. Cleanup: `rm -r build-package-sunos-sparc-7.0.2 build-package-sunos-sparc-7.0.2.zip build-package-sunos-sparcv9-7.0.2 build-package-sunos-sparcv9-7.0.2.zip build-package-sunos-x86-64-7.0.2 build-package-sunos-x86-64-7.0.2.zip build-package-sunos-x86-7.0.2 build-package-sunos-x86-7.0.2.zip` +14. Exit build system: `exit` +14. Copy binaries to local system: `scp "user@login.opencsw.org:*.jar" lib/native/` + +### Windows + +Build on a native x86 64bit system. x86 32bit and x86 64bit are build natively, +windows aarch64 is crossbuild. + +The documentation can be found in `WindowsDevelopmentEnvironment.md`. + +### FreeBSD + +Binaries are build natively in VM Images of FreeBSD 13.2 (see `FreeBSD.md`) + +Builds are done for: + +- aarch64 +- x86 +- x86-64 + +### Dragonfly BSD + +Binaries are build natively in a 6.4.0 x86-64 VM installed from the ISO Image: + +https://www.dragonflybsd.org/download/ + +```bash +rsync -av --exclude=.git USER@BUILD_HOST:src/jnalib/ jnalib/ +chmod +x jnalib/native/libffi/configure jnalib/native/libffi/install-sh +cd jnalib +ant +``` + +### OpenBSD + +Binaries are build in VMs for + +- x86 +- x86-64 + +They are build using the build-packages generated as part of the Linux build + +``` +scp user@BUILD_HOST:src/jnalib/build/build-package-openbsd-x86-7.0.2.zip . +unzip build-package-openbsd-x86-7.0.2.zip +cd build-package-openbsd-x86-7.0.2 +export JAVA_HOME=/usr/local/jdk-1.8.0 +export MAKE=gmake +sh build.sh +scp openbsd-x86.jar user@BUILD_HOST:src/jnalib/lib/native +``` + +``` +scp user@BUILD_HOST:src/jnalib/build/build-package-openbsd-x86-64-7.0.2.zip . +unzip build-package-openbsd-x86-7.0.2.zip +cd build-package-openbsd-x86-7.0.2 +export JAVA_HOME=/usr/local/jdk-1.8.0 +export MAKE=gmake +sh build.sh +scp openbsd-x86-64.jar user@BUILD_HOST:src/jnalib/lib/native +``` \ No newline at end of file diff --git a/www/FreeBSD.md b/www/FreeBSD.md new file mode 100644 index 0000000000..1232717281 --- /dev/null +++ b/www/FreeBSD.md @@ -0,0 +1,172 @@ +Building JNA for FreeBSD +======================== + +aarch64 +------- + +This recipe was used to build the FreeBSD aarch64 native library on amd64: + +``` +# Fetch FreeBSD 13.2 image and extract it +wget https://download.freebsd.org/releases/VM-IMAGES/13.2-RELEASE/aarch64/Latest/FreeBSD-13.2-RELEASE-arm64-aarch64.qcow2.xz +xz -d FreeBSD-13.2-RELEASE-arm64-aarch64.qcow2.xz + +# Ensure there is enough space in the image +qemu-img resize -f qcow2 FreeBSD-13.2-RELEASE-arm64-aarch64.qcow2 +5G + +# Launch aarch64 emulator with downloaded image +qemu-system-aarch64 -m 4096M -cpu cortex-a57 -M virt \ + -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin \ + -serial telnet::4444,server -nographic \ + -drive if=none,file=FreeBSD-13.2-RELEASE-arm64-aarch64.qcow2,id=hd0 \ + -device virtio-blk-device,drive=hd0 \ + -device virtio-net-device,netdev=net0 \ + -netdev user,id=net0 + +# Connect to terminal for emulated system and boot into single user mode with default shell +telnet localhost 4444 + +# Resize partitions +gpart show /dev/vtbd0 +gpart recover /dev/vtbd0 +gpart show /dev/vtbd0 +gpart resize -i 3 /dev/vtbd0 +growfs / + +# Exit single user mode (BSD boots to multi-user) +exit + +# Login as root + +# Set current date and time (YYYYMMDDHHMM) +date 202403081928 + +# Install prerequisites - part 1 - java, build system, rsync +pkg install openjdk17 wget automake rsync gmake gcc bash texinfo +# Adjust fstab (optional, only needed if reboot is planned) +# fdesc /dev/fd fdescfs rw 0 0 +# proc /proc procfs rw 0 0 + +# Install prerequisites - part 2 - ant +wget https://dlcdn.apache.org/ant/binaries/apache-ant-1.10.14-bin.zip +unzip apache-ant-1.10.14-bin.zip + +# Transfer JNA source code to build environment +rsync -av --exclude=.git USER@BUILD_HOST:src/jnalib/ jnalib/ + +# Build JNA and run unittests +cd jnalib +chmod +x native/libffi/configure native/libffi/install-sh +/root/apache-ant-1.10.14/bin/ant + +# Copy jna native library back to host system +scp lib/native/freebsd-aarch64.jar USER@BUILD_HOST:src/jnalib/lib/native +``` + +x86 +--- + +``` +# Fetch image +wget https://download.freebsd.org/releases/VM-IMAGES/13.2-RELEASE/i386/Latest/FreeBSD-13.2-RELEASE-i386.qcow2.xz +xz -d FreeBSD-13.2-RELEASE-i386.qcow2.xz + +# Ensure there is enough space in the image +qemu-img resize -f qcow2 FreeBSD-13.2-RELEASE-i386.qcow2 +5G + +# Launch image +qemu-system-i386 -m 3096M -drive file=FreeBSD-13.2-RELEASE-i386.qcow2 + +gpart show /dev/ada0 +gpart recover /dev/ada0 +gpart show /dev/ada0 +gpart resize -i 4 /dev/ada0 +growfs / + +# Exit single user mode (BSD boots to multi-user) +exit + +# Login as root + +# Set keyboard configuration +kbdmap + +# Set current date and time (YYYYMMDDHHMM) +date 202403081928 + +# Install prerequisites - part 1 - java, build system, rsync +pkg install openjdk17 wget automake rsync gmake gcc bash texinfo +# Adjust fstab (optional, only needed if reboot is planned) +# fdesc /dev/fd fdescfs rw 0 0 +# proc /proc procfs rw 0 0 + + +# Install prerequisites - part 2 - ant +wget https://dlcdn.apache.org/ant/binaries/apache-ant-1.10.14-bin.zip +unzip apache-ant-1.10.14-bin.zip + +# Transfer JNA source code to build environment +rsync -av --exclude=.git USER@BUILD_HOST:src/jnalib/ jnalib/ + +# Build JNA and run unittests +cd jnalib +chmod +x native/libffi/configure native/libffi/install-sh +/root/apache-ant-1.10.14/bin/ant + +# Copy jna native library back to host system +scp lib/native/freebsd-x86.jar USER@BUILD_HOST:src/jnalib/lib/native +``` + +x86-64 +------ + +``` +# Fetch image +wget https://download.freebsd.org/releases/VM-IMAGES/13.2-RELEASE/amd64/Latest/FreeBSD-13.2-RELEASE-amd64.qcow2.xz +xz -d FreeBSD-13.2-RELEASE-amd64.qcow2.xz + +# Ensure there is enough space in the image +qemu-img resize -f qcow2 FreeBSD-13.2-RELEASE-amd64.qcow2 +5G + +# Launch image +qemu-system-amd64 -m 4096M -drive file=FreeBSD-13.2-RELEASE-amd64.qcow2 + +gpart show /dev/ada0 +gpart recover /dev/ada0 +gpart show /dev/ada0 +gpart resize -i 4 /dev/ada0 +growfs / + +# Exit single user mode (BSD boots to multi-user) +exit + +# Login as root + +# Set keyboard configuration +kbdmap + +# Set current date and time (YYYYMMDDHHMM) +date 202403081928 + +# Install prerequisites - part 1 - java, build system, rsync +pkg install openjdk17 wget automake rsync gmake gcc bash texinfo +# Adjust fstab (optional, only needed if reboot is planned) +# fdesc /dev/fd fdescfs rw 0 0 +# proc /proc procfs rw 0 0 + + +# Install prerequisites - part 2 - ant +wget https://dlcdn.apache.org/ant/binaries/apache-ant-1.10.14-bin.zip +unzip apache-ant-1.10.14-bin.zip + +# Transfer JNA source code to build environment +rsync -av --exclude=.git USER@BUILD_HOST:src/jnalib/ jnalib/ + +# Build JNA and run unittests +cd jnalib +chmod +x native/libffi/configure native/libffi/install-sh +/root/apache-ant-1.10.14/bin/ant + +# Copy jna native library back to host system +scp lib/native/freebsd-x86-64.jar USER@BUILD_HOST:src/jnalib/lib/native +``` \ No newline at end of file diff --git a/www/ReleasingJNA.md b/www/ReleasingJNA.md index 1abe339dfe..2d8868f53d 100644 --- a/www/ReleasingJNA.md +++ b/www/ReleasingJNA.md @@ -18,6 +18,8 @@ JNA Release Process * Commit and push generated files in `dist`, `CHANGES.md` and `README.md`. +* Login to https://oss.sonatype.org and release the maven artifacts + * Tag * Tag using the new version number (e.g. `git tag 4.2.1`) * Push new tag to origin (`git push --tags`) @@ -29,8 +31,8 @@ JNA Release Process * Email release notice to [jna-users Google group](http://groups.google.com/group/jna-users). -* Increment the version in build.xml for the next development iteration - * Increment "jna.revision" in build.xml by one +* Increment the version in common.xml for the next development iteration + * Increment "jna.minor" in common.xml by one * Create a new section in CHANGES.md for 'Next Release (x.y.z)' * Commit and push